/*
 * Copyright (c) 2006, 2007 Cisco Systems, Inc.  All rights reserved.
 * Copyright (c) 2007, 2008 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/string.h>
#include <linux/etherdevice.h>

#include <linux/mlx4/cmd.h>
#include <linux/mlx4/qp.h>
#include <linux/export.h>

#include "mlx4.h"

int mlx4_get_mgm_entry_size(struct mlx4_dev *dev)
{
	return 1 << dev->oper_log_mgm_entry_size;
}

int mlx4_get_qp_per_mgm(struct mlx4_dev *dev)
{
	return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2);
}

static int mlx4_QP_FLOW_STEERING_ATTACH(struct mlx4_dev *dev,
					struct mlx4_cmd_mailbox *mailbox,
					u32 size,
					u64 *reg_id)
{
	u64 imm;
	int err = 0;

	err = mlx4_cmd_imm(dev, mailbox->dma, &imm, size, 0,
			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
			   MLX4_CMD_NATIVE);
	if (err)
		return err;
	*reg_id = imm;

	return err;
}

static int mlx4_QP_FLOW_STEERING_DETACH(struct mlx4_dev *dev, u64 regid)
{
	int err = 0;

	err = mlx4_cmd(dev, regid, 0, 0,
		       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
		       MLX4_CMD_NATIVE);

	return err;
}

static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index,
			   struct mlx4_cmd_mailbox *mailbox)
{
	return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG,
			    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
}

static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index,
			    struct mlx4_cmd_mailbox *mailbox)
{
	return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG,
			MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
}

static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 port, u8 steer,
			      struct mlx4_cmd_mailbox *mailbox)
{
	u32 in_mod;

	in_mod = (u32) port << 16 | steer << 1;
	return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1,
			MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A,
			MLX4_CMD_NATIVE);
}

static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
			 u16 *hash, u8 op_mod)
{
	u64 imm;
	int err;

	err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod,
			   MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A,
			   MLX4_CMD_NATIVE);

	if (!err)
		*hash = imm;

	return err;
}

static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port,
					      enum mlx4_steer_type steer,
					      u32 qpn)
{
	struct mlx4_steer *s_steer;
	struct mlx4_promisc_qp *pqp;

	if (port < 1 || port > dev->caps.num_ports)
		return NULL;

	s_steer = &mlx4_priv(dev)->steer[port - 1];

	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
		if (pqp->qpn == qpn)
			return pqp;
	}
	/* not found */
	return NULL;
}

/*
 * Add new entry to steering data structure.
 * All promisc QPs should be added as well
 */
static int new_steering_entry(struct mlx4_dev *dev, u8 port,
			      enum mlx4_steer_type steer,
			      unsigned int index, u32 qpn)
{
	struct mlx4_steer *s_steer;
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_mgm *mgm;
	u32 members_count;
	struct mlx4_steer_index *new_entry;
	struct mlx4_promisc_qp *pqp;
	struct mlx4_promisc_qp *dqp = NULL;
	u32 prot;
	int err;

	if (port < 1 || port > dev->caps.num_ports)
		return -EINVAL;

	s_steer = &mlx4_priv(dev)->steer[port - 1];
	new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
	if (!new_entry)
		return -ENOMEM;

	INIT_LIST_HEAD(&new_entry->duplicates);
	new_entry->index = index;
	list_add_tail(&new_entry->list, &s_steer->steer_entries[steer]);

	/* If the given qpn is also a promisc qp,
	 * it should be inserted to duplicates list
	 */
	pqp = get_promisc_qp(dev, port, steer, qpn);
	if (pqp) {
		dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
		if (!dqp) {
			err = -ENOMEM;
			goto out_alloc;
		}
		dqp->qpn = qpn;
		list_add_tail(&dqp->list, &new_entry->duplicates);
	}

	/* if no promisc qps for this vep, we are done */
	if (list_empty(&s_steer->promisc_qps[steer]))
		return 0;

	/* now need to add all the promisc qps to the new
	 * steering entry, as they should also receive the packets
	 * destined to this address */
	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox)) {
		err = -ENOMEM;
		goto out_alloc;
	}
	mgm = mailbox->buf;

	err = mlx4_READ_ENTRY(dev, index, mailbox);
	if (err)
		goto out_mailbox;

	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
	prot = be32_to_cpu(mgm->members_count) >> 30;
	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
		/* don't add already existing qpn */
		if (pqp->qpn == qpn)
			continue;
		if (members_count == dev->caps.num_qp_per_mgm) {
			/* out of space */
			err = -ENOMEM;
			goto out_mailbox;
		}

		/* add the qpn */
		mgm->qp[members_count++] = cpu_to_be32(pqp->qpn & MGM_QPN_MASK);
	}
	/* update the qps count and update the entry with all the promisc qps*/
	mgm->members_count = cpu_to_be32(members_count | (prot << 30));
	err = mlx4_WRITE_ENTRY(dev, index, mailbox);

out_mailbox:
	mlx4_free_cmd_mailbox(dev, mailbox);
	if (!err)
		return 0;
out_alloc:
	if (dqp) {
		list_del(&dqp->list);
		kfree(dqp);
	}
	list_del(&new_entry->list);
	kfree(new_entry);
	return err;
}

