/*
 * Copyright(c) 2017 Intel Corporation.
 *
 * 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 OPA VNIC EMA Interface functions.
 */

#include "opa_vnic_internal.h"

/**
 * opa_vnic_vema_report_event - sent trap to report the specified event
 * @adapter: vnic port adapter
 * @event: event to be reported
 *
 * This function calls vema api to sent a trap for the given event.
 */
void opa_vnic_vema_report_event(struct opa_vnic_adapter *adapter, u8 event)
{
	struct __opa_veswport_info *info = &adapter->info;
	struct __opa_veswport_trap trap_data;

	trap_data.fabric_id = info->vesw.fabric_id;
	trap_data.veswid = info->vesw.vesw_id;
	trap_data.veswportnum = info->vport.port_num;
	trap_data.opaportnum = adapter->port_num;
	trap_data.veswportindex = adapter->vport_num;
	trap_data.opcode = event;

	opa_vnic_vema_send_trap(adapter, &trap_data, info->vport.encap_slid);
}

/**
 * opa_vnic_get_error_counters - get summary counters
 * @adapter: vnic port adapter
 * @cntrs: pointer to destination summary counters structure
 *
 * This function populates the summary counters that is maintained by the
 * given adapter to destination address provided.
 */
void opa_vnic_get_summary_counters(struct opa_vnic_adapter *adapter,
				   struct opa_veswport_summary_counters *cntrs)
{
	struct opa_vnic_stats vstats;
	__be64 *dst;
	u64 *src;

	memset(&vstats, 0, sizeof(vstats));
	spin_lock(&adapter->stats_lock);
	adapter->rn_ops->ndo_get_stats64(adapter->netdev, &vstats.netstats);
	spin_unlock(&adapter->stats_lock);

	cntrs->vp_instance = cpu_to_be16(adapter->vport_num);
	cntrs->vesw_id = cpu_to_be16(adapter->info.vesw.vesw_id);
	cntrs->veswport_num = cpu_to_be32(adapter->port_num);

	cntrs->tx_errors = cpu_to_be64(vstats.netstats.tx_errors);
	cntrs->rx_errors = cpu_to_be64(vstats.netstats.rx_errors);
	cntrs->tx_packets = cpu_to_be64(vstats.netstats.tx_packets);
	cntrs->rx_packets = cpu_to_be64(vstats.netstats.rx_packets);
	cntrs->tx_bytes = cpu_to_be64(vstats.netstats.tx_bytes);
	cntrs->rx_bytes = cpu_to_be64(vstats.netstats.rx_bytes);

	/*
	 * This loop depends on layout of
	 * opa_veswport_summary_counters opa_vnic_stats structures.
	 */
	for (dst = &cntrs->tx_unicast, src = &vstats.tx_grp.unicast;
	     dst < &cntrs->reserved[0]; dst++, src++) {
		*dst = cpu_to_be64(*src);
	}
}

/**
 * opa_vnic_get_error_counters - get error counters
 * @adapter: vnic port adapter
 * @cntrs: pointer to destination error counters structure
 *
 * This function populates the error counters that is maintained by the
 * given adapter to destination address provided.
 */
void opa_vnic_get_error_counters(struct opa_vnic_adapter *adapter,
				 struct opa_veswport_error_counters *cntrs)
{
	struct opa_vnic_stats vstats;

	memset(&vstats, 0, sizeof(vstats));
	spin_lock(&adapter->stats_lock);
	adapter->rn_ops->ndo_get_stats64(adapter->netdev, &vstats.netstats);
	spin_unlock(&adapter->stats_lock);

	cntrs->vp_instance = cpu_to_be16(adapter->vport_num);
	cntrs->vesw_id = cpu_to_be16(adapter->info.vesw.vesw_id);
	cntrs->veswport_num = cpu_to_be32(adapter->port_num);

	cntrs->tx_errors = cpu_to_be64(vstats.netstats.tx_errors);
	cntrs->rx_errors = cpu_to_be64(vstats.netstats.rx_errors);
	cntrs->tx_dlid_zero = cpu_to_be64(vstats.tx_dlid_zero);
	cntrs->tx_drop_state = cpu_to_be64(vstats.tx_drop_state);
	cntrs->tx_logic = cpu_to_be64(vstats.netstats.tx_fifo_errors +
				      vstats.netstats.tx_carrier_errors);

	cntrs->rx_bad_veswid = cpu_to_be64(vstats.netstats.rx_nohandler);
	cntrs->rx_runt = cpu_to_be64(vstats.rx_runt);
	cntrs->rx_oversize = cpu_to_be64(vstats.rx_oversize);
	cntrs->rx_drop_state = cpu_to_be64(vstats.rx_drop_state);
	cntrs->rx_logic = cpu_to_be64(vstats.netstats.rx_fifo_errors);
}

/**
 * opa_vnic_get_vesw_info -- Get the vesw information
 * @adapter: vnic port adapter
 * @info: pointer to destination vesw info structure
 *
 * This function copies the vesw info that is maintained by the
 * given adapter to destination address provided.
 */
