/*
 * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     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.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux_compat.h>
#include <linux/mlx4/cmd.h>

#include "mlx4.h"
#include "mlx4_stats.h"

#define MLX4_MAC_VALID		(1ull << 63)

#define MLX4_VLAN_VALID		(1u << 31)
#define MLX4_VLAN_MASK		0xfff

#define MLX4_STATS_TRAFFIC_COUNTERS_MASK	0xfULL
#define MLX4_STATS_TRAFFIC_DROPS_MASK		0xc0ULL
#define MLX4_STATS_ERROR_COUNTERS_MASK		0x1ffc30ULL
#define MLX4_STATS_PORT_COUNTERS_MASK		0x1fe00000ULL

#define MLX4_FLAG_V_IGNORE_FCS_MASK		0x2
#define MLX4_IGNORE_FCS_MASK			0x1

void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table)
{
	int i;

	qlock_init(&table->mutex);
	for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
		table->entries[i] = 0;
		table->refs[i]	 = 0;
	}
	table->max   = 1 << dev->caps.log_num_macs;
	table->total = 0;
}

void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table)
{
	int i;

	qlock_init(&table->mutex);
	for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
		table->entries[i] = 0;
		table->refs[i]	 = 0;
	}
	table->max   = (1 << dev->caps.log_num_vlans) - MLX4_VLAN_REGULAR;
	table->total = 0;
}

void mlx4_init_roce_gid_table(struct mlx4_dev *dev,
			      struct mlx4_roce_gid_table *table)
{
	int i;

	qlock_init(&table->mutex);
	for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++)
		memset(table->roce_gids[i].raw, 0, MLX4_ROCE_GID_ENTRY_SIZE);
}

static int validate_index(struct mlx4_dev *dev,
			  struct mlx4_mac_table *table, int index)
{
	int err = 0;

	if (index < 0 || index >= table->max || !table->entries[index]) {
		mlx4_warn(dev, "No valid Mac entry for the given index\n");
		err = -EINVAL;
	}
	return err;
}

static int find_index(struct mlx4_dev *dev,
		      struct mlx4_mac_table *table, uint64_t mac)
{
	int i;

	for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
		if (table->refs[i] &&
		    (MLX4_MAC_MASK & mac) ==
		    (MLX4_MAC_MASK & be64_to_cpu(table->entries[i])))
			return i;
	}
	/* Mac not found */
	return -EINVAL;
}

static int mlx4_set_port_mac_table(struct mlx4_dev *dev, uint8_t port,
				   __be64 *entries)
{
	struct mlx4_cmd_mailbox *mailbox;
	uint32_t in_mod;
	int err;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);

	memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);

	in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;

	err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
		       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
		       MLX4_CMD_NATIVE);

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}

int mlx4_find_cached_mac(struct mlx4_dev *dev, uint8_t port, uint64_t mac,
			 int *idx)
{
	struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
	struct mlx4_mac_table *table = &info->mac_table;
	int i;

	for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
		if (!table->refs[i])
			continue;

		if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
			*idx = i;
			return 0;
		}
	}

	return -ENOENT;
}
EXPORT_SYMBOL_GPL(mlx4_find_cached_mac);

int __mlx4_register_mac(struct mlx4_dev *dev, uint8_t port, uint64_t mac)
{
	struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
	struct mlx4_mac_table *table = &info->mac_table;
	int i, err = 0;
	int free = -1;

	mlx4_dbg(dev, "Registering MAC: 0x%llx for port %d\n",
		 (unsigned long long) mac, port);

	qlock(&table->mutex);
	for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
		if (!table->refs[i]) {
			if (free < 0)
				free = i;
			continue;
		}

		if ((MLX4_MAC_MASK & mac) ==
		     (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
			/* MAC already registered, increment ref count */
			err = i;
			++table->refs[i];
			goto out;
		}
	}

	mlx4_dbg(dev, "Free MAC index is %d\n", free);

	if (table->total == table->max) {
		/* No free mac entries */
		err = -ENOSPC;
		goto out;
	}

	/* Register new MAC */
	table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID);

	err = mlx4_set_port_mac_table(dev, port, table->entries);
	if (unlikely(err)) {
		mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
			 (unsigned long long) mac);
		table->entries[free] = 0;
		goto out;
	}
	table->refs[free] = 1;
	err = free;
	++table->total;
out:
	qunlock(&table->mutex);
	return err;
}
EXPORT_SYMBOL_GPL(__mlx4_register_mac);

int mlx4_register_mac(struct mlx4_dev *dev, uint8_t port, uint64_t mac)
{
	uint64_t out_param = 0;
	int err = -EINVAL;

	if (mlx4_is_mfunc(dev)) {
		if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
			err = mlx4_cmd_imm(dev, mac, &out_param,
					   ((uint32_t) port) << 8 | (uint32_t) RES_MAC,
					   RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
					   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
		}
		if (err && err == -EINVAL && mlx4_is_slave(dev)) {
			/* retry using old REG_MAC format */
			set_param_l(&out_param, port);
			err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
					   RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
					   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
			if (!err)
				dev->flags |= MLX4_FLAG_OLD_REG_MAC;
		}
		if (err)
			return err;

		return get_param_l(&out_param);
	}
	return __mlx4_register_mac(dev, port, mac);
}
EXPORT_SYMBOL_GPL(mlx4_register_mac);

int mlx4_get_base_qpn(struct mlx4_dev *dev, uint8_t port)
{
	return dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] +
			(port - 1) * (1 << dev->caps.log_num_macs);
}
EXPORT_SYMBOL_GPL(mlx4_get_base_qpn);