/* update the data structures with existing steering entry */
static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
				   enum mlx4_steer_type steer,
				   unsigned int index, u32 qpn)
{
	struct mlx4_steer *s_steer;
	struct mlx4_steer_index *tmp_entry, *entry = NULL;
	struct mlx4_promisc_qp *pqp;
	struct mlx4_promisc_qp *dqp;

	if (port < 1 || port > dev->caps.num_ports)
		return -EINVAL;

	s_steer = &mlx4_priv(dev)->steer[port - 1];

	pqp = get_promisc_qp(dev, port, steer, qpn);
	if (!pqp)
		return 0; /* nothing to do */

	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
		if (tmp_entry->index == index) {
			entry = tmp_entry;
			break;
		}
	}
	if (unlikely(!entry)) {
		mlx4_warn(dev, "Steering entry at index %x is not registered\n", index);
		return -EINVAL;
	}

	/* the given qpn is listed as a promisc qpn
	 * we need to add it as a duplicate to this entry
	 * for future references */
	list_for_each_entry(dqp, &entry->duplicates, list) {
		if (qpn == dqp->qpn)
			return 0; /* qp is already duplicated */
	}

	/* add the qp as a duplicate on this index */
	dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
	if (!dqp)
		return -ENOMEM;
	dqp->qpn = qpn;
	list_add_tail(&dqp->list, &entry->duplicates);

	return 0;
}

/* Check whether a qpn is a duplicate on steering entry
 * If so, it should not be removed from mgm */
static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
				  enum mlx4_steer_type steer,
				  unsigned int index, u32 qpn)
{
	struct mlx4_steer *s_steer;
	struct mlx4_steer_index *tmp_entry, *entry = NULL;
	struct mlx4_promisc_qp *dqp, *tmp_dqp;

	if (port < 1 || port > dev->caps.num_ports)
		return NULL;

	s_steer = &mlx4_priv(dev)->steer[port - 1];

	/* if qp is not promisc, it cannot be duplicated */
	if (!get_promisc_qp(dev, port, steer, qpn))
		return false;

	/* The qp is promisc qp so it is a duplicate on this index
	 * Find the index entry, and remove the duplicate */
	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
		if (tmp_entry->index == index) {
			entry = tmp_entry;
			break;
		}
	}
	if (unlikely(!entry)) {
		mlx4_warn(dev, "Steering entry for index %x is not registered\n", index);
		return false;
	}
	list_for_each_entry_safe(dqp, tmp_dqp, &entry->duplicates, list) {
		if (dqp->qpn == qpn) {
			list_del(&dqp->list);
			kfree(dqp);
		}
	}
	return true;
}

/* Returns true if all the QPs != tqpn contained in this entry
 * are Promisc QPs. Returns false otherwise.
 */
static bool promisc_steering_entry(struct mlx4_dev *dev, u8 port,
				   enum mlx4_steer_type steer,
				   unsigned int index, u32 tqpn,
				   u32 *members_count)
{
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_mgm *mgm;
	u32 m_count;
	bool ret = false;
	int i;

	if (port < 1 || port > dev->caps.num_ports)
		return false;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return false;
	mgm = mailbox->buf;

	if (mlx4_READ_ENTRY(dev, index, mailbox))
		goto out;
	m_count = be32_to_cpu(mgm->members_count) & 0xffffff;
	if (members_count)
		*members_count = m_count;

	for (i = 0;  i < m_count; i++) {
		u32 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
		if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
			/* the qp is not promisc, the entry can't be removed */
			goto out;
		}
	}
	ret = true;
out:
	mlx4_free_cmd_mailbox(dev, mailbox);
	return ret;
}

/* IF a steering entry contains only promisc QPs, it can be removed. */
static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
				      enum mlx4_steer_type steer,
				      unsigned int index, u32 tqpn)
{
	struct mlx4_steer *s_steer;
	struct mlx4_steer_index *entry = NULL, *tmp_entry;
	u32 members_count;
	bool ret = false;

	if (port < 1 || port > dev->caps.num_ports)
		return NULL;

	s_steer = &mlx4_priv(dev)->steer[port - 1];

	if (!promisc_steering_entry(dev, port, steer, index,
				    tqpn, &members_count))
		goto out;

	/* All the qps currently registered for this entry are promiscuous,
	  * Checking for duplicates */
	ret = true;
	list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) {
		if (entry->index == index) {
			if (list_empty(&entry->duplicates) ||
			    members_count == 1) {
				struct mlx4_promisc_qp *pqp, *tmp_pqp;
				/* If there is only 1 entry in duplicates then
				 * this is the QP we want to delete, going over
				 * the list and deleting the entry.
				 */
				list_del(&entry->list);
				list_for_each_entry_safe(pqp, tmp_pqp,
							 &entry->duplicates,
							 list) {
					list_del(&pqp->list);
					kfree(pqp);
				}
				kfree(entry);
			} else {
				/* This entry contains duplicates so it shouldn't be removed */
				ret = false;
				goto out;
			}
		}
	}

out:
	return ret;
}

static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
			  enum mlx4_steer_type steer, u32 qpn)
{
	struct mlx4_steer *s_steer;
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_mgm *mgm;
	struct mlx4_steer_index *entry;
	struct mlx4_promisc_qp *pqp;
	struct mlx4_promisc_qp *dqp;
	u32 members_count;
	u32 prot;
	int i;
	bool found;
	int err;
	struct mlx4_priv *priv = mlx4_priv(dev);

	if (port < 1 || port > dev->caps.num_ports)
		return -EINVAL;

	s_steer = &mlx4_priv(dev)->steer[port - 1];

	mutex_lock(&priv->mcg_table.mutex);

	if (get_promisc_qp(dev, port, steer, qpn)) {
		err = 0;  /* Noting to do, already exists */
		goto out_mutex;
	}

