/*
 * Copyright(c) 2017 Intel Corporation.
 * Copyright(c) 2021 Cornelis Networks.
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * 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.
 *
 * 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.
 *  - Neither the name of Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 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.
 *
 */

/*
 * This file contains OPX Virtual Network Interface Controller (VNIC)
 * Ethernet Management Agent (EMA) driver
 */

#include <linux/module.h>
#include <linux/xarray.h>
#include <rdma/ib_addr.h>
#include <rdma/ib_verbs.h>
#include <rdma/opa_smi.h>
#include <rdma/opa_port_info.h>

#include "opa_vnic_internal.h"

char opa_vnic_driver_name[] = "opa_vnic";

/*
 * The trap service level is kept in bits 3 to 7 in the trap_sl_rsvd
 * field in the class port info MAD.
 */
#define GET_TRAP_SL_FROM_CLASS_PORT_INFO(x)  (((x) >> 3) & 0x1f)

/* Cap trap bursts to a reasonable limit good for normal cases */
#define OPA_VNIC_TRAP_BURST_LIMIT 4

/*
 * VNIC trap limit timeout.
 * Inverse of cap2_mask response time out (1.0737 secs) = 0.9
 * secs approx IB spec 13.4.6.2.1 PortInfoSubnetTimeout and
 * 13.4.9 Traps.
 */
#define OPA_VNIC_TRAP_TIMEOUT  ((4096 * (1UL << 18)) / 1000)

#define OPA_VNIC_UNSUP_ATTR  \
		cpu_to_be16(IB_MGMT_MAD_STATUS_UNSUPPORTED_METHOD_ATTRIB)

#define OPA_VNIC_INVAL_ATTR  \
		cpu_to_be16(IB_MGMT_MAD_STATUS_INVALID_ATTRIB_VALUE)

#define OPA_VNIC_CLASS_CAP_TRAP   0x1

/* Maximum number of VNIC ports supported */
#define OPA_VNIC_MAX_NUM_VPORT    255

/**
 * struct opa_vnic_vema_port -- VNIC VEMA port details
 * @cport: pointer to port
 * @mad_agent: pointer to mad agent for port
 * @class_port_info: Class port info information.
 * @tid: Transaction id
 * @port_num: OPA port number
 * @vports: vnic ports
 * @event_handler: ib event handler
 * @lock: adapter interface lock
 */
struct opa_vnic_vema_port {
	struct opa_vnic_ctrl_port      *cport;
	struct ib_mad_agent            *mad_agent;
	struct opa_class_port_info      class_port_info;
	u64                             tid;
	u8                              port_num;
	struct xarray                   vports;
	struct ib_event_handler         event_handler;

	/* Lock to query/update network adapter */
	struct mutex                    lock;
};

static int opa_vnic_vema_add_one(struct ib_device *device);
static void opa_vnic_vema_rem_one(struct ib_device *device,
				  void *client_data);

static struct ib_client opa_vnic_client = {
	.name   = opa_vnic_driver_name,
	.add    = opa_vnic_vema_add_one,
	.remove = opa_vnic_vema_rem_one,
};

/**
 * vema_get_vport_num -- Get the vnic from the mad
 * @recvd_mad:  Received mad
 *
 * Return: returns value of the vnic port number
 */
static inline u8 vema_get_vport_num(struct opa_vnic_vema_mad *recvd_mad)
{
	return be32_to_cpu(recvd_mad->mad_hdr.attr_mod) & 0xff;
}

/**
 * vema_get_vport_adapter -- Get vnic port adapter from recvd mad
 * @recvd_mad: received mad
 * @port: ptr to port struct on which MAD was recvd
 *
 * Return: vnic adapter
 */
static inline struct opa_vnic_adapter *
vema_get_vport_adapter(struct opa_vnic_vema_mad *recvd_mad,
		       struct opa_vnic_vema_port *port)
{
	u8 vport_num = vema_get_vport_num(recvd_mad);

	return xa_load(&port->vports, vport_num);
}

/**
 * vema_mac_tbl_req_ok -- Check if mac request has correct values
 * @mac_tbl: mac table
 *
 * This function checks for the validity of the offset and number of
 * entries required.
 *
 * Return: true if offset and num_entries are valid
 */
static inline bool vema_mac_tbl_req_ok(struct opa_veswport_mactable *mac_tbl)
{
	u16 offset, num_entries;
	u16 req_entries = ((OPA_VNIC_EMA_DATA - sizeof(*mac_tbl)) /
			   sizeof(mac_tbl->tbl_entries[0]));

	offset = be16_to_cpu(mac_tbl->offset);
	num_entries = be16_to_cpu(mac_tbl->num_entries);

	return ((num_entries <= req_entries) &&
		(offset + num_entries <= OPA_VNIC_MAC_TBL_MAX_ENTRIES));
}

