/*
 *  IBM eServer eHCA Infiniband device driver for Linux on POWER
 *
 *  SQP functions
 *
 *  Authors: Khadija Souissi <souissi@de.ibm.com>
 *           Heiko J Schick <schickhj@de.ibm.com>
 *
 *  Copyright (c) 2005 IBM Corporation
 *
 *  All rights reserved.
 *
 *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
 *  BSD.
 *
 * OpenIB BSD License
 *
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <rdma/ib_mad.h>

#include "ehca_classes.h"
#include "ehca_tools.h"
#include "ehca_iverbs.h"
#include "hcp_if.h"

#define IB_MAD_STATUS_REDIRECT		__constant_htons(0x0002)
#define IB_MAD_STATUS_UNSUP_VERSION	__constant_htons(0x0004)
#define IB_MAD_STATUS_UNSUP_METHOD	__constant_htons(0x0008)

#define IB_PMA_CLASS_PORT_INFO		__constant_htons(0x0001)

/**
 * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
 * pair is created successfully, the corresponding port gets active.
 *
 * Define Special Queue pair 0 (SMI QP) is still not supported.
 *
 * @qp_init_attr: Queue pair init attributes with port and queue pair type
 */

u64 ehca_define_sqp(struct ehca_shca *shca,
		    struct ehca_qp *ehca_qp,
		    struct ib_qp_init_attr *qp_init_attr)
{
	u32 pma_qp_nr, bma_qp_nr;
	u64 ret;
	u8 port = qp_init_attr->port_num;
	int counter;

	shca->sport[port - 1].port_state = IB_PORT_DOWN;

	switch (qp_init_attr->qp_type) {
	case IB_QPT_SMI:
		/* function not supported yet */
		break;
	case IB_QPT_GSI:
		ret = hipz_h_define_aqp1(shca->ipz_hca_handle,
					 ehca_qp->ipz_qp_handle,
					 ehca_qp->galpas.kernel,
					 (u32) qp_init_attr->port_num,
					 &pma_qp_nr, &bma_qp_nr);

		if (ret != H_SUCCESS) {
			ehca_err(&shca->ib_device,
				 "Can't define AQP1 for port %x. h_ret=%lli",
				 port, ret);
			return ret;
		}
		shca->sport[port - 1].pma_qp_nr = pma_qp_nr;
		ehca_dbg(&shca->ib_device, "port=%x pma_qp_nr=%x",
			 port, pma_qp_nr);
		break;
	default:
		ehca_err(&shca->ib_device, "invalid qp_type=%x",
			 qp_init_attr->qp_type);
		return H_PARAMETER;
	}

	if (ehca_nr_ports < 0) /* autodetect mode */
		return H_SUCCESS;

	for (counter = 0;
	     shca->sport[port - 1].port_state != IB_PORT_ACTIVE &&
		     counter < ehca_port_act_time;
	     counter++) {
		ehca_dbg(&shca->ib_device, "... wait until port %x is active",
			 port);
		msleep_interruptible(1000);
	}

	if (counter == ehca_port_act_time) {
		ehca_err(&shca->ib_device, "Port %x is not active.", port);
		return H_HARDWARE;
	}

	return H_SUCCESS;
}

struct ib_perf {
	struct ib_mad_hdr mad_hdr;
	u8 reserved[40];
	u8 data[192];
} __attribute__ ((packed));


static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
			     struct ib_mad *in_mad, struct ib_mad *out_mad)
{
	struct ib_perf *in_perf = (struct ib_perf *)in_mad;
	struct ib_perf *out_perf = (struct ib_perf *)out_mad;
	struct ib_class_port_info *poi =
		(struct ib_class_port_info *)out_perf->data;
	struct ehca_shca *shca =
		container_of(ibdev, struct ehca_shca, ib_device);
	struct ehca_sport *sport = &shca->sport[port_num - 1];

	ehca_dbg(ibdev, "method=%x", in_perf->mad_hdr.method);

	*out_mad = *in_mad;

	if (in_perf->mad_hdr.class_version != 1) {
		ehca_warn(ibdev, "Unsupported class_version=%x",
			  in_perf->mad_hdr.class_version);
		out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_VERSION;
		goto perf_reply;
	}

	switch (in_perf->mad_hdr.method) {
	case IB_MGMT_METHOD_GET:
	case IB_MGMT_METHOD_SET:
		/* set class port info for redirection */
		out_perf->mad_hdr.attr_id = IB_PMA_CLASS_PORT_INFO;
		out_perf->mad_hdr.status = IB_MAD_STATUS_REDIRECT;
		memset(poi, 0, sizeof(*poi));
		poi->base_version = 1;
		poi->class_version = 1;
		poi->resp_time_value = 18;
		poi->redirect_lid = sport->saved_attr.lid;
		poi->redirect_qp = sport->pma_qp_nr;
		poi->redirect_qkey = IB_QP1_QKEY;
		poi->redirect_pkey = IB_DEFAULT_PKEY_FULL;

		ehca_dbg(ibdev, "ehca_pma_lid=%x ehca_pma_qp=%x",
			 sport->saved_attr.lid, sport->pma_qp_nr);
		break;

	case IB_MGMT_METHOD_GET_RESP:
		return IB_MAD_RESULT_FAILURE;

	default:
		out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_METHOD;
		break;
	}

perf_reply:
	out_perf->mad_hdr.method = IB_MGMT_METHOD_GET_RESP;

	return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
}

int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
		     struct ib_wc *in_wc, struct ib_grh *in_grh,
		     struct ib_mad *in_mad,
		     struct ib_mad *out_mad)
{
	int ret;

	if (!port_num || port_num > ibdev->phys_port_cnt)
		return IB_MAD_RESULT_FAILURE;

	/* accept only pma request */
	if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
		return IB_MAD_RESULT_SUCCESS;

	ehca_dbg(ibdev, "port_num=%x src_qp=%x", port_num, in_wc->src_qp);
	ret = ehca_process_perf(ibdev, port_num, in_mad, out_mad);

	return ret;
}