	pqp = kmalloc(sizeof(*pqp), GFP_KERNEL);
	if (!pqp) {
		err = -ENOMEM;
		goto out_mutex;
	}
	pqp->qpn = qpn;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox)) {
		err = -ENOMEM;
		goto out_alloc;
	}
	mgm = mailbox->buf;

	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
		/* The promisc QP needs to be added for each one of the steering
		 * entries. If it already exists, needs to be added as
		 * a duplicate for this entry.
		 */
		list_for_each_entry(entry,
				    &s_steer->steer_entries[steer],
				    list) {
			err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
			if (err)
				goto out_mailbox;

			members_count = be32_to_cpu(mgm->members_count) &
					0xffffff;
			prot = be32_to_cpu(mgm->members_count) >> 30;
			found = false;
			for (i = 0; i < members_count; i++) {
				if ((be32_to_cpu(mgm->qp[i]) &
				     MGM_QPN_MASK) == qpn) {
					/* Entry already exists.
					 * Add to duplicates.
					 */
					dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
					if (!dqp) {
						err = -ENOMEM;
						goto out_mailbox;
					}
					dqp->qpn = qpn;
					list_add_tail(&dqp->list,
						      &entry->duplicates);
					found = true;
				}
			}
			if (!found) {
				/* Need to add the qpn to mgm */
				if (members_count ==
				    dev->caps.num_qp_per_mgm) {
					/* entry is full */
					err = -ENOMEM;
					goto out_mailbox;
				}
				mgm->qp[members_count++] =
					cpu_to_be32(qpn & MGM_QPN_MASK);
				mgm->members_count =
					cpu_to_be32(members_count |
						    (prot << 30));
				err = mlx4_WRITE_ENTRY(dev, entry->index,
						       mailbox);
				if (err)
					goto out_mailbox;
			}
		}
	}

	/* add the new qpn to list of promisc qps */
	list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
	/* now need to add all the promisc qps to default entry */
	memset(mgm, 0, sizeof(*mgm));
	members_count = 0;
	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) {
		if (members_count == dev->caps.num_qp_per_mgm) {
			/* entry is full */
			err = -ENOMEM;
			goto out_list;
		}
		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
	}
	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);

	err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
	if (err)
		goto out_list;

	mlx4_free_cmd_mailbox(dev, mailbox);
	mutex_unlock(&priv->mcg_table.mutex);
	return 0;

out_list:
	list_del(&pqp->list);
out_mailbox:
	mlx4_free_cmd_mailbox(dev, mailbox);
out_alloc:
	kfree(pqp);
out_mutex:
	mutex_unlock(&priv->mcg_table.mutex);
	return err;
}

static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
			     enum mlx4_steer_type steer, u32 qpn)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_steer *s_steer;
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_mgm *mgm;
	struct mlx4_steer_index *entry, *tmp_entry;
	struct mlx4_promisc_qp *pqp;
	struct mlx4_promisc_qp *dqp;
	u32 members_count;
	bool found;
	bool back_to_list = false;
	int i;
	int err;

	if (port < 1 || port > dev->caps.num_ports)
		return -EINVAL;

	s_steer = &mlx4_priv(dev)->steer[port - 1];
	mutex_lock(&priv->mcg_table.mutex);

	pqp = get_promisc_qp(dev, port, steer, qpn);
	if (unlikely(!pqp)) {
		mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);
		/* nothing to do */
		err = 0;
		goto out_mutex;
	}

	/*remove from list of promisc qps */
	list_del(&pqp->list);

	/* set the default entry not to include the removed one */
	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox)) {
		err = -ENOMEM;
		back_to_list = true;
		goto out_list;
	}
	mgm = mailbox->buf;
	members_count = 0;
	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);

	err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
	if (err)
		goto out_mailbox;

	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
		/* Remove the QP from all the steering entries */
		list_for_each_entry_safe(entry, tmp_entry,
					 &s_steer->steer_entries[steer],
					 list) {
			found = false;
			list_for_each_entry(dqp, &entry->duplicates, list) {
				if (dqp->qpn == qpn) {
					found = true;
					break;
				}
			}
			if (found) {
				/* A duplicate, no need to change the MGM,
				 * only update the duplicates list
				 */
				list_del(&dqp->list);
				kfree(dqp);
			} else {
				int loc = -1;

				err = mlx4_READ_ENTRY(dev,
						      entry->index,
						      mailbox);
				if (err)
					goto out_mailbox;
				members_count =
					be32_to_cpu(mgm->members_count) &
					0xffffff;
				if (!members_count) {
					mlx4_warn(dev, "QP %06x wasn't found in entry %x mcount=0. deleting entry...\n",
						  qpn, entry->index);
					list_del(&entry->list);
					kfree(entry);
					continue;
				}

				for (i = 0; i < members_count; ++i)
					if ((be32_to_cpu(mgm->qp[i]) &
					     MGM_QPN_MASK) == qpn) {
						loc = i;
						break;
					}

				if (loc < 0) {
					mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
						 qpn, entry->index);
					err = -EINVAL;
					goto out_mailbox;
				}

				/* Copy the last QP in this MGM
				 * over removed QP
				 */
				mgm->qp[loc] = mgm->qp[members_count - 1];
				mgm->qp[members_count - 1] = 0;
				mgm->members_count =
					cpu_to_be32(--members_count |
						    (MLX4_PROT_ETH << 30));

				err = mlx4_WRITE_ENTRY(dev,
						       entry->index,
						       mailbox);
				if (err)
					goto out_mailbox;
			}
		}
	}

out_mailbox:
	mlx4_free_cmd_mailbox(dev, mailbox);
out_list:
	if (back_to_list)
		list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
	else
		kfree(pqp);
out_mutex:
	mutex_unlock(&priv->mcg_table.mutex);
	return err;
}

/*
 * Caller must hold MCG table semaphore.  gid and mgm parameters must
 * be properly aligned for command interface.
 *
 *  Returns 0 unless a firmware command error occurs.
 *
 * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1
 * and *mgm holds MGM entry.
 *
 * if GID is found in AMGM, *index = index in AMGM, *prev = index of
 * previous entry in hash chain and *mgm holds AMGM entry.
 *
 * If no AMGM exists for given gid, *index = -1, *prev = index of last
 * entry in hash chain and *mgm holds end of hash chain.
 */