/*
 * Return the power on default values in the port info structure
 * in big endian format as required by MAD.
 */
static inline void vema_get_pod_values(struct opa_veswport_info *port_info)
{
	memset(port_info, 0, sizeof(*port_info));
	port_info->vport.max_mac_tbl_ent =
		cpu_to_be16(OPA_VNIC_MAC_TBL_MAX_ENTRIES);
	port_info->vport.max_smac_ent =
		cpu_to_be16(OPA_VNIC_MAX_SMAC_LIMIT);
	port_info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL;
	port_info->vport.config_state = OPA_VNIC_STATE_DROP_ALL;
	port_info->vesw.eth_mtu = cpu_to_be16(ETH_DATA_LEN);
}

/**
 * vema_add_vport -- Add a new vnic port
 * @port: ptr to opa_vnic_vema_port struct
 * @vport_num: vnic port number (to be added)
 *
 * Return a pointer to the vnic adapter structure
 */
static struct opa_vnic_adapter *vema_add_vport(struct opa_vnic_vema_port *port,
					       u8 vport_num)
{
	struct opa_vnic_ctrl_port *cport = port->cport;
	struct opa_vnic_adapter *adapter;

	adapter = opa_vnic_add_netdev(cport->ibdev, port->port_num, vport_num);
	if (!IS_ERR(adapter)) {
		int rc;

		adapter->cport = cport;
		rc = xa_insert(&port->vports, vport_num, adapter, GFP_KERNEL);
		if (rc < 0) {
			opa_vnic_rem_netdev(adapter);
			adapter = ERR_PTR(rc);
		}
	}

	return adapter;
}

/**
 * vema_get_class_port_info -- Get class info for port
 * @port:  Port on whic MAD was received
 * @recvd_mad: pointer to the received mad
 * @rsp_mad:   pointer to respose mad
 *
 * This function copies the latest class port info value set for the
 * port and stores it for generating traps
 */
static void vema_get_class_port_info(struct opa_vnic_vema_port *port,
				     struct opa_vnic_vema_mad *recvd_mad,
				     struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_class_port_info *port_info;

	port_info = (struct opa_class_port_info *)rsp_mad->data;
	memcpy(port_info, &port->class_port_info, sizeof(*port_info));
	port_info->base_version = OPA_MGMT_BASE_VERSION;
	port_info->class_version = OPA_EMA_CLASS_VERSION;

	/*
	 * Set capability mask bit indicating agent generates traps,
	 * and set the maximum number of VNIC ports supported.
	 */
	port_info->cap_mask = cpu_to_be16((OPA_VNIC_CLASS_CAP_TRAP |
					   (OPA_VNIC_MAX_NUM_VPORT << 8)));

	/*
	 * Since a get routine is always sent by the EM first we
	 * set the expected response time to
	 * 4.096 usec * 2^18 == 1.0737 sec here.
	 */
	port_info->cap_mask2_resp_time = cpu_to_be32(18);
}

/**
 * vema_set_class_port_info -- Get class info for port
 * @port:  Port on whic MAD was received
 * @recvd_mad: pointer to the received mad
 * @rsp_mad:   pointer to respose mad
 *
 * This function updates the port class info for the specific vnic
 * and sets up the response mad data
 */
static void vema_set_class_port_info(struct opa_vnic_vema_port *port,
				     struct opa_vnic_vema_mad *recvd_mad,
				     struct opa_vnic_vema_mad *rsp_mad)
{
	memcpy(&port->class_port_info, recvd_mad->data,
	       sizeof(port->class_port_info));

	vema_get_class_port_info(port, recvd_mad, rsp_mad);
}

/**
 * vema_get_veswport_info -- Get veswport info
 * @port:      source port on which MAD was received
 * @recvd_mad: pointer to the received mad
 * @rsp_mad:   pointer to respose mad
 */
static void vema_get_veswport_info(struct opa_vnic_vema_port *port,
				   struct opa_vnic_vema_mad *recvd_mad,
				   struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_veswport_info *port_info =
				  (struct opa_veswport_info *)rsp_mad->data;
	struct opa_vnic_adapter *adapter;

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (adapter) {
		memset(port_info, 0, sizeof(*port_info));
		opa_vnic_get_vesw_info(adapter, &port_info->vesw);
		opa_vnic_get_per_veswport_info(adapter,
					       &port_info->vport);
	} else {
		vema_get_pod_values(port_info);
	}
}