void __mlx4_unregister_mac(struct mlx4_dev *dev, uint8_t port, uint64_t mac)
{
	struct mlx4_port_info *info;
	struct mlx4_mac_table *table;
	int index;

	if (port < 1 || port > dev->caps.num_ports) {
		mlx4_warn(dev, "invalid port number (%d), aborting...\n", port);
		return;
	}
	info = &mlx4_priv(dev)->port[port];
	table = &info->mac_table;
	qlock(&table->mutex);
	index = find_index(dev, table, mac);

	if (validate_index(dev, table, index))
		goto out;
	if (--table->refs[index]) {
		mlx4_dbg(dev, "Have more references for index %d, no need to modify mac table\n",
			 index);
		goto out;
	}

	table->entries[index] = 0;
	mlx4_set_port_mac_table(dev, port, table->entries);
	--table->total;
out:
	qunlock(&table->mutex);
}
EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);

void mlx4_unregister_mac(struct mlx4_dev *dev, uint8_t port, uint64_t mac)
{
	uint64_t out_param = 0;

	if (mlx4_is_mfunc(dev)) {
		if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
			(void) mlx4_cmd_imm(dev, mac, &out_param,
					    ((uint32_t) port) << 8 | (uint32_t) RES_MAC,
					    RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
					    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
		} else {
			/* use old unregister mac format */
			set_param_l(&out_param, port);
			(void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
					    RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
					    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
		}
		return;
	}
	__mlx4_unregister_mac(dev, port, mac);
	return;
}
EXPORT_SYMBOL_GPL(mlx4_unregister_mac);

int __mlx4_replace_mac(struct mlx4_dev *dev, uint8_t port, int qpn,
		       uint64_t new_mac)
{
	struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
	struct mlx4_mac_table *table = &info->mac_table;
	int index = qpn - info->base_qpn;
	int err = 0;

	/* CX1 doesn't support multi-functions */
	qlock(&table->mutex);

	err = validate_index(dev, table, index);
	if (err)
		goto out;

	table->entries[index] = cpu_to_be64(new_mac | MLX4_MAC_VALID);

	err = mlx4_set_port_mac_table(dev, port, table->entries);
	if (unlikely(err)) {
		mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
			 (unsigned long long) new_mac);
		table->entries[index] = 0;
	}
out:
	qunlock(&table->mutex);
	return err;
}
EXPORT_SYMBOL_GPL(__mlx4_replace_mac);

static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, uint8_t port,
				    __be32 *entries)
{
	struct mlx4_cmd_mailbox *mailbox;
	uint32_t in_mod;
	int err;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);

	memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
	in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
	err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
		       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
		       MLX4_CMD_NATIVE);

	mlx4_free_cmd_mailbox(dev, mailbox);

	return err;
}

int mlx4_find_cached_vlan(struct mlx4_dev *dev, uint8_t port, uint16_t vid,
			  int *idx)
{
	struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
	int i;

	for (i = 0; i < MLX4_MAX_VLAN_NUM; ++i) {
		if (table->refs[i] &&
		    (vid == (MLX4_VLAN_MASK &
			      be32_to_cpu(table->entries[i])))) {
			/* VLAN already registered, increase reference count */
			*idx = i;
			return 0;
		}
	}

	return -ENOENT;
}
EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan);

int __mlx4_register_vlan(struct mlx4_dev *dev, uint8_t port, uint16_t vlan,
				int *index)
{
	struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
	int i, err = 0;
	int free = -1;

	qlock(&table->mutex);

	if (table->total == table->max) {
		/* No free vlan entries */
		err = -ENOSPC;
		goto out;
	}

	for (i = MLX4_VLAN_REGULAR; i < MLX4_MAX_VLAN_NUM; i++) {
		if (free < 0 && (table->refs[i] == 0)) {
			free = i;
			continue;
		}

		if (table->refs[i] &&
		    (vlan == (MLX4_VLAN_MASK &
			      be32_to_cpu(table->entries[i])))) {
			/* Vlan already registered, increase references count */
			*index = i;
			++table->refs[i];
			goto out;
		}
	}

	if (free < 0) {
		err = -ENOMEM;
		goto out;
	}

	/* Register new VLAN */
	table->refs[free] = 1;
	table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);

	err = mlx4_set_port_vlan_table(dev, port, table->entries);
	if (unlikely(err)) {
		mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);
		table->refs[free] = 0;
		table->entries[free] = 0;
		goto out;
	}

	*index = free;
	++table->total;
out:
	qunlock(&table->mutex);
	return err;
}