static int find_entry(struct mlx4_dev *dev, u8 port,
		      u8 *gid, enum mlx4_protocol prot,
		      struct mlx4_cmd_mailbox *mgm_mailbox,
		      int *prev, int *index)
{
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_mgm *mgm = mgm_mailbox->buf;
	u8 *mgid;
	int err;
	u16 hash;
	u8 op_mod = (prot == MLX4_PROT_ETH) ?
		!!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return -ENOMEM;
	mgid = mailbox->buf;

	memcpy(mgid, gid, 16);

	err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod);
	mlx4_free_cmd_mailbox(dev, mailbox);
	if (err)
		return err;

	if (0)
		mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, hash);

	*index = hash;
	*prev  = -1;

	do {
		err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox);
		if (err)
			return err;

		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
			if (*index != hash) {
				mlx4_err(dev, "Found zero MGID in AMGM\n");
				err = -EINVAL;
			}
			return err;
		}

		if (!memcmp(mgm->gid, gid, 16) &&
		    be32_to_cpu(mgm->members_count) >> 30 == prot)
			return err;

		*prev = *index;
		*index = be32_to_cpu(mgm->next_gid_index) >> 6;
	} while (*index);

	*index = -1;
	return err;
}

static const u8 __promisc_mode[] = {
	[MLX4_FS_REGULAR]   = 0x0,
	[MLX4_FS_ALL_DEFAULT] = 0x1,
	[MLX4_FS_MC_DEFAULT] = 0x3,
	[MLX4_FS_MIRROR_RX_PORT] = 0x4,
	[MLX4_FS_MIRROR_SX_PORT] = 0x5,
	[MLX4_FS_UC_SNIFFER] = 0x6,
	[MLX4_FS_MC_SNIFFER] = 0x7,
};

int mlx4_map_sw_to_hw_steering_mode(struct mlx4_dev *dev,
				    enum mlx4_net_trans_promisc_mode flow_type)
{
	if (flow_type >= MLX4_FS_MODE_NUM) {
		mlx4_err(dev, "Invalid flow type. type = %d\n", flow_type);
		return -EINVAL;
	}
	return __promisc_mode[flow_type];
}
EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_mode);

static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,
				  struct mlx4_net_trans_rule_hw_ctrl *hw)
{
	u8 flags = 0;

	flags = ctrl->queue_mode == MLX4_NET_TRANS_Q_LIFO ? 1 : 0;
	flags |= ctrl->exclusive ? (1 << 2) : 0;
	flags |= ctrl->allow_loopback ? (1 << 3) : 0;

	hw->flags = flags;
	hw->type = __promisc_mode[ctrl->promisc_mode];
	hw->prio = cpu_to_be16(ctrl->priority);
	hw->port = ctrl->port;
	hw->qpn = cpu_to_be32(ctrl->qpn);
}