/**
 * vema_set_veswport_info -- Set veswport info
 * @port:      source port on which MAD was received
 * @recvd_mad: pointer to the received mad
 * @rsp_mad:   pointer to respose mad
 *
 * This function gets the port class infor for vnic
 */
static void vema_set_veswport_info(struct opa_vnic_vema_port *port,
				   struct opa_vnic_vema_mad *recvd_mad,
				   struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_vnic_ctrl_port *cport = port->cport;
	struct opa_veswport_info *port_info;
	struct opa_vnic_adapter *adapter;
	u8 vport_num;

	vport_num = vema_get_vport_num(recvd_mad);

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (!adapter) {
		adapter = vema_add_vport(port, vport_num);
		if (IS_ERR(adapter)) {
			c_err("failed to add vport %d: %ld\n",
			      vport_num, PTR_ERR(adapter));
			goto err_exit;
		}
	}

	port_info = (struct opa_veswport_info *)recvd_mad->data;
	opa_vnic_set_vesw_info(adapter, &port_info->vesw);
	opa_vnic_set_per_veswport_info(adapter, &port_info->vport);

	/* Process the new config settings */
	opa_vnic_process_vema_config(adapter);

	vema_get_veswport_info(port, recvd_mad, rsp_mad);
	return;

err_exit:
	rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
}

/**
 * vema_get_mac_entries -- Get MAC entries in VNIC MAC table
 * @port:      source port on which MAD was received
 * @recvd_mad: pointer to the received mad
 * @rsp_mad:   pointer to respose mad
 *
 * This function gets the MAC entries that are programmed into
 * the VNIC MAC forwarding table. It checks for the validity of
 * the index into the MAC table and the number of entries that
 * are to be retrieved.
 */
static void vema_get_mac_entries(struct opa_vnic_vema_port *port,
				 struct opa_vnic_vema_mad *recvd_mad,
				 struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_veswport_mactable *mac_tbl_in, *mac_tbl_out;
	struct opa_vnic_adapter *adapter;

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (!adapter) {
		rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
		return;
	}

	mac_tbl_in = (struct opa_veswport_mactable *)recvd_mad->data;
	mac_tbl_out = (struct opa_veswport_mactable *)rsp_mad->data;

	if (vema_mac_tbl_req_ok(mac_tbl_in)) {
		mac_tbl_out->offset = mac_tbl_in->offset;
		mac_tbl_out->num_entries = mac_tbl_in->num_entries;
		opa_vnic_query_mac_tbl(adapter, mac_tbl_out);
	} else {
		rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
	}
}

/**
 * vema_set_mac_entries -- Set MAC entries in VNIC MAC table
 * @port:      source port on which MAD was received
 * @recvd_mad: pointer to the received mad
 * @rsp_mad:   pointer to respose mad
 *
 * This function sets the MAC entries in the VNIC forwarding table
 * It checks for the validity of the index and the number of forwarding
 * table entries to be programmed.
 */
static void vema_set_mac_entries(struct opa_vnic_vema_port *port,
				 struct opa_vnic_vema_mad *recvd_mad,
				 struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_veswport_mactable *mac_tbl;
	struct opa_vnic_adapter *adapter;

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (!adapter) {
		rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
		return;
	}

	mac_tbl = (struct opa_veswport_mactable *)recvd_mad->data;
	if (vema_mac_tbl_req_ok(mac_tbl)) {
		if (opa_vnic_update_mac_tbl(adapter, mac_tbl))
			rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR;
	} else {
		rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR;
	}
	vema_get_mac_entries(port, recvd_mad, rsp_mad);
}

/**
 * vema_set_delete_vesw -- Reset VESW info to POD values
 * @port:      source port on which MAD was received
 * @recvd_mad: pointer to the received mad
 * @rsp_mad:   pointer to respose mad
 *
 * This function clears all the fields of veswport info for the requested vesw
 * and sets them back to the power-on default values. It does not delete the
 * vesw.
 */
static void vema_set_delete_vesw(struct opa_vnic_vema_port *port,
				 struct opa_vnic_vema_mad *recvd_mad,
				 struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_veswport_info *port_info =
				  (struct opa_veswport_info *)rsp_mad->data;
	struct opa_vnic_adapter *adapter;

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (!adapter) {
		rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
		return;
	}

	vema_get_pod_values(port_info);
	opa_vnic_set_vesw_info(adapter, &port_info->vesw);
	opa_vnic_set_per_veswport_info(adapter, &port_info->vport);

	/* Process the new config settings */
	opa_vnic_process_vema_config(adapter);

	opa_vnic_release_mac_tbl(adapter);

	vema_get_veswport_info(port, recvd_mad, rsp_mad);
}