int mlx4_register_vlan(struct mlx4_dev *dev, uint8_t port, uint16_t vlan,
		       int *index)
{
	uint64_t out_param = 0;
	int err;

	if (vlan > 4095)
		return -EINVAL;

	if (mlx4_is_mfunc(dev)) {
		err = mlx4_cmd_imm(dev, vlan, &out_param,
				   ((uint32_t) port) << 8 | (uint32_t) RES_VLAN,
				   RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
				   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
		if (!err)
			*index = get_param_l(&out_param);

		return err;
	}
	return __mlx4_register_vlan(dev, port, vlan, index);
}
EXPORT_SYMBOL_GPL(mlx4_register_vlan);

void __mlx4_unregister_vlan(struct mlx4_dev *dev, uint8_t port, uint16_t vlan)
{
	struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
	int index;

	qlock(&table->mutex);
	if (mlx4_find_cached_vlan(dev, port, vlan, &index)) {
		mlx4_warn(dev, "vlan 0x%x is not in the vlan table\n", vlan);
		goto out;
	}

	if (index < MLX4_VLAN_REGULAR) {
		mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
		goto out;
	}

	if (--table->refs[index]) {
		mlx4_dbg(dev, "Have %d more references for index %d, no need to modify vlan table\n",
			 table->refs[index], index);
		goto out;
	}
	table->entries[index] = 0;
	mlx4_set_port_vlan_table(dev, port, table->entries);
	--table->total;
out:
	qunlock(&table->mutex);
}

void mlx4_unregister_vlan(struct mlx4_dev *dev, uint8_t port, uint16_t vlan)
{
	uint64_t out_param = 0;

	if (mlx4_is_mfunc(dev)) {
		(void) mlx4_cmd_imm(dev, vlan, &out_param,
				    ((uint32_t) port) << 8 | (uint32_t) RES_VLAN,
				    RES_OP_RESERVE_AND_MAP,
				    MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
				    MLX4_CMD_WRAPPED);
		return;
	}
	__mlx4_unregister_vlan(dev, port, vlan);
}
EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);

int mlx4_get_port_ib_caps(struct mlx4_dev *dev, uint8_t port, __be32 *caps)
{
	struct mlx4_cmd_mailbox *inmailbox, *outmailbox;
	uint8_t *inbuf, *outbuf;
	int err;

	inmailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(inmailbox))
		return PTR_ERR(inmailbox);

	outmailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(outmailbox)) {
		mlx4_free_cmd_mailbox(dev, inmailbox);
		return PTR_ERR(outmailbox);
	}

	inbuf = inmailbox->buf;
	outbuf = outmailbox->buf;
	inbuf[0] = 1;
	inbuf[1] = 1;
	inbuf[2] = 1;
	inbuf[3] = 1;
	*(__be16 *) (&inbuf[16]) = cpu_to_be16(0x0015);
	*(__be32 *) (&inbuf[20]) = cpu_to_be32(port);

	err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3,
			   MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
			   MLX4_CMD_NATIVE);
	if (!err)
		*caps = *(__be32 *) (outbuf + 84);
	mlx4_free_cmd_mailbox(dev, inmailbox);
	mlx4_free_cmd_mailbox(dev, outmailbox);
	return err;
}
static struct mlx4_roce_gid_entry zgid_entry;

int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port)
{
	int vfs;
	int slave_gid = slave;
	unsigned i;
	struct mlx4_slaves_pport slaves_pport;
	struct mlx4_active_ports actv_ports;
	unsigned max_port_p_one;

	if (slave == 0)
		return MLX4_ROCE_PF_GIDS;

	/* Slave is a VF */
	slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
	actv_ports = mlx4_get_active_ports(dev, slave);
	max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
		bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;

	for (i = 1; i < max_port_p_one; i++) {
		struct mlx4_active_ports exclusive_ports;
		struct mlx4_slaves_pport slaves_pport_actv;
		bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
		set_bit(i - 1, exclusive_ports.ports);
		if (i == port)
			continue;
		slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
				    dev, &exclusive_ports);
		slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
					   dev->persist->num_vfs + 1);
	}
	vfs = bitmap_weight(slaves_pport.slaves, dev->persist->num_vfs + 1) - 1;
	if (slave_gid <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % vfs))
		return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs) + 1;
	return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs;
}

int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port)
{
	int gids;
	unsigned i;
	int slave_gid = slave;
	int vfs;

	struct mlx4_slaves_pport slaves_pport;
	struct mlx4_active_ports actv_ports;
	unsigned max_port_p_one;

	if (slave == 0)
		return 0;

	slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
	actv_ports = mlx4_get_active_ports(dev, slave);
	max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
		bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;

	for (i = 1; i < max_port_p_one; i++) {
		struct mlx4_active_ports exclusive_ports;
		struct mlx4_slaves_pport slaves_pport_actv;
		bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
		set_bit(i - 1, exclusive_ports.ports);
		if (i == port)
			continue;
		slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
				    dev, &exclusive_ports);
		slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
					   dev->persist->num_vfs + 1);
	}
	gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
	vfs = bitmap_weight(slaves_pport.slaves, dev->persist->num_vfs + 1) - 1;
	if (slave_gid <= gids % vfs)
		return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave_gid - 1);

	return MLX4_ROCE_PF_GIDS + (gids % vfs) +
		((gids / vfs) * (slave_gid - 1));
}
EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix);

static int mlx4_reset_roce_port_gids(struct mlx4_dev *dev, int slave,
				     int port, struct mlx4_cmd_mailbox *mailbox)
{
	struct mlx4_roce_gid_entry *gid_entry_mbox;
	struct mlx4_priv *priv = mlx4_priv(dev);
	int num_gids, base, offset;
	int i, err;

	num_gids = mlx4_get_slave_num_gids(dev, slave, port);
	base = mlx4_get_base_gid_ix(dev, slave, port);

	memset(mailbox->buf, 0, MLX4_MAILBOX_SIZE);

	qlock(&(priv->port[port].gid_table.mutex));
	/* Zero-out gids belonging to that slave in the port GID table */
	for (i = 0, offset = base; i < num_gids; offset++, i++)
		memcpy(priv->port[port].gid_table.roce_gids[offset].raw,
		       zgid_entry.raw, MLX4_ROCE_GID_ENTRY_SIZE);

	/* Now, copy roce port gids table to mailbox for passing to FW */
	gid_entry_mbox = (struct mlx4_roce_gid_entry *)mailbox->buf;
	for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++)
		memcpy(gid_entry_mbox->raw,
		       priv->port[port].gid_table.roce_gids[i].raw,
		       MLX4_ROCE_GID_ENTRY_SIZE);

	err = mlx4_cmd(dev, mailbox->dma,
		       ((uint32_t)port) | (MLX4_SET_PORT_GID_TABLE << 8),
		       MLX4_SET_PORT_ETH_OPCODE, MLX4_CMD_SET_PORT,
		       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
	qunlock(&(priv->port[port].gid_table.mutex));
	return err;
}