void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter,
			    struct opa_vesw_info *info)
{
	struct __opa_vesw_info *src = &adapter->info.vesw;
	int i;

	info->fabric_id = cpu_to_be16(src->fabric_id);
	info->vesw_id = cpu_to_be16(src->vesw_id);
	memcpy(info->rsvd0, src->rsvd0, ARRAY_SIZE(src->rsvd0));
	info->def_port_mask = cpu_to_be16(src->def_port_mask);
	memcpy(info->rsvd1, src->rsvd1, ARRAY_SIZE(src->rsvd1));
	info->pkey = cpu_to_be16(src->pkey);

	memcpy(info->rsvd2, src->rsvd2, ARRAY_SIZE(src->rsvd2));
	info->u_mcast_dlid = cpu_to_be32(src->u_mcast_dlid);
	for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
		info->u_ucast_dlid[i] = cpu_to_be32(src->u_ucast_dlid[i]);

	memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
	for (i = 0; i < OPA_VNIC_MAX_NUM_PCP; i++)
		info->eth_mtu[i] = cpu_to_be16(src->eth_mtu[i]);

	info->eth_mtu_non_vlan = cpu_to_be16(src->eth_mtu_non_vlan);
	memcpy(info->rsvd4, src->rsvd4, ARRAY_SIZE(src->rsvd4));
}

/**
 * opa_vnic_set_vesw_info -- Set the vesw information
 * @adapter: vnic port adapter
 * @info: pointer to vesw info structure
 *
 * This function updates the vesw info that is maintained by the
 * given adapter with vesw info provided. Reserved fields are stored
 * and returned back to EM as is.
 */
void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter,
			    struct opa_vesw_info *info)
{
	struct __opa_vesw_info *dst = &adapter->info.vesw;
	int i;

	dst->fabric_id = be16_to_cpu(info->fabric_id);
	dst->vesw_id = be16_to_cpu(info->vesw_id);
	memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0));
	dst->def_port_mask = be16_to_cpu(info->def_port_mask);
	memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1));
	dst->pkey = be16_to_cpu(info->pkey);

	memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2));
	dst->u_mcast_dlid = be32_to_cpu(info->u_mcast_dlid);
	for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
		dst->u_ucast_dlid[i] = be32_to_cpu(info->u_ucast_dlid[i]);

	memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
	for (i = 0; i < OPA_VNIC_MAX_NUM_PCP; i++)
		dst->eth_mtu[i] = be16_to_cpu(info->eth_mtu[i]);

	dst->eth_mtu_non_vlan = be16_to_cpu(info->eth_mtu_non_vlan);
	memcpy(dst->rsvd4, info->rsvd4, ARRAY_SIZE(info->rsvd4));
}

/**
 * opa_vnic_get_per_veswport_info -- Get the vesw per port information
 * @adapter: vnic port adapter
 * @info: pointer to destination vport info structure
 *
 * This function copies the vesw per port info that is maintained by the
 * given adapter to destination address provided.
 * Note that the read only fields are not copied.
 */
void opa_vnic_get_per_veswport_info(struct opa_vnic_adapter *adapter,
				    struct opa_per_veswport_info *info)
{
	struct __opa_per_veswport_info *src = &adapter->info.vport;

	info->port_num = cpu_to_be32(src->port_num);
	info->eth_link_status = src->eth_link_status;
	memcpy(info->rsvd0, src->rsvd0, ARRAY_SIZE(src->rsvd0));

	memcpy(info->base_mac_addr, src->base_mac_addr,
	       ARRAY_SIZE(info->base_mac_addr));
	info->config_state = src->config_state;
	info->oper_state = src->oper_state;
	info->max_mac_tbl_ent = cpu_to_be16(src->max_mac_tbl_ent);
	info->max_smac_ent = cpu_to_be16(src->max_smac_ent);
	info->mac_tbl_digest = cpu_to_be32(src->mac_tbl_digest);
	memcpy(info->rsvd1, src->rsvd1, ARRAY_SIZE(src->rsvd1));

	info->encap_slid = cpu_to_be32(src->encap_slid);
	memcpy(info->pcp_to_sc_uc, src->pcp_to_sc_uc,
	       ARRAY_SIZE(info->pcp_to_sc_uc));
	memcpy(info->pcp_to_vl_uc, src->pcp_to_vl_uc,
	       ARRAY_SIZE(info->pcp_to_vl_uc));
	memcpy(info->pcp_to_sc_mc, src->pcp_to_sc_mc,
	       ARRAY_SIZE(info->pcp_to_sc_mc));
	memcpy(info->pcp_to_vl_mc, src->pcp_to_vl_mc,
	       ARRAY_SIZE(info->pcp_to_vl_mc));
	info->non_vlan_sc_uc = src->non_vlan_sc_uc;
	info->non_vlan_vl_uc = src->non_vlan_vl_uc;
	info->non_vlan_sc_mc = src->non_vlan_sc_mc;
	info->non_vlan_vl_mc = src->non_vlan_vl_mc;
	memcpy(info->rsvd2, src->rsvd2, ARRAY_SIZE(src->rsvd2));