/**
 * vema_get_mac_list -- Get the unicast/multicast macs.
 * @port:      source port on which MAD was received
 * @recvd_mad: Received mad contains fields to set vnic parameters
 * @rsp_mad:   Response mad to be built
 * @attr_id:   Attribute ID indicating multicast or unicast mac list
 */
static void vema_get_mac_list(struct opa_vnic_vema_port *port,
			      struct opa_vnic_vema_mad *recvd_mad,
			      struct opa_vnic_vema_mad *rsp_mad,
			      u16 attr_id)
{
	struct opa_veswport_iface_macs *macs_in, *macs_out;
	int max_entries = (OPA_VNIC_EMA_DATA - sizeof(*macs_out)) / ETH_ALEN;
	struct opa_vnic_adapter *adapter;

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (!adapter) {
		rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
		return;
	}

	macs_in = (struct opa_veswport_iface_macs *)recvd_mad->data;
	macs_out = (struct opa_veswport_iface_macs *)rsp_mad->data;

	macs_out->start_idx = macs_in->start_idx;
	if (macs_in->num_macs_in_msg)
		macs_out->num_macs_in_msg = macs_in->num_macs_in_msg;
	else
		macs_out->num_macs_in_msg = cpu_to_be16(max_entries);

	if (attr_id == OPA_EM_ATTR_IFACE_MCAST_MACS)
		opa_vnic_query_mcast_macs(adapter, macs_out);
	else
		opa_vnic_query_ucast_macs(adapter, macs_out);
}

/**
 * vema_get_summary_counters -- Gets summary counters.
 * @port:      source port on which MAD was received
 * @recvd_mad: Received mad contains fields to set vnic parameters
 * @rsp_mad:   Response mad to be built
 */
static void vema_get_summary_counters(struct opa_vnic_vema_port *port,
				      struct opa_vnic_vema_mad *recvd_mad,
				      struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_veswport_summary_counters *cntrs;
	struct opa_vnic_adapter *adapter;

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (adapter) {
		cntrs = (struct opa_veswport_summary_counters *)rsp_mad->data;
		opa_vnic_get_summary_counters(adapter, cntrs);
	} else {
		rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
	}
}

/**
 * vema_get_error_counters -- Gets summary counters.
 * @port:      source port on which MAD was received
 * @recvd_mad: Received mad contains fields to set vnic parameters
 * @rsp_mad:   Response mad to be built
 */
static void vema_get_error_counters(struct opa_vnic_vema_port *port,
				    struct opa_vnic_vema_mad *recvd_mad,
				    struct opa_vnic_vema_mad *rsp_mad)
{
	struct opa_veswport_error_counters *cntrs;
	struct opa_vnic_adapter *adapter;

	adapter = vema_get_vport_adapter(recvd_mad, port);
	if (adapter) {
		cntrs = (struct opa_veswport_error_counters *)rsp_mad->data;
		opa_vnic_get_error_counters(adapter, cntrs);
	} else {
		rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR;
	}
}

/**
 * vema_get -- Process received get MAD
 * @port:      source port on which MAD was received
 * @recvd_mad: Received mad
 * @rsp_mad:   Response mad to be built
 */
static void vema_get(struct opa_vnic_vema_port *port,
		     struct opa_vnic_vema_mad *recvd_mad,
		     struct opa_vnic_vema_mad *rsp_mad)
{
	u16 attr_id = be16_to_cpu(recvd_mad->mad_hdr.attr_id);

	switch (attr_id) {
	case OPA_EM_ATTR_CLASS_PORT_INFO:
		vema_get_class_port_info(port, recvd_mad, rsp_mad);
		break;
	case OPA_EM_ATTR_VESWPORT_INFO:
		vema_get_veswport_info(port, recvd_mad, rsp_mad);
		break;
	case OPA_EM_ATTR_VESWPORT_MAC_ENTRIES:
		vema_get_mac_entries(port, recvd_mad, rsp_mad);
		break;
	case OPA_EM_ATTR_IFACE_UCAST_MACS:
	case OPA_EM_ATTR_IFACE_MCAST_MACS:
		vema_get_mac_list(port, recvd_mad, rsp_mad, attr_id);
		break;
	case OPA_EM_ATTR_VESWPORT_SUMMARY_COUNTERS:
		vema_get_summary_counters(port, recvd_mad, rsp_mad);
		break;
	case OPA_EM_ATTR_VESWPORT_ERROR_COUNTERS:
		vema_get_error_counters(port, recvd_mad, rsp_mad);
		break;
	default:
		rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR;
		break;
	}
}