void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave)
{
	struct mlx4_active_ports actv_ports;
	struct mlx4_cmd_mailbox *mailbox;
	int num_eth_ports, err;
	int i;

	if (slave < 0 || slave > dev->persist->num_vfs)
		return;

	actv_ports = mlx4_get_active_ports(dev, slave);

	for (i = 0, num_eth_ports = 0; i < dev->caps.num_ports; i++) {
		if (test_bit(i, actv_ports.ports)) {
			if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH)
				continue;
			num_eth_ports++;
		}
	}

	if (!num_eth_ports)
		return;

	/* have ETH ports.  Alloc mailbox for SET_PORT command */
	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return;

	for (i = 0; i < dev->caps.num_ports; i++) {
		if (test_bit(i, actv_ports.ports)) {
			if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH)
				continue;
			err = mlx4_reset_roce_port_gids(dev, slave, i + 1, mailbox);
			if (err)
				mlx4_warn(dev, "Could not reset ETH port GID table for slave %d, port %d (%d)\n",
					  slave, i + 1, err);
		}
	}

	mlx4_free_cmd_mailbox(dev, mailbox);
	return;
}

static int mlx4_common_set_port(struct mlx4_dev *dev, int slave,
				uint32_t in_mod,
				uint8_t op_mod,
				struct mlx4_cmd_mailbox *inbox)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_port_info *port_info;
	struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
	struct mlx4_slave_state *slave_st = &master->slave_state[slave];
	struct mlx4_set_port_rqp_calc_context *qpn_context;
	struct mlx4_set_port_general_context *gen_context;
	struct mlx4_roce_gid_entry *gid_entry_tbl, *gid_entry_mbox, *gid_entry_mb1;
	int reset_qkey_viols;
	int port;
	int is_eth;
	int num_gids;
	int base;
	uint32_t in_modifier;
	uint32_t promisc;
	uint16_t mtu, prev_mtu;
	int err;
	int i, j;
	int offset;
	__be32 agg_cap_mask;
	__be32 slave_cap_mask;
	__be32 new_cap_mask;

	port = in_mod & 0xff;
	in_modifier = in_mod >> 8;
	is_eth = op_mod;
	port_info = &priv->port[port];

	/* Slaves cannot perform SET_PORT operations except changing MTU */
	if (is_eth) {
		if (slave != dev->caps.function &&
		    in_modifier != MLX4_SET_PORT_GENERAL &&
		    in_modifier != MLX4_SET_PORT_GID_TABLE) {
			mlx4_warn(dev, "denying SET_PORT for slave:%d\n",
					slave);
			return -EINVAL;
		}
		switch (in_modifier) {
		case MLX4_SET_PORT_RQP_CALC:
			qpn_context = inbox->buf;
			qpn_context->base_qpn =
				cpu_to_be32(port_info->base_qpn);
			qpn_context->n_mac = 0x7;
			promisc = be32_to_cpu(qpn_context->promisc) >>
				SET_PORT_PROMISC_SHIFT;
			qpn_context->promisc = cpu_to_be32(
				promisc << SET_PORT_PROMISC_SHIFT |
				port_info->base_qpn);
			promisc = be32_to_cpu(qpn_context->mcast) >>
				SET_PORT_MC_PROMISC_SHIFT;
			qpn_context->mcast = cpu_to_be32(
				promisc << SET_PORT_MC_PROMISC_SHIFT |
				port_info->base_qpn);
			break;
		case MLX4_SET_PORT_GENERAL:
			gen_context = inbox->buf;
			/* Mtu is configured as the max MTU among all the
			 * the functions on the port. */
			mtu = be16_to_cpu(gen_context->mtu);
			mtu = MIN_T(int, mtu,
				    dev->caps.eth_mtu_cap[port] + ETHERHDRSIZE + VLAN_HLEN + ETH_FCS_LEN);
			prev_mtu = slave_st->mtu[port];
			slave_st->mtu[port] = mtu;
			if (mtu > master->max_mtu[port])
				master->max_mtu[port] = mtu;
			if (mtu < prev_mtu && prev_mtu ==
						master->max_mtu[port]) {
				slave_st->mtu[port] = mtu;
				master->max_mtu[port] = mtu;
				for (i = 0; i < dev->num_slaves; i++) {
					master->max_mtu[port] =
					MAX(master->max_mtu[port],
					    master->slave_state[i].mtu[port]);
				}
			}

			gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
			break;
		case MLX4_SET_PORT_GID_TABLE:
			/* change to MULTIPLE entries: number of guest's gids
			 * need a FOR-loop here over number of gids the guest has.
			 * 1. Check no duplicates in gids passed by slave
			 */
			num_gids = mlx4_get_slave_num_gids(dev, slave, port);
			base = mlx4_get_base_gid_ix(dev, slave, port);
			gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
			for (i = 0; i < num_gids; gid_entry_mbox++, i++) {
				if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw,
					    sizeof(zgid_entry)))
					continue;
				gid_entry_mb1 = gid_entry_mbox + 1;
				for (j = i + 1; j < num_gids; gid_entry_mb1++, j++) {
					if (!memcmp(gid_entry_mb1->raw,
						    zgid_entry.raw, sizeof(zgid_entry)))
						continue;
					if (!memcmp(gid_entry_mb1->raw, gid_entry_mbox->raw,
						    sizeof(gid_entry_mbox->raw))) {
						/* found duplicate */
						return -EINVAL;
					}
				}
			}

			/* 2. Check that do not have duplicates in OTHER
			 *    entries in the port GID table
			 */

			qlock(&(priv->port[port].gid_table.mutex));
			for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
				if (i >= base && i < base + num_gids)
					continue; /* don't compare to slave's current gids */
				gid_entry_tbl = &priv->port[port].gid_table.roce_gids[i];
				if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry)))
					continue;
				gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
				for (j = 0; j < num_gids; gid_entry_mbox++, j++) {
					if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw,
						    sizeof(zgid_entry)))
						continue;
					if (!memcmp(gid_entry_mbox->raw, gid_entry_tbl->raw,
						    sizeof(gid_entry_tbl->raw))) {
						/* found duplicate */
						mlx4_warn(dev, "requested gid entry for slave:%d is a duplicate of gid at index %d\n",
							  slave, i);
						qunlock(&(priv->port[port].gid_table.mutex));
						return -EINVAL;
					}
				}
			}

			/* insert slave GIDs with memcpy, starting at slave's base index */
			gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
			for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++)
				memcpy(priv->port[port].gid_table.roce_gids[offset].raw,
				       gid_entry_mbox->raw, MLX4_ROCE_GID_ENTRY_SIZE);

			/* Now, copy roce port gids table to current mailbox for passing to FW */
			gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
			for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++)
				memcpy(gid_entry_mbox->raw,
				       priv->port[port].gid_table.roce_gids[i].raw,
				       MLX4_ROCE_GID_ENTRY_SIZE);

			err = mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod,
				       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
				       MLX4_CMD_NATIVE);
			qunlock(&(priv->port[port].gid_table.mutex));
			return err;
		}

		return mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod,
				MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
				MLX4_CMD_NATIVE);
	}

	/* Slaves are not allowed to SET_PORT beacon (LED) blink */
	if (op_mod == MLX4_SET_PORT_BEACON_OPCODE) {
		mlx4_warn(dev, "denying SET_PORT Beacon slave:%d\n", slave);
		return -EPERM;
	}

	/* For IB, we only consider:
	 * - The capability mask, which is set to the aggregate of all
	 *   slave function capabilities
	 * - The QKey violatin counter - reset according to each request.
	 */

	if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
		reset_qkey_viols = (*(uint8_t *) inbox->buf) & 0x40;
		new_cap_mask = ((__be32 *) inbox->buf)[2];
	} else {
		reset_qkey_viols = ((uint8_t *) inbox->buf)[3] & 0x1;
		new_cap_mask = ((__be32 *) inbox->buf)[1];
	}

	/* slave may not set the IS_SM capability for the port */
	if (slave != mlx4_master_func_num(dev) &&
	    (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_IS_SM))
		return -EINVAL;

	/* No DEV_MGMT in multifunc mode */
	if (mlx4_is_mfunc(dev) &&
	    (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_DEV_MGMT_SUP))
		return -EINVAL;

	agg_cap_mask = 0;
	slave_cap_mask =
		priv->mfunc.master.slave_state[slave].ib_cap_mask[port];
	priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = new_cap_mask;
	for (i = 0; i < dev->num_slaves; i++)
		agg_cap_mask |=
			priv->mfunc.master.slave_state[i].ib_cap_mask[port];

	/* only clear mailbox for guests.  Master may be setting
	* MTU or PKEY table size
	*/
	if (slave != dev->caps.function)
		memset(inbox->buf, 0, 256);
	if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
		*(uint8_t *) inbox->buf	   |= !!reset_qkey_viols << 6;
		((__be32 *) inbox->buf)[2] = agg_cap_mask;
	} else {
		((uint8_t *) inbox->buf)[3]     |= !!reset_qkey_viols;
		((__be32 *) inbox->buf)[1] = agg_cap_mask;
	}

	err = mlx4_cmd(dev, inbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
		       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
	if (err)
		priv->mfunc.master.slave_state[slave].ib_cap_mask[port] =
			slave_cap_mask;
	return err;
}