const u16 __sw_id_hw[] = {
	[MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001,
	[MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005,
	[MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003,
	[MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002,
	[MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004,
	[MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006,
	[MLX4_NET_TRANS_RULE_ID_VXLAN]	 = 0xE008
};

int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev,
				  enum mlx4_net_trans_rule_id id)
{
	if (id >= MLX4_NET_TRANS_RULE_NUM) {
		mlx4_err(dev, "Invalid network rule id. id = %d\n", id);
		return -EINVAL;
	}
	return __sw_id_hw[id];
}
EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_id);

static const int __rule_hw_sz[] = {
	[MLX4_NET_TRANS_RULE_ID_ETH] =
		sizeof(struct mlx4_net_trans_rule_hw_eth),
	[MLX4_NET_TRANS_RULE_ID_IB] =
		sizeof(struct mlx4_net_trans_rule_hw_ib),
	[MLX4_NET_TRANS_RULE_ID_IPV6] = 0,
	[MLX4_NET_TRANS_RULE_ID_IPV4] =
		sizeof(struct mlx4_net_trans_rule_hw_ipv4),
	[MLX4_NET_TRANS_RULE_ID_TCP] =
		sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
	[MLX4_NET_TRANS_RULE_ID_UDP] =
		sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
	[MLX4_NET_TRANS_RULE_ID_VXLAN] =
		sizeof(struct mlx4_net_trans_rule_hw_vxlan)
};

int mlx4_hw_rule_sz(struct mlx4_dev *dev,
	       enum mlx4_net_trans_rule_id id)
{
	if (id >= MLX4_NET_TRANS_RULE_NUM) {
		mlx4_err(dev, "Invalid network rule id. id = %d\n", id);
		return -EINVAL;
	}

	return __rule_hw_sz[id];
}
EXPORT_SYMBOL_GPL(mlx4_hw_rule_sz);

static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,
			    struct _rule_hw *rule_hw)
{
	if (mlx4_hw_rule_sz(dev, spec->id) < 0)
		return -EINVAL;
	memset(rule_hw, 0, mlx4_hw_rule_sz(dev, spec->id));
	rule_hw->id = cpu_to_be16(__sw_id_hw[spec->id]);
	rule_hw->size = mlx4_hw_rule_sz(dev, spec->id) >> 2;

	switch (spec->id) {
	case MLX4_NET_TRANS_RULE_ID_ETH:
		memcpy(rule_hw->eth.dst_mac, spec->eth.dst_mac, ETH_ALEN);
		memcpy(rule_hw->eth.dst_mac_msk, spec->eth.dst_mac_msk,
		       ETH_ALEN);
		memcpy(rule_hw->eth.src_mac, spec->eth.src_mac, ETH_ALEN);
		memcpy(rule_hw->eth.src_mac_msk, spec->eth.src_mac_msk,
		       ETH_ALEN);
		if (spec->eth.ether_type_enable) {
			rule_hw->eth.ether_type_enable = 1;
			rule_hw->eth.ether_type = spec->eth.ether_type;
		}
		rule_hw->eth.vlan_tag = spec->eth.vlan_id;
		rule_hw->eth.vlan_tag_msk = spec->eth.vlan_id_msk;
		break;

	case MLX4_NET_TRANS_RULE_ID_IB:
		rule_hw->ib.l3_qpn = spec->ib.l3_qpn;
		rule_hw->ib.qpn_mask = spec->ib.qpn_msk;
		memcpy(&rule_hw->ib.dst_gid, &spec->ib.dst_gid, 16);
		memcpy(&rule_hw->ib.dst_gid_msk, &spec->ib.dst_gid_msk, 16);
		break;

	case MLX4_NET_TRANS_RULE_ID_IPV6:
		return -EOPNOTSUPP;

	case MLX4_NET_TRANS_RULE_ID_IPV4:
		rule_hw->ipv4.src_ip = spec->ipv4.src_ip;
		rule_hw->ipv4.src_ip_msk = spec->ipv4.src_ip_msk;
		rule_hw->ipv4.dst_ip = spec->ipv4.dst_ip;
		rule_hw->ipv4.dst_ip_msk = spec->ipv4.dst_ip_msk;
		break;

	case MLX4_NET_TRANS_RULE_ID_TCP:
	case MLX4_NET_TRANS_RULE_ID_UDP:
		rule_hw->tcp_udp.dst_port = spec->tcp_udp.dst_port;
		rule_hw->tcp_udp.dst_port_msk = spec->tcp_udp.dst_port_msk;
		rule_hw->tcp_udp.src_port = spec->tcp_udp.src_port;
		rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk;
		break;

	case MLX4_NET_TRANS_RULE_ID_VXLAN:
		rule_hw->vxlan.vni =
			cpu_to_be32(be32_to_cpu(spec->vxlan.vni) << 8);
		rule_hw->vxlan.vni_mask =
			cpu_to_be32(be32_to_cpu(spec->vxlan.vni_mask) << 8);
		break;

	default:
		return -EINVAL;
	}

	return __rule_hw_sz[spec->id];
}

static void mlx4_err_rule(struct mlx4_dev *dev, char *str,
			  struct mlx4_net_trans_rule *rule)
{
#define BUF_SIZE 256
	struct mlx4_spec_list *cur;
	char buf[BUF_SIZE];
	int len = 0;

	mlx4_err(dev, "%s", str);
	len += scnprintf(buf + len, BUF_SIZE - len,
			 "port = %d prio = 0x%x qp = 0x%x ",
			 rule->port, rule->priority, rule->qpn);

	list_for_each_entry(cur, &rule->list, list) {
		switch (cur->id) {
		case MLX4_NET_TRANS_RULE_ID_ETH:
			len += scnprintf(buf + len, BUF_SIZE - len,
					 "dmac = %pM ", &cur->eth.dst_mac);
			if (cur->eth.ether_type)
				len += scnprintf(buf + len, BUF_SIZE - len,
						 "ethertype = 0x%x ",
						 be16_to_cpu(cur->eth.ether_type));
			if (cur->eth.vlan_id)
				len += scnprintf(buf + len, BUF_SIZE - len,
						 "vlan-id = %d ",
						 be16_to_cpu(cur->eth.vlan_id));
			break;

		case MLX4_NET_TRANS_RULE_ID_IPV4:
			if (cur->ipv4.src_ip)
				len += scnprintf(buf + len, BUF_SIZE - len,
						 "src-ip = %pI4 ",
						 &cur->ipv4.src_ip);
			if (cur->ipv4.dst_ip)
				len += scnprintf(buf + len, BUF_SIZE - len,
						 "dst-ip = %pI4 ",
						 &cur->ipv4.dst_ip);
			break;

		case MLX4_NET_TRANS_RULE_ID_TCP:
		case MLX4_NET_TRANS_RULE_ID_UDP:
			if (cur->tcp_udp.src_port)
				len += scnprintf(buf + len, BUF_SIZE - len,
						 "src-port = %d ",
						 be16_to_cpu(cur->tcp_udp.src_port));
			if (cur->tcp_udp.dst_port)
				len += scnprintf(buf + len, BUF_SIZE - len,
						 "dst-port = %d ",
						 be16_to_cpu(cur->tcp_udp.dst_port));
			break;

		case MLX4_NET_TRANS_RULE_ID_IB:
			len += scnprintf(buf + len, BUF_SIZE - len,
					 "dst-gid = %pI6\n", cur->ib.dst_gid);
			len += scnprintf(buf + len, BUF_SIZE - len,
					 "dst-gid-mask = %pI6\n",
					 cur->ib.dst_gid_msk);
			break;

		case MLX4_NET_TRANS_RULE_ID_VXLAN:
			len += scnprintf(buf + len, BUF_SIZE - len,
					 "VNID = %d ", be32_to_cpu(cur->vxlan.vni));
			break;
		case MLX4_NET_TRANS_RULE_ID_IPV6:
			break;

		default:
			break;
		}
	}
	len += scnprintf(buf + len, BUF_SIZE - len, "\n");
	mlx4_err(dev, "%s", buf);

	if (len >= BUF_SIZE)
		mlx4_err(dev, "Network rule error message was truncated, print buffer is too small\n");
}

int mlx4_flow_attach(struct mlx4_dev *dev,
		     struct mlx4_net_trans_rule *rule, u64 *reg_id)
{
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_spec_list *cur;
	u32 size = 0;
	int ret;

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

	if (!mlx4_qp_lookup(dev, rule->qpn)) {
		mlx4_err_rule(dev, "QP doesn't exist\n", rule);
		ret = -EINVAL;
		goto out;
	}

	trans_rule_ctrl_to_hw(rule, mailbox->buf);

	size += sizeof(struct mlx4_net_trans_rule_hw_ctrl);

	list_for_each_entry(cur, &rule->list, list) {
		ret = parse_trans_rule(dev, cur, mailbox->buf + size);
		if (ret < 0)
			goto out;

		size += ret;
	}

	ret = mlx4_QP_FLOW_STEERING_ATTACH(dev, mailbox, size >> 2, reg_id);
	if (ret == -ENOMEM) {
		mlx4_err_rule(dev,
			      "mcg table is full. Fail to register network rule\n",
			      rule);
	} else if (ret) {
		if (ret == -ENXIO) {
			if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED)
				mlx4_err_rule(dev,
					      "DMFS is not enabled, "
					      "failed to register network rule.\n",
					      rule);
			else
				mlx4_err_rule(dev,
					      "Rule exceeds the dmfs_high_rate_mode limitations, "
					      "failed to register network rule.\n",
					      rule);

		} else {
			mlx4_err_rule(dev, "Fail to register network rule.\n", rule);
		}
	}

out:
	mlx4_free_cmd_mailbox(dev, mailbox);

	return ret;
}
EXPORT_SYMBOL_GPL(mlx4_flow_attach);

int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id)
{
	int err;

	err = mlx4_QP_FLOW_STEERING_DETACH(dev, reg_id);
	if (err)
		mlx4_err(dev, "Fail to detach network rule. registration id = 0x%llx\n",
			 reg_id);
	return err;
}
EXPORT_SYMBOL_GPL(mlx4_flow_detach);

int mlx4_tunnel_steer_add(struct mlx4_dev *dev, unsigned char *addr,
			  int port, int qpn, u16 prio, u64 *reg_id)
{
	int err;
	struct mlx4_spec_list spec_eth_outer = { {NULL} };
	struct mlx4_spec_list spec_vxlan     = { {NULL} };
	struct mlx4_spec_list spec_eth_inner = { {NULL} };

	struct mlx4_net_trans_rule rule = {
		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
		.exclusive = 0,
		.allow_loopback = 1,
		.promisc_mode = MLX4_FS_REGULAR,
	};

	__be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);

	rule.port = port;
	rule.qpn = qpn;
	rule.priority = prio;
	INIT_LIST_HEAD(&rule.list);

	spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH;
	memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN);
	memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN);

	spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN;    /* any vxlan header */
	spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH;	 /* any inner eth header */

	list_add_tail(&spec_eth_outer.list, &rule.list);
	list_add_tail(&spec_vxlan.list,     &rule.list);
	list_add_tail(&spec_eth_inner.list, &rule.list);

	err = mlx4_flow_attach(dev, &rule, reg_id);
	return err;
}
EXPORT_SYMBOL(mlx4_tunnel_steer_add);