/**
 * vema_set -- Process received set MAD
 * @port:      source port on which MAD was received
 * @recvd_mad: Received mad contains fields to set vnic parameters
 * @rsp_mad:   Response mad to be built
 */
static void vema_set(struct opa_vnic_vema_port *port,
		     struct opa_vnic_vema_mad *recvd_mad,
		     struct opa_vnic_vema_mad *rsp_mad)
{
	u16 attr_id = be16_to_cpu(recvd_mad->mad_hdr.attr_id);

	switch (attr_id) {
	case OPA_EM_ATTR_CLASS_PORT_INFO:
		vema_set_class_port_info(port, recvd_mad, rsp_mad);
		break;
	case OPA_EM_ATTR_VESWPORT_INFO:
		vema_set_veswport_info(port, recvd_mad, rsp_mad);
		break;
	case OPA_EM_ATTR_VESWPORT_MAC_ENTRIES:
		vema_set_mac_entries(port, recvd_mad, rsp_mad);
		break;
	case OPA_EM_ATTR_DELETE_VESW:
		vema_set_delete_vesw(port, recvd_mad, rsp_mad);
		break;
	default:
		rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR;
		break;
	}
}

/**
 * vema_send -- Send handler for VEMA MAD agent
 * @mad_agent: pointer to the mad agent
 * @mad_wc:    pointer to mad send work completion information
 *
 * Free all the data structures associated with the sent MAD
 */
static void vema_send(struct ib_mad_agent *mad_agent,
		      struct ib_mad_send_wc *mad_wc)
{
	rdma_destroy_ah(mad_wc->send_buf->ah, RDMA_DESTROY_AH_SLEEPABLE);
	ib_free_send_mad(mad_wc->send_buf);
}

/**
 * vema_recv -- Recv handler for VEMA MAD agent
 * @mad_agent: pointer to the mad agent
 * @send_buf: Send buffer if found, else NULL
 * @mad_wc:    pointer to mad send work completion information
 *
 * Handle only set and get methods and respond to other methods
 * as unsupported. Allocate response buffer and address handle
 * for the response MAD.
 */
static void vema_recv(struct ib_mad_agent *mad_agent,
		      struct ib_mad_send_buf *send_buf,
		      struct ib_mad_recv_wc *mad_wc)
{
	struct opa_vnic_vema_port *port;
	struct ib_ah              *ah;
	struct ib_mad_send_buf    *rsp;
	struct opa_vnic_vema_mad  *vema_mad;

	if (!mad_wc || !mad_wc->recv_buf.mad)
		return;

	port = mad_agent->context;
	ah = ib_create_ah_from_wc(mad_agent->qp->pd, mad_wc->wc,
				  mad_wc->recv_buf.grh, mad_agent->port_num);
	if (IS_ERR(ah))
		goto free_recv_mad;

	rsp = ib_create_send_mad(mad_agent, mad_wc->wc->src_qp,
				 mad_wc->wc->pkey_index, 0,
				 IB_MGMT_VENDOR_HDR, OPA_VNIC_EMA_DATA,
				 GFP_KERNEL, OPA_MGMT_BASE_VERSION);
	if (IS_ERR(rsp))
		goto err_rsp;

	rsp->ah = ah;
	vema_mad = rsp->mad;
	memcpy(vema_mad, mad_wc->recv_buf.mad, IB_MGMT_VENDOR_HDR);
	vema_mad->mad_hdr.method = IB_MGMT_METHOD_GET_RESP;
	vema_mad->mad_hdr.status = 0;

	/* Lock ensures network adapter is not removed */
	mutex_lock(&port->lock);

	switch (mad_wc->recv_buf.mad->mad_hdr.method) {
	case IB_MGMT_METHOD_GET:
		vema_get(port, (struct opa_vnic_vema_mad *)mad_wc->recv_buf.mad,
			 vema_mad);
		break;
	case IB_MGMT_METHOD_SET:
		vema_set(port, (struct opa_vnic_vema_mad *)mad_wc->recv_buf.mad,
			 vema_mad);
		break;
	default:
		vema_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR;
		break;
	}
	mutex_unlock(&port->lock);

	if (!ib_post_send_mad(rsp, NULL)) {
		/*
		 * with post send successful ah and send mad
		 * will be destroyed in send handler
		 */
		goto free_recv_mad;
	}