int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
			  struct mlx4_vhcr *vhcr,
			  struct mlx4_cmd_mailbox *inbox,
			  struct mlx4_cmd_mailbox *outbox,
			  struct mlx4_cmd_info *cmd)
{
	int port = mlx4_slave_convert_port(
			dev, slave, vhcr->in_modifier & 0xFF);

	if (port < 0)
		return -EINVAL;

	vhcr->in_modifier = (vhcr->in_modifier & ~0xFF) |
			    (port & 0xFF);

	return mlx4_common_set_port(dev, slave, vhcr->in_modifier,
				    vhcr->op_modifier, inbox);
}

/* bit locations for set port command with zero op modifier */
enum {
	MLX4_SET_PORT_VL_CAP	 = 4, /* bits 7:4 */
	MLX4_SET_PORT_MTU_CAP	 = 12, /* bits 15:12 */
	MLX4_CHANGE_PORT_PKEY_TBL_SZ = 20,
	MLX4_CHANGE_PORT_VL_CAP	 = 21,
	MLX4_CHANGE_PORT_MTU_CAP = 22,
};

int mlx4_SET_PORT(struct mlx4_dev *dev, uint8_t port, int pkey_tbl_sz)
{
	struct mlx4_cmd_mailbox *mailbox;
	int err, vl_cap, pkey_tbl_flag = 0;

	if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
		return 0;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);

	((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];

	if (pkey_tbl_sz >= 0 && mlx4_is_master(dev)) {
		pkey_tbl_flag = 1;
		((__be16 *) mailbox->buf)[20] = cpu_to_be16(pkey_tbl_sz);
	}

	/* IB VL CAP enum isn't used by the firmware, just numerical values */
	for (vl_cap = 8; vl_cap >= 1; vl_cap >>= 1) {
		((__be32 *) mailbox->buf)[0] = cpu_to_be32(
			(1 << MLX4_CHANGE_PORT_MTU_CAP) |
			(1 << MLX4_CHANGE_PORT_VL_CAP)  |
			(pkey_tbl_flag << MLX4_CHANGE_PORT_PKEY_TBL_SZ) |
			(dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) |
			(vl_cap << MLX4_SET_PORT_VL_CAP));
		err = mlx4_cmd(dev, mailbox->dma, port,
			       MLX4_SET_PORT_IB_OPCODE, MLX4_CMD_SET_PORT,
			       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
		if (err != -ENOMEM)
			break;
	}

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}

int mlx4_SET_PORT_general(struct mlx4_dev *dev, uint8_t port, int mtu,
			  uint8_t pptx, uint8_t pfctx, uint8_t pprx,
			  uint8_t pfcrx)
{
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_set_port_general_context *context;
	int err;
	uint32_t in_mod;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);
	context = mailbox->buf;
	context->flags = SET_PORT_GEN_ALL_VALID;
	context->mtu = cpu_to_be16(mtu);
	context->pptx = (pptx * (!pfctx)) << 7;
	context->pfctx = pfctx;
	context->pprx = (pprx * (!pfcrx)) << 7;
	context->pfcrx = pfcrx;

	in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
	err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
		       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
		       MLX4_CMD_WRAPPED);

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}
EXPORT_SYMBOL(mlx4_SET_PORT_general);