int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
				      u32 max_range_qpn)
{
	int err;
	u64 in_param;

	in_param = ((u64) min_range_qpn) << 32;
	in_param |= ((u64) max_range_qpn) & 0xFFFFFFFF;

	err = mlx4_cmd(dev, in_param, 0, 0,
			MLX4_FLOW_STEERING_IB_UC_QP_RANGE,
			MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);

	return err;
}
EXPORT_SYMBOL_GPL(mlx4_FLOW_STEERING_IB_UC_QP_RANGE);

int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
			  int block_mcast_loopback, enum mlx4_protocol prot,
			  enum mlx4_steer_type steer)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_mgm *mgm;
	u32 members_count;
	int index = -1, prev;
	int link = 0;
	int i;
	int err;
	u8 port = gid[5];
	u8 new_entry = 0;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);
	mgm = mailbox->buf;

	mutex_lock(&priv->mcg_table.mutex);
	err = find_entry(dev, port, gid, prot,
			 mailbox, &prev, &index);
	if (err)
		goto out;

	if (index != -1) {
		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
			new_entry = 1;
			memcpy(mgm->gid, gid, 16);
		}
	} else {
		link = 1;

		index = mlx4_bitmap_alloc(&priv->mcg_table.bitmap);
		if (index == -1) {
			mlx4_err(dev, "No AMGM entries left\n");
			err = -ENOMEM;
			goto out;
		}
		index += dev->caps.num_mgms;

		new_entry = 1;
		memset(mgm, 0, sizeof(*mgm));
		memcpy(mgm->gid, gid, 16);
	}

	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
	if (members_count == dev->caps.num_qp_per_mgm) {
		mlx4_err(dev, "MGM at index %x is full\n", index);
		err = -ENOMEM;
		goto out;
	}

	for (i = 0; i < members_count; ++i)
		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
			mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn);
			err = 0;
			goto out;
		}

	if (block_mcast_loopback)
		mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) |
						       (1U << MGM_BLCK_LB_BIT));
	else
		mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);

	mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30);

	err = mlx4_WRITE_ENTRY(dev, index, mailbox);
	if (err)
		goto out;

	if (!link)
		goto out;

	err = mlx4_READ_ENTRY(dev, prev, mailbox);
	if (err)
		goto out;

	mgm->next_gid_index = cpu_to_be32(index << 6);

	err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
	if (err)
		goto out;

out:
	if (prot == MLX4_PROT_ETH && index != -1) {
		/* manage the steering entry for promisc mode */
		if (new_entry)
			err = new_steering_entry(dev, port, steer,
						 index, qp->qpn);
		else
			err = existing_steering_entry(dev, port, steer,
						      index, qp->qpn);
	}
	if (err && link && index != -1) {
		if (index < dev->caps.num_mgms)
			mlx4_warn(dev, "Got AMGM index %d < %d\n",
				  index, dev->caps.num_mgms);
		else
			mlx4_bitmap_free(&priv->mcg_table.bitmap,
					 index - dev->caps.num_mgms, MLX4_USE_RR);
	}
	mutex_unlock(&priv->mcg_table.mutex);

	mlx4_free_cmd_mailbox(dev, mailbox);
	return err;
}