	ib_free_send_mad(rsp);

err_rsp:
	rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
free_recv_mad:
	ib_free_recv_mad(mad_wc);
}

/**
 * vema_get_port -- Gets the opa_vnic_vema_port
 * @cport: pointer to control dev
 * @port_num: Port number
 *
 * This function loops through the ports and returns
 * the opa_vnic_vema port structure that is associated
 * with the OPA port number
 *
 * Return: ptr to requested opa_vnic_vema_port strucure
 *         if success, NULL if not
 */
static struct opa_vnic_vema_port *
vema_get_port(struct opa_vnic_ctrl_port *cport, u8 port_num)
{
	struct opa_vnic_vema_port *port = (void *)cport + sizeof(*cport);

	if (port_num > cport->num_ports)
		return NULL;

	return port + (port_num - 1);
}

/**
 * opa_vnic_vema_send_trap -- This function sends a trap to the EM
 * @adapter: pointer to vnic adapter
 * @data: pointer to trap data filled by calling function
 * @lid:  issuers lid (encap_slid from vesw_port_info)
 *
 * This function is called from the VNIC driver to send a trap if there
 * is somethng the EM should be notified about. These events currently
 * are
 * 1) UNICAST INTERFACE MACADDRESS changes
 * 2) MULTICAST INTERFACE MACADDRESS changes
 * 3) ETHERNET LINK STATUS changes
 * While allocating the send mad the remote site qpn used is 1
 * as this is the well known QP.
 *
 */
void opa_vnic_vema_send_trap(struct opa_vnic_adapter *adapter,
			     struct __opa_veswport_trap *data, u32 lid)
{
	struct opa_vnic_ctrl_port *cport = adapter->cport;
	struct ib_mad_send_buf *send_buf;
	struct opa_vnic_vema_port *port;
	struct ib_device *ibp;
	struct opa_vnic_vema_mad_trap *trap_mad;
	struct opa_class_port_info *class;
	struct rdma_ah_attr ah_attr;
	struct ib_ah *ah;
	struct opa_veswport_trap *trap;
	u32 trap_lid;
	u16 pkey_idx;

	if (!cport)
		goto err_exit;
	ibp = cport->ibdev;
	port = vema_get_port(cport, data->opaportnum);
	if (!port || !port->mad_agent)
		goto err_exit;

	if (time_before(jiffies, adapter->trap_timeout)) {
		if (adapter->trap_count == OPA_VNIC_TRAP_BURST_LIMIT) {
			v_warn("Trap rate exceeded\n");
			goto err_exit;
		} else {
			adapter->trap_count++;
		}
	} else {
		adapter->trap_count = 0;
	}

	class = &port->class_port_info;
	/* Set up address handle */
	memset(&ah_attr, 0, sizeof(ah_attr));
	ah_attr.type = rdma_ah_find_type(ibp, port->port_num);
	rdma_ah_set_sl(&ah_attr,
		       GET_TRAP_SL_FROM_CLASS_PORT_INFO(class->trap_sl_rsvd));
	rdma_ah_set_port_num(&ah_attr, port->port_num);
	trap_lid = be32_to_cpu(class->trap_lid);
	/*
	 * check for trap lid validity, must not be zero
	 * The trap sink could change after we fashion the MAD but since traps
	 * are not guaranteed we won't use a lock as anyway the change will take
	 * place even with locking.
	 */
	if (!trap_lid) {
		c_err("%s: Invalid dlid\n", __func__);
		goto err_exit;
	}

	rdma_ah_set_dlid(&ah_attr, trap_lid);
	ah = rdma_create_ah(port->mad_agent->qp->pd, &ah_attr, 0);
	if (IS_ERR(ah)) {
		c_err("%s:Couldn't create new AH = %p\n", __func__, ah);
		c_err("%s:dlid = %d, sl = %d, port = %d\n", __func__,
		      rdma_ah_get_dlid(&ah_attr), rdma_ah_get_sl(&ah_attr),
		      rdma_ah_get_port_num(&ah_attr));
		goto err_exit;
	}

	if (ib_find_pkey(ibp, data->opaportnum, IB_DEFAULT_PKEY_FULL,
			 &pkey_idx) < 0) {
		c_err("%s:full key not found, defaulting to partial\n",
		      __func__);
		if (ib_find_pkey(ibp, data->opaportnum, IB_DEFAULT_PKEY_PARTIAL,
				 &pkey_idx) < 0)
			pkey_idx = 1;
	}