int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, uint8_t port,
			   uint32_t base_qpn,
			   uint8_t promisc)
{
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_set_port_rqp_calc_context *context;
	int err;
	uint32_t in_mod;
	uint32_t m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ?
		MCAST_DIRECT : MCAST_DEFAULT;

	if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0)
		return 0;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);
	context = mailbox->buf;
	context->base_qpn = cpu_to_be32(base_qpn);
	context->n_mac = dev->caps.log_num_macs;
	context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
				       base_qpn);
	context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT |
				     base_qpn);
	context->intra_no_vlan = 0;
	context->no_vlan = MLX4_NO_VLAN_IDX;
	context->intra_vlan_miss = 0;
	context->vlan_miss = MLX4_VLAN_MISS_IDX;

	in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port;
	err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
		       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
		       MLX4_CMD_WRAPPED);

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}
EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);

int mlx4_SET_PORT_fcs_check(struct mlx4_dev *dev, uint8_t port,
			    uint8_t ignore_fcs_value)
{
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_set_port_general_context *context;
	uint32_t in_mod;
	int err;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);
	context = mailbox->buf;
	context->v_ignore_fcs |= MLX4_FLAG_V_IGNORE_FCS_MASK;
	if (ignore_fcs_value)
		context->ignore_fcs |= MLX4_IGNORE_FCS_MASK;
	else
		context->ignore_fcs &= ~MLX4_IGNORE_FCS_MASK;

	in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
	err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
		       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}
EXPORT_SYMBOL(mlx4_SET_PORT_fcs_check);

enum {
	VXLAN_ENABLE_MODIFY	= 1 << 7,
	VXLAN_STEERING_MODIFY	= 1 << 6,

	VXLAN_ENABLE		= 1 << 7,
};

struct mlx4_set_port_vxlan_context {
	uint32_t	reserved1;
	uint8_t	modify_flags;
	uint8_t	reserved2;
	uint8_t	enable_flags;
	uint8_t	steering;
};

int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, uint8_t port, uint8_t steering,
			int enable)
{
	int err;
	uint32_t in_mod;
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_set_port_vxlan_context  *context;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);
	context = mailbox->buf;
	memset(context, 0, sizeof(*context));

	context->modify_flags = VXLAN_ENABLE_MODIFY | VXLAN_STEERING_MODIFY;
	if (enable)
		context->enable_flags = VXLAN_ENABLE;
	context->steering  = steering;

	in_mod = MLX4_SET_PORT_VXLAN << 8 | port;
	err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
		       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
		       MLX4_CMD_NATIVE);

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}
EXPORT_SYMBOL(mlx4_SET_PORT_VXLAN);

int mlx4_SET_PORT_BEACON(struct mlx4_dev *dev, uint8_t port, uint16_t time)
{
	int err;
	struct mlx4_cmd_mailbox *mailbox;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);

	*((__be32 *)mailbox->buf) = cpu_to_be32(time);

	err = mlx4_cmd(dev, mailbox->dma, port, MLX4_SET_PORT_BEACON_OPCODE,
		       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
		       MLX4_CMD_NATIVE);

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}
EXPORT_SYMBOL(mlx4_SET_PORT_BEACON);