	info->uc_macs_gen_count = cpu_to_be16(src->uc_macs_gen_count);
	info->mc_macs_gen_count = cpu_to_be16(src->mc_macs_gen_count);
	memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
}

/**
 * opa_vnic_set_per_veswport_info -- Set vesw per port information
 * @adapter: vnic port adapter
 * @info: pointer to vport info structure
 *
 * This function updates the vesw per port info that is maintained by the
 * given adapter with vesw per port info provided. Reserved fields are
 * stored and returned back to EM as is.
 */
void opa_vnic_set_per_veswport_info(struct opa_vnic_adapter *adapter,
				    struct opa_per_veswport_info *info)
{
	struct __opa_per_veswport_info *dst = &adapter->info.vport;

	dst->port_num = be32_to_cpu(info->port_num);
	memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0));

	memcpy(dst->base_mac_addr, info->base_mac_addr,
	       ARRAY_SIZE(dst->base_mac_addr));
	dst->config_state = info->config_state;
	memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1));

	dst->encap_slid = be32_to_cpu(info->encap_slid);
	memcpy(dst->pcp_to_sc_uc, info->pcp_to_sc_uc,
	       ARRAY_SIZE(dst->pcp_to_sc_uc));
	memcpy(dst->pcp_to_vl_uc, info->pcp_to_vl_uc,
	       ARRAY_SIZE(dst->pcp_to_vl_uc));
	memcpy(dst->pcp_to_sc_mc, info->pcp_to_sc_mc,
	       ARRAY_SIZE(dst->pcp_to_sc_mc));
	memcpy(dst->pcp_to_vl_mc, info->pcp_to_vl_mc,
	       ARRAY_SIZE(dst->pcp_to_vl_mc));
	dst->non_vlan_sc_uc = info->non_vlan_sc_uc;
	dst->non_vlan_vl_uc = info->non_vlan_vl_uc;
	dst->non_vlan_sc_mc = info->non_vlan_sc_mc;
	dst->non_vlan_vl_mc = info->non_vlan_vl_mc;
	memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2));
	memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
}

/**
 * opa_vnic_query_mcast_macs - query multicast mac list
 * @adapter: vnic port adapter
 * @macs: pointer mac list
 *
 * This function populates the provided mac list with the configured
 * multicast addresses in the adapter.
 */
void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter,
			       struct opa_veswport_iface_macs *macs)
{
	u16 start_idx, num_macs, idx = 0, count = 0;
	struct netdev_hw_addr *ha;

	start_idx = be16_to_cpu(macs->start_idx);
	num_macs = be16_to_cpu(macs->num_macs_in_msg);
	netdev_for_each_mc_addr(ha, adapter->netdev) {
		struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];

		if (start_idx > idx++)
			continue;
		else if (num_macs == count)
			break;
		memcpy(entry, ha->addr, sizeof(*entry));
		count++;
	}

	macs->tot_macs_in_lst = cpu_to_be16(netdev_mc_count(adapter->netdev));
	macs->num_macs_in_msg = cpu_to_be16(count);
	macs->gen_count = cpu_to_be16(adapter->info.vport.mc_macs_gen_count);
}

/**
 * opa_vnic_query_ucast_macs - query unicast mac list
 * @adapter: vnic port adapter
 * @macs: pointer mac list
 *
 * This function populates the provided mac list with the configured
 * unicast addresses in the adapter.
 */
void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter,
			       struct opa_veswport_iface_macs *macs)
{
	u16 start_idx, tot_macs, num_macs, idx = 0, count = 0;
	struct netdev_hw_addr *ha;

	start_idx = be16_to_cpu(macs->start_idx);
	num_macs = be16_to_cpu(macs->num_macs_in_msg);
	/* loop through dev_addrs list first */
	for_each_dev_addr(adapter->netdev, ha) {
		struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];

		/* Do not include EM specified MAC address */
		if (!memcmp(adapter->info.vport.base_mac_addr, ha->addr,
			    ARRAY_SIZE(adapter->info.vport.base_mac_addr)))
			continue;

		if (start_idx > idx++)
			continue;
		else if (num_macs == count)
			break;
		memcpy(entry, ha->addr, sizeof(*entry));
		count++;
	}

	/* loop through uc list */
	netdev_for_each_uc_addr(ha, adapter->netdev) {
		struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];

		if (start_idx > idx++)
			continue;
		else if (num_macs == count)
			break;
		memcpy(entry, ha->addr, sizeof(*entry));
		count++;
	}

	tot_macs = netdev_hw_addr_list_count(&adapter->netdev->dev_addrs) +
		   netdev_uc_count(adapter->netdev);
	macs->tot_macs_in_lst = cpu_to_be16(tot_macs);
	macs->num_macs_in_msg = cpu_to_be16(count);
	macs->gen_count = cpu_to_be16(adapter->info.vport.uc_macs_gen_count);
}