	send_buf = ib_create_send_mad(port->mad_agent, 1, pkey_idx, 0,
				      IB_MGMT_VENDOR_HDR, IB_MGMT_MAD_DATA,
				      GFP_ATOMIC, OPA_MGMT_BASE_VERSION);
	if (IS_ERR(send_buf)) {
		c_err("%s:Couldn't allocate send buf\n", __func__);
		goto err_sndbuf;
	}

	send_buf->ah = ah;

	/* Set up common MAD hdr */
	trap_mad = send_buf->mad;
	trap_mad->mad_hdr.base_version = OPA_MGMT_BASE_VERSION;
	trap_mad->mad_hdr.mgmt_class = OPA_MGMT_CLASS_INTEL_EMA;
	trap_mad->mad_hdr.class_version = OPA_EMA_CLASS_VERSION;
	trap_mad->mad_hdr.method = IB_MGMT_METHOD_TRAP;
	port->tid++;
	trap_mad->mad_hdr.tid = cpu_to_be64(port->tid);
	trap_mad->mad_hdr.attr_id = IB_SMP_ATTR_NOTICE;

	/* Set up vendor OUI */
	trap_mad->oui[0] = INTEL_OUI_1;
	trap_mad->oui[1] = INTEL_OUI_2;
	trap_mad->oui[2] = INTEL_OUI_3;

	/* Setup notice attribute portion */
	trap_mad->notice.gen_type = OPA_INTEL_EMA_NOTICE_TYPE_INFO << 1;
	trap_mad->notice.oui_1 = INTEL_OUI_1;
	trap_mad->notice.oui_2 = INTEL_OUI_2;
	trap_mad->notice.oui_3 = INTEL_OUI_3;
	trap_mad->notice.issuer_lid = cpu_to_be32(lid);

	/* copy the actual trap data */
	trap = (struct opa_veswport_trap *)trap_mad->notice.raw_data;
	trap->fabric_id = cpu_to_be16(data->fabric_id);
	trap->veswid = cpu_to_be16(data->veswid);
	trap->veswportnum = cpu_to_be32(data->veswportnum);
	trap->opaportnum = cpu_to_be16(data->opaportnum);
	trap->veswportindex = data->veswportindex;
	trap->opcode = data->opcode;

	/* If successful send set up rate limit timeout else bail */
	if (ib_post_send_mad(send_buf, NULL)) {
		ib_free_send_mad(send_buf);
	} else {
		if (adapter->trap_count)
			return;
		adapter->trap_timeout = jiffies +
					usecs_to_jiffies(OPA_VNIC_TRAP_TIMEOUT);
		return;
	}

err_sndbuf:
	rdma_destroy_ah(ah, 0);
err_exit:
	v_err("Aborting trap\n");
}

static void opa_vnic_event(struct ib_event_handler *handler,
			   struct ib_event *record)
{
	struct opa_vnic_vema_port *port =
		container_of(handler, struct opa_vnic_vema_port, event_handler);
	struct opa_vnic_ctrl_port *cport = port->cport;
	struct opa_vnic_adapter *adapter;
	unsigned long index;

	if (record->element.port_num != port->port_num)
		return;

	c_dbg("OPA_VNIC received event %d on device %s port %d\n",
	      record->event, dev_name(&record->device->dev),
	      record->element.port_num);

	if (record->event != IB_EVENT_PORT_ERR &&
	    record->event != IB_EVENT_PORT_ACTIVE)
		return;

	xa_for_each(&port->vports, index, adapter) {
		if (record->event == IB_EVENT_PORT_ACTIVE)
			netif_carrier_on(adapter->netdev);
		else
			netif_carrier_off(adapter->netdev);
	}
}

/**
 * vema_unregister -- Unregisters agent
 * @cport: pointer to control port
 *
 * This deletes the registration by VEMA for MADs
 */
static void vema_unregister(struct opa_vnic_ctrl_port *cport)
{
	struct opa_vnic_adapter *adapter;
	unsigned long index;
	int i;

	for (i = 1; i <= cport->num_ports; i++) {
		struct opa_vnic_vema_port *port = vema_get_port(cport, i);

		if (!port->mad_agent)
			continue;

		/* Lock ensures no MAD is being processed */
		mutex_lock(&port->lock);
		xa_for_each(&port->vports, index, adapter)
			opa_vnic_rem_netdev(adapter);
		mutex_unlock(&port->lock);

		ib_unregister_mad_agent(port->mad_agent);
		port->mad_agent = NULL;
		mutex_destroy(&port->lock);
		xa_destroy(&port->vports);
		ib_unregister_event_handler(&port->event_handler);
	}
}