int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
				struct mlx4_vhcr *vhcr,
				struct mlx4_cmd_mailbox *inbox,
				struct mlx4_cmd_mailbox *outbox,
				struct mlx4_cmd_info *cmd)
{
	int err = 0;

	return err;
}

int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, uint8_t port,
			uint64_t mac, uint64_t clear, uint8_t mode)
{
	return mlx4_cmd(dev, (mac | (clear << 63)), port, mode,
			MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B,
			MLX4_CMD_WRAPPED);
}
EXPORT_SYMBOL(mlx4_SET_MCAST_FLTR);

int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave,
			       struct mlx4_vhcr *vhcr,
			       struct mlx4_cmd_mailbox *inbox,
			       struct mlx4_cmd_mailbox *outbox,
			       struct mlx4_cmd_info *cmd)
{
	int err = 0;

	return err;
}

int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave,
			       uint32_t in_mod,
			       struct mlx4_cmd_mailbox *outbox)
{
	return mlx4_cmd_box(dev, 0, outbox->dma, in_mod, 0,
			    MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
			    MLX4_CMD_NATIVE);
}

int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
				struct mlx4_vhcr *vhcr,
				struct mlx4_cmd_mailbox *inbox,
				struct mlx4_cmd_mailbox *outbox,
				struct mlx4_cmd_info *cmd)
{
	if (slave != dev->caps.function)
		return 0;
	return mlx4_common_dump_eth_stats(dev, slave,
					  vhcr->in_modifier, outbox);
}

int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, uint8_t *gid,
				 int *slave_id)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	int i, found_ix = -1;
	int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
	struct mlx4_slaves_pport slaves_pport;
	unsigned num_vfs;
	int slave_gid;

	if (!mlx4_is_mfunc(dev))
		return -EINVAL;

	slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
	num_vfs = bitmap_weight(slaves_pport.slaves,
				dev->persist->num_vfs + 1) - 1;

	for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
		if (!memcmp(priv->port[port].gid_table.roce_gids[i].raw, gid,
			    MLX4_ROCE_GID_ENTRY_SIZE)) {
			found_ix = i;
			break;
		}
	}

	if (found_ix >= 0) {
		/* Calculate a slave_gid which is the slave number in the gid
		 * table and not a globally unique slave number.
		 */
		if (found_ix < MLX4_ROCE_PF_GIDS)
			slave_gid = 0;
		else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) *
			 (vf_gids / num_vfs + 1))
			slave_gid = ((found_ix - MLX4_ROCE_PF_GIDS) /
				     (vf_gids / num_vfs + 1)) + 1;
		else
			slave_gid =
			((found_ix - MLX4_ROCE_PF_GIDS -
			  ((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) /
			 (vf_gids / num_vfs)) + vf_gids % num_vfs + 1;

		/* Calculate the globally unique slave id */
		if (slave_gid) {
			struct mlx4_active_ports exclusive_ports;
			struct mlx4_active_ports actv_ports;
			struct mlx4_slaves_pport slaves_pport_actv;
			unsigned max_port_p_one;
			int num_vfs_before = 0;
			int candidate_slave_gid;

			/* Calculate how many VFs are on the previous port, if exists */
			for (i = 1; i < port; i++) {
				bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
				set_bit(i - 1, exclusive_ports.ports);
				slaves_pport_actv =
					mlx4_phys_to_slaves_pport_actv(
							dev, &exclusive_ports);
				num_vfs_before += bitmap_weight(
						slaves_pport_actv.slaves,
						dev->persist->num_vfs + 1);
			}

			/* candidate_slave_gid isn't necessarily the correct slave, but
			 * it has the same number of ports and is assigned to the same
			 * ports as the real slave we're looking for. On dual port VF,
			 * slave_gid = [single port VFs on port <port>] +
			 * [offset of the current slave from the first dual port VF] +
			 * 1 (for the PF).
			 */
			candidate_slave_gid = slave_gid + num_vfs_before;

			actv_ports = mlx4_get_active_ports(dev, candidate_slave_gid);
			max_port_p_one = find_first_bit(
				actv_ports.ports, dev->caps.num_ports) +
				bitmap_weight(actv_ports.ports,
					      dev->caps.num_ports) + 1;

			/* Calculate the real slave number */
			for (i = 1; i < max_port_p_one; i++) {
				if (i == port)
					continue;
				bitmap_zero(exclusive_ports.ports,
					    dev->caps.num_ports);
				set_bit(i - 1, exclusive_ports.ports);
				slaves_pport_actv =
					mlx4_phys_to_slaves_pport_actv(
						dev, &exclusive_ports);
				slave_gid += bitmap_weight(
						slaves_pport_actv.slaves,
						dev->persist->num_vfs + 1);
			}
		}
		*slave_id = slave_gid;
	}

	return (found_ix >= 0) ? 0 : -EINVAL;
}
EXPORT_SYMBOL(mlx4_get_slave_from_roce_gid);

int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id,
				 uint8_t *gid)
{
	struct mlx4_priv *priv = mlx4_priv(dev);

	if (!mlx4_is_master(dev))
		return -EINVAL;

	memcpy(gid, priv->port[port].gid_table.roce_gids[slave_id].raw,
	       MLX4_ROCE_GID_ENTRY_SIZE);
	return 0;
}
EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave);

/* Cable Module Info */
#define MODULE_INFO_MAX_READ 48

#define I2C_ADDR_LOW  0x50
#define I2C_ADDR_HIGH 0x51
#define I2C_PAGE_SIZE 256