int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
			  enum mlx4_protocol prot, enum mlx4_steer_type steer)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_mgm *mgm;
	u32 members_count;
	int prev, index;
	int i, loc = -1;
	int err;
	u8 port = gid[5];
	bool removed_entry = false;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);
	mgm = mailbox->buf;

	mutex_lock(&priv->mcg_table.mutex);

	err = find_entry(dev, port, gid, prot,
			 mailbox, &prev, &index);
	if (err)
		goto out;

	if (index == -1) {
		mlx4_err(dev, "MGID %pI6 not found\n", gid);
		err = -EINVAL;
		goto out;
	}

	/* If this QP is also a promisc QP, it shouldn't be removed only if
	 * at least one none promisc QP is also attached to this MCG
	 */
	if (prot == MLX4_PROT_ETH &&
	    check_duplicate_entry(dev, port, steer, index, qp->qpn) &&
	    !promisc_steering_entry(dev, port, steer, index, qp->qpn, NULL))
			goto out;

	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
	for (i = 0; i < members_count; ++i)
		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
			loc = i;
			break;
		}

	if (loc == -1) {
		mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
		err = -EINVAL;
		goto out;
	}

	/* copy the last QP in this MGM over removed QP */
	mgm->qp[loc] = mgm->qp[members_count - 1];
	mgm->qp[members_count - 1] = 0;
	mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);

	if (prot == MLX4_PROT_ETH)
		removed_entry = can_remove_steering_entry(dev, port, steer,
								index, qp->qpn);
	if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) {
		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
		goto out;
	}

	/* We are going to delete the entry, members count should be 0 */
	mgm->members_count = cpu_to_be32((u32) prot << 30);

	if (prev == -1) {
		/* Remove entry from MGM */
		int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6;
		if (amgm_index) {
			err = mlx4_READ_ENTRY(dev, amgm_index, mailbox);
			if (err)
				goto out;
		} else
			memset(mgm->gid, 0, 16);

		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
		if (err)
			goto out;

		if (amgm_index) {
			if (amgm_index < dev->caps.num_mgms)
				mlx4_warn(dev, "MGM entry %d had AMGM index %d < %d\n",
					  index, amgm_index, dev->caps.num_mgms);
			else
				mlx4_bitmap_free(&priv->mcg_table.bitmap,
						 amgm_index - dev->caps.num_mgms, MLX4_USE_RR);
		}
	} else {
		/* Remove entry from AMGM */
		int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6;
		err = mlx4_READ_ENTRY(dev, prev, mailbox);
		if (err)
			goto out;

		mgm->next_gid_index = cpu_to_be32(cur_next_index << 6);

		err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
		if (err)
			goto out;

		if (index < dev->caps.num_mgms)
			mlx4_warn(dev, "entry %d had next AMGM index %d < %d\n",
				  prev, index, dev->caps.num_mgms);
		else
			mlx4_bitmap_free(&priv->mcg_table.bitmap,
					 index - dev->caps.num_mgms, MLX4_USE_RR);
	}

out:
	mutex_unlock(&priv->mcg_table.mutex);

	mlx4_free_cmd_mailbox(dev, mailbox);
	if (err && dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR)
		/* In case device is under an error, return success as a closing command */
		err = 0;
	return err;
}

static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp,
			  u8 gid[16], u8 attach, u8 block_loopback,
			  enum mlx4_protocol prot)
{
	struct mlx4_cmd_mailbox *mailbox;
	int err = 0;
	int qpn;

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

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

	memcpy(mailbox->buf, gid, 16);
	qpn = qp->qpn;
	qpn |= (prot << 28);
	if (attach && block_loopback)
		qpn |= (1 << 31);

	err = mlx4_cmd(dev, mailbox->dma, qpn, attach,
		       MLX4_CMD_QP_ATTACH, MLX4_CMD_TIME_CLASS_A,
		       MLX4_CMD_WRAPPED);

	mlx4_free_cmd_mailbox(dev, mailbox);
	if (err && !attach &&
	    dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR)
		err = 0;
	return err;
}

int mlx4_trans_to_dmfs_attach(struct mlx4_dev *dev, struct mlx4_qp *qp,
			      u8 gid[16], u8 port,
			      int block_mcast_loopback,
			      enum mlx4_protocol prot, u64 *reg_id)
{
		struct mlx4_spec_list spec = { {NULL} };
		__be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);

		struct mlx4_net_trans_rule rule = {
			.queue_mode = MLX4_NET_TRANS_Q_FIFO,
			.exclusive = 0,
			.promisc_mode = MLX4_FS_REGULAR,
			.priority = MLX4_DOMAIN_NIC,
		};

		rule.allow_loopback = !block_mcast_loopback;
		rule.port = port;
		rule.qpn = qp->qpn;
		INIT_LIST_HEAD(&rule.list);

		switch (prot) {
		case MLX4_PROT_ETH:
			spec.id = MLX4_NET_TRANS_RULE_ID_ETH;
			memcpy(spec.eth.dst_mac, &gid[10], ETH_ALEN);
			memcpy(spec.eth.dst_mac_msk, &mac_mask, ETH_ALEN);
			break;

		case MLX4_PROT_IB_IPV6:
			spec.id = MLX4_NET_TRANS_RULE_ID_IB;
			memcpy(spec.ib.dst_gid, gid, 16);
			memset(&spec.ib.dst_gid_msk, 0xff, 16);
			break;
		default:
			return -EINVAL;
		}
		list_add_tail(&spec.list, &rule.list);

		return mlx4_flow_attach(dev, &rule, reg_id);
}

int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
			  u8 port, int block_mcast_loopback,
			  enum mlx4_protocol prot, u64 *reg_id)
{
	switch (dev->caps.steering_mode) {
	case MLX4_STEERING_MODE_A0:
		if (prot == MLX4_PROT_ETH)
			return 0;
		/* fall through */

	case MLX4_STEERING_MODE_B0:
		if (prot == MLX4_PROT_ETH)
			gid[7] |= (MLX4_MC_STEER << 1);

		if (mlx4_is_mfunc(dev))
			return mlx4_QP_ATTACH(dev, qp, gid, 1,
					      block_mcast_loopback, prot);
		return mlx4_qp_attach_common(dev, qp, gid,
					     block_mcast_loopback, prot,
					     MLX4_MC_STEER);

	case MLX4_STEERING_MODE_DEVICE_MANAGED:
		return mlx4_trans_to_dmfs_attach(dev, qp, gid, port,
						 block_mcast_loopback,
						 prot, reg_id);
	default:
		return -EINVAL;
	}
}
EXPORT_SYMBOL_GPL(mlx4_multicast_attach);