/**
 * vema_register -- Registers agent
 * @cport: pointer to control port
 *
 * This function registers the handlers for the VEMA MADs
 *
 * Return: returns 0 on success. non zero otherwise
 */
static int vema_register(struct opa_vnic_ctrl_port *cport)
{
	struct ib_mad_reg_req reg_req = {
		.mgmt_class = OPA_MGMT_CLASS_INTEL_EMA,
		.mgmt_class_version = OPA_MGMT_BASE_VERSION,
		.oui = { INTEL_OUI_1, INTEL_OUI_2, INTEL_OUI_3 }
	};
	int i;

	set_bit(IB_MGMT_METHOD_GET, reg_req.method_mask);
	set_bit(IB_MGMT_METHOD_SET, reg_req.method_mask);

	/* register ib event handler and mad agent for each port on dev */
	for (i = 1; i <= cport->num_ports; i++) {
		struct opa_vnic_vema_port *port = vema_get_port(cport, i);
		int ret;

		port->cport = cport;
		port->port_num = i;

		INIT_IB_EVENT_HANDLER(&port->event_handler,
				      cport->ibdev, opa_vnic_event);
		ib_register_event_handler(&port->event_handler);

		xa_init(&port->vports);
		mutex_init(&port->lock);
		port->mad_agent = ib_register_mad_agent(cport->ibdev, i,
							IB_QPT_GSI, &reg_req,
							IB_MGMT_RMPP_VERSION,
							vema_send, vema_recv,
							port, 0);
		if (IS_ERR(port->mad_agent)) {
			ret = PTR_ERR(port->mad_agent);
			port->mad_agent = NULL;
			mutex_destroy(&port->lock);
			vema_unregister(cport);
			return ret;
		}
	}

	return 0;
}

/**
 * opa_vnic_ctrl_config_dev -- This function sends a trap to the EM
 * by way of ib_modify_port to indicate support for ethernet on the
 * fabric.
 * @cport: pointer to control port
 * @en: enable or disable ethernet on fabric support
 */
static void opa_vnic_ctrl_config_dev(struct opa_vnic_ctrl_port *cport, bool en)
{
	struct ib_port_modify pm = { 0 };
	int i;

	if (en)
		pm.set_port_cap_mask = OPA_CAP_MASK3_IsEthOnFabricSupported;
	else
		pm.clr_port_cap_mask = OPA_CAP_MASK3_IsEthOnFabricSupported;

	for (i = 1; i <= cport->num_ports; i++)
		ib_modify_port(cport->ibdev, i, IB_PORT_OPA_MASK_CHG, &pm);
}

/**
 * opa_vnic_vema_add_one -- Handle new ib device
 * @device: ib device pointer
 *
 * Allocate the vnic control port and initialize it.
 */
static int opa_vnic_vema_add_one(struct ib_device *device)
{
	struct opa_vnic_ctrl_port *cport;
	int rc, size = sizeof(*cport);

	if (!rdma_cap_opa_vnic(device))
		return -EOPNOTSUPP;

	size += device->phys_port_cnt * sizeof(struct opa_vnic_vema_port);
	cport = kzalloc(size, GFP_KERNEL);
	if (!cport)
		return -ENOMEM;

	cport->num_ports = device->phys_port_cnt;
	cport->ibdev = device;

	/* Initialize opa vnic management agent (vema) */
	rc = vema_register(cport);
	if (!rc)
		c_info("VNIC client initialized\n");

	ib_set_client_data(device, &opa_vnic_client, cport);
	opa_vnic_ctrl_config_dev(cport, true);
	return 0;
}

/**
 * opa_vnic_vema_rem_one -- Handle ib device removal
 * @device: ib device pointer
 * @client_data: ib client data
 *
 * Uninitialize and free the vnic control port.
 */
static void opa_vnic_vema_rem_one(struct ib_device *device,
				  void *client_data)
{
	struct opa_vnic_ctrl_port *cport = client_data;

	c_info("removing VNIC client\n");
	opa_vnic_ctrl_config_dev(cport, false);
	vema_unregister(cport);
	kfree(cport);
}

static int __init opa_vnic_init(void)
{
	int rc;

	rc = ib_register_client(&opa_vnic_client);
	if (rc)
		pr_err("VNIC driver register failed %d\n", rc);

	return rc;
}
module_init(opa_vnic_init);

static void opa_vnic_deinit(void)
{
	ib_unregister_client(&opa_vnic_client);
}
module_exit(opa_vnic_deinit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Cornelis Networks");
MODULE_DESCRIPTION("Cornelis OPX Virtual Network driver");