/* Module Info Data */
struct mlx4_cable_info {
	uint8_t	i2c_addr;
	uint8_t	page_num;
	__be16	dev_mem_address;
	__be16	reserved1;
	__be16	size;
	__be32	reserved2[2];
	uint8_t	data[MODULE_INFO_MAX_READ];
};

enum cable_info_err {
	 CABLE_INF_INV_PORT      = 0x1,
	 CABLE_INF_OP_NOSUP      = 0x2,
	 CABLE_INF_NOT_CONN      = 0x3,
	 CABLE_INF_NO_EEPRM      = 0x4,
	 CABLE_INF_PAGE_ERR      = 0x5,
	 CABLE_INF_INV_ADDR      = 0x6,
	 CABLE_INF_I2C_ADDR      = 0x7,
	 CABLE_INF_QSFP_VIO      = 0x8,
	 CABLE_INF_I2C_BUSY      = 0x9,
};

#define MAD_STATUS_2_CABLE_ERR(mad_status) ((mad_status >> 8) & 0xFF)

static inline const char *cable_info_mad_err_str(uint16_t mad_status)
{
	uint8_t err = MAD_STATUS_2_CABLE_ERR(mad_status);

	switch (err) {
	case CABLE_INF_INV_PORT:
		return "invalid port selected";
	case CABLE_INF_OP_NOSUP:
		return "operation not supported for this port (the port is of type CX4 or internal)";
	case CABLE_INF_NOT_CONN:
		return "cable is not connected";
	case CABLE_INF_NO_EEPRM:
		return "the connected cable has no EPROM (passive copper cable)";
	case CABLE_INF_PAGE_ERR:
		return "page number is greater than 15";
	case CABLE_INF_INV_ADDR:
		return "invalid device_address or size (that is, size equals 0 or address+size is greater than 256)";
	case CABLE_INF_I2C_ADDR:
		return "invalid I2C slave address";
	case CABLE_INF_QSFP_VIO:
		return "at least one cable violates the QSFP specification and ignores the modsel signal";
	case CABLE_INF_I2C_BUSY:
		return "I2C bus is constantly busy";
	}
	return "Unknown Error";
}

/**
 * mlx4_get_module_info - Read cable module eeprom data
 * @dev: mlx4_dev.
 * @port: port number.
 * @offset: byte offset in eeprom to start reading data from.
 * @size: num of bytes to read.
 * @data: output buffer to put the requested data into.
 *
 * Reads cable module eeprom data, puts the outcome data into
 * data pointer paramer.
 * Returns num of read bytes on success or a negative error
 * code.
 */
int mlx4_get_module_info(struct mlx4_dev *dev, uint8_t port,
			 uint16_t offset, uint16_t size, uint8_t *data)
{
	struct mlx4_cmd_mailbox *inbox, *outbox;
	struct mlx4_mad_ifc *inmad, *outmad;
	struct mlx4_cable_info *cable_info;
	uint16_t i2c_addr;
	int ret;

	if (size > MODULE_INFO_MAX_READ)
		size = MODULE_INFO_MAX_READ;

	inbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(inbox))
		return PTR_ERR(inbox);

	outbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(outbox)) {
		mlx4_free_cmd_mailbox(dev, inbox);
		return PTR_ERR(outbox);
	}

	inmad = (struct mlx4_mad_ifc *)(inbox->buf);
	outmad = (struct mlx4_mad_ifc *)(outbox->buf);

	inmad->method = 0x1; /* Get */
	inmad->class_version = 0x1;
	inmad->mgmt_class = 0x1;
	inmad->base_version = 0x1;
	inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */

	if (offset < I2C_PAGE_SIZE && offset + size > I2C_PAGE_SIZE)
		/* Cross pages reads are not allowed
		 * read until offset 256 in low page
		 */
		size -= offset + size - I2C_PAGE_SIZE;

	i2c_addr = I2C_ADDR_LOW;
	if (offset >= I2C_PAGE_SIZE) {
		/* Reset offset to high page */
		i2c_addr = I2C_ADDR_HIGH;
		offset -= I2C_PAGE_SIZE;
	}

	cable_info = (struct mlx4_cable_info *)inmad->data;
	cable_info->dev_mem_address = cpu_to_be16(offset);
	cable_info->page_num = 0;
	cable_info->i2c_addr = i2c_addr;
	cable_info->size = cpu_to_be16(size);

	ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3,
			   MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
			   MLX4_CMD_NATIVE);
	if (ret)
		goto out;

	if (be16_to_cpu(outmad->status)) {
		/* Mad returned with bad status */
		ret = be16_to_cpu(outmad->status);
		mlx4_warn(dev,
			  "MLX4_CMD_MAD_IFC Get Module info attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n",
			  0xFF60, port, i2c_addr, offset, size,
			  ret, cable_info_mad_err_str(ret));

		if (i2c_addr == I2C_ADDR_HIGH &&
		    MAD_STATUS_2_CABLE_ERR(ret) == CABLE_INF_I2C_ADDR)
			/* Some SFP cables do not support i2c slave
			 * address 0x51 (high page), abort silently.
			 */
			ret = 0;
		else
			ret = -ret;
		goto out;
	}
	cable_info = (struct mlx4_cable_info *)outmad->data;
	memcpy(data, cable_info->data, size);
	ret = size;
out:
	mlx4_free_cmd_mailbox(dev, inbox);
	mlx4_free_cmd_mailbox(dev, outbox);
	return ret;
}
EXPORT_SYMBOL(mlx4_get_module_info);