int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
			  enum mlx4_protocol prot, u64 reg_id)
{
	switch (dev->caps.steering_mode) {
	case MLX4_STEERING_MODE_A0:
		if (prot == MLX4_PROT_ETH)
			return 0;
		/* fall through */

	case MLX4_STEERING_MODE_B0:
		if (prot == MLX4_PROT_ETH)
			gid[7] |= (MLX4_MC_STEER << 1);

		if (mlx4_is_mfunc(dev))
			return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);

		return mlx4_qp_detach_common(dev, qp, gid, prot,
					     MLX4_MC_STEER);

	case MLX4_STEERING_MODE_DEVICE_MANAGED:
		return mlx4_flow_detach(dev, reg_id);

	default:
		return -EINVAL;
	}
}
EXPORT_SYMBOL_GPL(mlx4_multicast_detach);

int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
				u32 qpn, enum mlx4_net_trans_promisc_mode mode)
{
	struct mlx4_net_trans_rule rule = {
		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
		.exclusive = 0,
		.allow_loopback = 1,
	};

	u64 *regid_p;

	switch (mode) {
	case MLX4_FS_ALL_DEFAULT:
		regid_p = &dev->regid_promisc_array[port];
		break;
	case MLX4_FS_MC_DEFAULT:
		regid_p = &dev->regid_allmulti_array[port];
		break;
	default:
		return -1;
	}

	if (*regid_p != 0)
		return -1;

	rule.promisc_mode = mode;
	rule.port = port;
	rule.qpn = qpn;
	INIT_LIST_HEAD(&rule.list);
	mlx4_info(dev, "going promisc on %x\n", port);

	return  mlx4_flow_attach(dev, &rule, regid_p);
}
EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_add);

int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
				   enum mlx4_net_trans_promisc_mode mode)
{
	int ret;
	u64 *regid_p;

	switch (mode) {
	case MLX4_FS_ALL_DEFAULT:
		regid_p = &dev->regid_promisc_array[port];
		break;
	case MLX4_FS_MC_DEFAULT:
		regid_p = &dev->regid_allmulti_array[port];
		break;
	default:
		return -1;
	}

	if (*regid_p == 0)
		return -1;

	ret =  mlx4_flow_detach(dev, *regid_p);
	if (ret == 0)
		*regid_p = 0;

	return ret;
}
EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_remove);

int mlx4_unicast_attach(struct mlx4_dev *dev,
			struct mlx4_qp *qp, u8 gid[16],
			int block_mcast_loopback, enum mlx4_protocol prot)
{
	if (prot == MLX4_PROT_ETH)
		gid[7] |= (MLX4_UC_STEER << 1);

	if (mlx4_is_mfunc(dev))
		return mlx4_QP_ATTACH(dev, qp, gid, 1,
					block_mcast_loopback, prot);

	return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback,
					prot, MLX4_UC_STEER);
}
EXPORT_SYMBOL_GPL(mlx4_unicast_attach);

int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
			       u8 gid[16], enum mlx4_protocol prot)
{
	if (prot == MLX4_PROT_ETH)
		gid[7] |= (MLX4_UC_STEER << 1);

	if (mlx4_is_mfunc(dev))
		return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);

	return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_UC_STEER);
}
EXPORT_SYMBOL_GPL(mlx4_unicast_detach);

int mlx4_PROMISC_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)
{
	u32 qpn = (u32) vhcr->in_param & 0xffffffff;
	int port = mlx4_slave_convert_port(dev, slave, vhcr->in_param >> 62);
	enum mlx4_steer_type steer = vhcr->in_modifier;

	if (port < 0)
		return -EINVAL;

	/* Promiscuous unicast is not allowed in mfunc */
	if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)
		return 0;

	if (vhcr->op_modifier)
		return add_promisc_qp(dev, port, steer, qpn);
	else
		return remove_promisc_qp(dev, port, steer, qpn);
}

static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn,
			enum mlx4_steer_type steer, u8 add, u8 port)
{
	return mlx4_cmd(dev, (u64) qpn | (u64) port << 62, (u32) steer, add,
			MLX4_CMD_PROMISC, MLX4_CMD_TIME_CLASS_A,
			MLX4_CMD_WRAPPED);
}

int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
{
	if (mlx4_is_mfunc(dev))
		return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port);

	return add_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
}
EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add);

int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
{
	if (mlx4_is_mfunc(dev))
		return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port);

	return remove_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
}
EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove);

int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
{
	if (mlx4_is_mfunc(dev))
		return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port);

	return add_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
}
EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add);

int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
{
	if (mlx4_is_mfunc(dev))
		return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port);

	return remove_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
}
EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove);

int mlx4_init_mcg_table(struct mlx4_dev *dev)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	int err;

	/* No need for mcg_table when fw managed the mcg table*/
	if (dev->caps.steering_mode ==
	    MLX4_STEERING_MODE_DEVICE_MANAGED)
		return 0;
	err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms,
			       dev->caps.num_amgms - 1, 0, 0);
	if (err)
		return err;

	mutex_init(&priv->mcg_table.mutex);

	return 0;
}

void mlx4_cleanup_mcg_table(struct mlx4_dev *dev)
{
	if (dev->caps.steering_mode !=
	    MLX4_STEERING_MODE_DEVICE_MANAGED)
		mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap);
}
