cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mcg.c (42828B)


      1/*
      2 * Copyright (c) 2006, 2007 Cisco Systems, Inc.  All rights reserved.
      3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
      4 *
      5 * This software is available to you under a choice of one of two
      6 * licenses.  You may choose to be licensed under the terms of the GNU
      7 * General Public License (GPL) Version 2, available from the file
      8 * COPYING in the main directory of this source tree, or the
      9 * OpenIB.org BSD license below:
     10 *
     11 *     Redistribution and use in source and binary forms, with or
     12 *     without modification, are permitted provided that the following
     13 *     conditions are met:
     14 *
     15 *      - Redistributions of source code must retain the above
     16 *        copyright notice, this list of conditions and the following
     17 *        disclaimer.
     18 *
     19 *      - Redistributions in binary form must reproduce the above
     20 *        copyright notice, this list of conditions and the following
     21 *        disclaimer in the documentation and/or other materials
     22 *        provided with the distribution.
     23 *
     24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     31 * SOFTWARE.
     32 */
     33
     34#include <linux/string.h>
     35#include <linux/etherdevice.h>
     36
     37#include <linux/mlx4/cmd.h>
     38#include <linux/mlx4/qp.h>
     39#include <linux/export.h>
     40
     41#include "mlx4.h"
     42
     43int mlx4_get_mgm_entry_size(struct mlx4_dev *dev)
     44{
     45	return 1 << dev->oper_log_mgm_entry_size;
     46}
     47
     48int mlx4_get_qp_per_mgm(struct mlx4_dev *dev)
     49{
     50	return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2);
     51}
     52
     53static int mlx4_QP_FLOW_STEERING_ATTACH(struct mlx4_dev *dev,
     54					struct mlx4_cmd_mailbox *mailbox,
     55					u32 size,
     56					u64 *reg_id)
     57{
     58	u64 imm;
     59	int err = 0;
     60
     61	err = mlx4_cmd_imm(dev, mailbox->dma, &imm, size, 0,
     62			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
     63			   MLX4_CMD_NATIVE);
     64	if (err)
     65		return err;
     66	*reg_id = imm;
     67
     68	return err;
     69}
     70
     71static int mlx4_QP_FLOW_STEERING_DETACH(struct mlx4_dev *dev, u64 regid)
     72{
     73	int err = 0;
     74
     75	err = mlx4_cmd(dev, regid, 0, 0,
     76		       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
     77		       MLX4_CMD_NATIVE);
     78
     79	return err;
     80}
     81
     82static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index,
     83			   struct mlx4_cmd_mailbox *mailbox)
     84{
     85	return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG,
     86			    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
     87}
     88
     89static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index,
     90			    struct mlx4_cmd_mailbox *mailbox)
     91{
     92	return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG,
     93			MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
     94}
     95
     96static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 port, u8 steer,
     97			      struct mlx4_cmd_mailbox *mailbox)
     98{
     99	u32 in_mod;
    100
    101	in_mod = (u32) port << 16 | steer << 1;
    102	return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1,
    103			MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A,
    104			MLX4_CMD_NATIVE);
    105}
    106
    107static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
    108			 u16 *hash, u8 op_mod)
    109{
    110	u64 imm;
    111	int err;
    112
    113	err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod,
    114			   MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A,
    115			   MLX4_CMD_NATIVE);
    116
    117	if (!err)
    118		*hash = imm;
    119
    120	return err;
    121}
    122
    123static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port,
    124					      enum mlx4_steer_type steer,
    125					      u32 qpn)
    126{
    127	struct mlx4_steer *s_steer;
    128	struct mlx4_promisc_qp *pqp;
    129
    130	if (port < 1 || port > dev->caps.num_ports)
    131		return NULL;
    132
    133	s_steer = &mlx4_priv(dev)->steer[port - 1];
    134
    135	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
    136		if (pqp->qpn == qpn)
    137			return pqp;
    138	}
    139	/* not found */
    140	return NULL;
    141}
    142
    143/*
    144 * Add new entry to steering data structure.
    145 * All promisc QPs should be added as well
    146 */
    147static int new_steering_entry(struct mlx4_dev *dev, u8 port,
    148			      enum mlx4_steer_type steer,
    149			      unsigned int index, u32 qpn)
    150{
    151	struct mlx4_steer *s_steer;
    152	struct mlx4_cmd_mailbox *mailbox;
    153	struct mlx4_mgm *mgm;
    154	u32 members_count;
    155	struct mlx4_steer_index *new_entry;
    156	struct mlx4_promisc_qp *pqp;
    157	struct mlx4_promisc_qp *dqp = NULL;
    158	u32 prot;
    159	int err;
    160
    161	if (port < 1 || port > dev->caps.num_ports)
    162		return -EINVAL;
    163
    164	s_steer = &mlx4_priv(dev)->steer[port - 1];
    165	new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
    166	if (!new_entry)
    167		return -ENOMEM;
    168
    169	INIT_LIST_HEAD(&new_entry->duplicates);
    170	new_entry->index = index;
    171	list_add_tail(&new_entry->list, &s_steer->steer_entries[steer]);
    172
    173	/* If the given qpn is also a promisc qp,
    174	 * it should be inserted to duplicates list
    175	 */
    176	pqp = get_promisc_qp(dev, port, steer, qpn);
    177	if (pqp) {
    178		dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
    179		if (!dqp) {
    180			err = -ENOMEM;
    181			goto out_alloc;
    182		}
    183		dqp->qpn = qpn;
    184		list_add_tail(&dqp->list, &new_entry->duplicates);
    185	}
    186
    187	/* if no promisc qps for this vep, we are done */
    188	if (list_empty(&s_steer->promisc_qps[steer]))
    189		return 0;
    190
    191	/* now need to add all the promisc qps to the new
    192	 * steering entry, as they should also receive the packets
    193	 * destined to this address */
    194	mailbox = mlx4_alloc_cmd_mailbox(dev);
    195	if (IS_ERR(mailbox)) {
    196		err = -ENOMEM;
    197		goto out_alloc;
    198	}
    199	mgm = mailbox->buf;
    200
    201	err = mlx4_READ_ENTRY(dev, index, mailbox);
    202	if (err)
    203		goto out_mailbox;
    204
    205	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
    206	prot = be32_to_cpu(mgm->members_count) >> 30;
    207	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
    208		/* don't add already existing qpn */
    209		if (pqp->qpn == qpn)
    210			continue;
    211		if (members_count == dev->caps.num_qp_per_mgm) {
    212			/* out of space */
    213			err = -ENOMEM;
    214			goto out_mailbox;
    215		}
    216
    217		/* add the qpn */
    218		mgm->qp[members_count++] = cpu_to_be32(pqp->qpn & MGM_QPN_MASK);
    219	}
    220	/* update the qps count and update the entry with all the promisc qps*/
    221	mgm->members_count = cpu_to_be32(members_count | (prot << 30));
    222	err = mlx4_WRITE_ENTRY(dev, index, mailbox);
    223
    224out_mailbox:
    225	mlx4_free_cmd_mailbox(dev, mailbox);
    226	if (!err)
    227		return 0;
    228out_alloc:
    229	if (dqp) {
    230		list_del(&dqp->list);
    231		kfree(dqp);
    232	}
    233	list_del(&new_entry->list);
    234	kfree(new_entry);
    235	return err;
    236}
    237
    238/* update the data structures with existing steering entry */
    239static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
    240				   enum mlx4_steer_type steer,
    241				   unsigned int index, u32 qpn)
    242{
    243	struct mlx4_steer *s_steer;
    244	struct mlx4_steer_index *tmp_entry, *entry = NULL;
    245	struct mlx4_promisc_qp *pqp;
    246	struct mlx4_promisc_qp *dqp;
    247
    248	if (port < 1 || port > dev->caps.num_ports)
    249		return -EINVAL;
    250
    251	s_steer = &mlx4_priv(dev)->steer[port - 1];
    252
    253	pqp = get_promisc_qp(dev, port, steer, qpn);
    254	if (!pqp)
    255		return 0; /* nothing to do */
    256
    257	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
    258		if (tmp_entry->index == index) {
    259			entry = tmp_entry;
    260			break;
    261		}
    262	}
    263	if (unlikely(!entry)) {
    264		mlx4_warn(dev, "Steering entry at index %x is not registered\n", index);
    265		return -EINVAL;
    266	}
    267
    268	/* the given qpn is listed as a promisc qpn
    269	 * we need to add it as a duplicate to this entry
    270	 * for future references */
    271	list_for_each_entry(dqp, &entry->duplicates, list) {
    272		if (qpn == dqp->qpn)
    273			return 0; /* qp is already duplicated */
    274	}
    275
    276	/* add the qp as a duplicate on this index */
    277	dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
    278	if (!dqp)
    279		return -ENOMEM;
    280	dqp->qpn = qpn;
    281	list_add_tail(&dqp->list, &entry->duplicates);
    282
    283	return 0;
    284}
    285
    286/* Check whether a qpn is a duplicate on steering entry
    287 * If so, it should not be removed from mgm */
    288static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
    289				  enum mlx4_steer_type steer,
    290				  unsigned int index, u32 qpn)
    291{
    292	struct mlx4_steer *s_steer;
    293	struct mlx4_steer_index *tmp_entry, *entry = NULL;
    294	struct mlx4_promisc_qp *dqp, *tmp_dqp;
    295
    296	if (port < 1 || port > dev->caps.num_ports)
    297		return NULL;
    298
    299	s_steer = &mlx4_priv(dev)->steer[port - 1];
    300
    301	/* if qp is not promisc, it cannot be duplicated */
    302	if (!get_promisc_qp(dev, port, steer, qpn))
    303		return false;
    304
    305	/* The qp is promisc qp so it is a duplicate on this index
    306	 * Find the index entry, and remove the duplicate */
    307	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
    308		if (tmp_entry->index == index) {
    309			entry = tmp_entry;
    310			break;
    311		}
    312	}
    313	if (unlikely(!entry)) {
    314		mlx4_warn(dev, "Steering entry for index %x is not registered\n", index);
    315		return false;
    316	}
    317	list_for_each_entry_safe(dqp, tmp_dqp, &entry->duplicates, list) {
    318		if (dqp->qpn == qpn) {
    319			list_del(&dqp->list);
    320			kfree(dqp);
    321		}
    322	}
    323	return true;
    324}
    325
    326/* Returns true if all the QPs != tqpn contained in this entry
    327 * are Promisc QPs. Returns false otherwise.
    328 */
    329static bool promisc_steering_entry(struct mlx4_dev *dev, u8 port,
    330				   enum mlx4_steer_type steer,
    331				   unsigned int index, u32 tqpn,
    332				   u32 *members_count)
    333{
    334	struct mlx4_cmd_mailbox *mailbox;
    335	struct mlx4_mgm *mgm;
    336	u32 m_count;
    337	bool ret = false;
    338	int i;
    339
    340	if (port < 1 || port > dev->caps.num_ports)
    341		return false;
    342
    343	mailbox = mlx4_alloc_cmd_mailbox(dev);
    344	if (IS_ERR(mailbox))
    345		return false;
    346	mgm = mailbox->buf;
    347
    348	if (mlx4_READ_ENTRY(dev, index, mailbox))
    349		goto out;
    350	m_count = be32_to_cpu(mgm->members_count) & 0xffffff;
    351	if (members_count)
    352		*members_count = m_count;
    353
    354	for (i = 0;  i < m_count; i++) {
    355		u32 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
    356		if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
    357			/* the qp is not promisc, the entry can't be removed */
    358			goto out;
    359		}
    360	}
    361	ret = true;
    362out:
    363	mlx4_free_cmd_mailbox(dev, mailbox);
    364	return ret;
    365}
    366
    367/* IF a steering entry contains only promisc QPs, it can be removed. */
    368static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
    369				      enum mlx4_steer_type steer,
    370				      unsigned int index, u32 tqpn)
    371{
    372	struct mlx4_steer *s_steer;
    373	struct mlx4_steer_index *entry = NULL, *tmp_entry;
    374	u32 members_count;
    375	bool ret = false;
    376
    377	if (port < 1 || port > dev->caps.num_ports)
    378		return NULL;
    379
    380	s_steer = &mlx4_priv(dev)->steer[port - 1];
    381
    382	if (!promisc_steering_entry(dev, port, steer, index,
    383				    tqpn, &members_count))
    384		goto out;
    385
    386	/* All the qps currently registered for this entry are promiscuous,
    387	  * Checking for duplicates */
    388	ret = true;
    389	list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) {
    390		if (entry->index == index) {
    391			if (list_empty(&entry->duplicates) ||
    392			    members_count == 1) {
    393				struct mlx4_promisc_qp *pqp, *tmp_pqp;
    394				/* If there is only 1 entry in duplicates then
    395				 * this is the QP we want to delete, going over
    396				 * the list and deleting the entry.
    397				 */
    398				list_del(&entry->list);
    399				list_for_each_entry_safe(pqp, tmp_pqp,
    400							 &entry->duplicates,
    401							 list) {
    402					list_del(&pqp->list);
    403					kfree(pqp);
    404				}
    405				kfree(entry);
    406			} else {
    407				/* This entry contains duplicates so it shouldn't be removed */
    408				ret = false;
    409				goto out;
    410			}
    411		}
    412	}
    413
    414out:
    415	return ret;
    416}
    417
    418static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
    419			  enum mlx4_steer_type steer, u32 qpn)
    420{
    421	struct mlx4_steer *s_steer;
    422	struct mlx4_cmd_mailbox *mailbox;
    423	struct mlx4_mgm *mgm;
    424	struct mlx4_steer_index *entry;
    425	struct mlx4_promisc_qp *pqp;
    426	struct mlx4_promisc_qp *dqp;
    427	u32 members_count;
    428	u32 prot;
    429	int i;
    430	bool found;
    431	int err;
    432	struct mlx4_priv *priv = mlx4_priv(dev);
    433
    434	if (port < 1 || port > dev->caps.num_ports)
    435		return -EINVAL;
    436
    437	s_steer = &mlx4_priv(dev)->steer[port - 1];
    438
    439	mutex_lock(&priv->mcg_table.mutex);
    440
    441	if (get_promisc_qp(dev, port, steer, qpn)) {
    442		err = 0;  /* Noting to do, already exists */
    443		goto out_mutex;
    444	}
    445
    446	pqp = kmalloc(sizeof(*pqp), GFP_KERNEL);
    447	if (!pqp) {
    448		err = -ENOMEM;
    449		goto out_mutex;
    450	}
    451	pqp->qpn = qpn;
    452
    453	mailbox = mlx4_alloc_cmd_mailbox(dev);
    454	if (IS_ERR(mailbox)) {
    455		err = -ENOMEM;
    456		goto out_alloc;
    457	}
    458	mgm = mailbox->buf;
    459
    460	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
    461		/* The promisc QP needs to be added for each one of the steering
    462		 * entries. If it already exists, needs to be added as
    463		 * a duplicate for this entry.
    464		 */
    465		list_for_each_entry(entry,
    466				    &s_steer->steer_entries[steer],
    467				    list) {
    468			err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
    469			if (err)
    470				goto out_mailbox;
    471
    472			members_count = be32_to_cpu(mgm->members_count) &
    473					0xffffff;
    474			prot = be32_to_cpu(mgm->members_count) >> 30;
    475			found = false;
    476			for (i = 0; i < members_count; i++) {
    477				if ((be32_to_cpu(mgm->qp[i]) &
    478				     MGM_QPN_MASK) == qpn) {
    479					/* Entry already exists.
    480					 * Add to duplicates.
    481					 */
    482					dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
    483					if (!dqp) {
    484						err = -ENOMEM;
    485						goto out_mailbox;
    486					}
    487					dqp->qpn = qpn;
    488					list_add_tail(&dqp->list,
    489						      &entry->duplicates);
    490					found = true;
    491				}
    492			}
    493			if (!found) {
    494				/* Need to add the qpn to mgm */
    495				if (members_count ==
    496				    dev->caps.num_qp_per_mgm) {
    497					/* entry is full */
    498					err = -ENOMEM;
    499					goto out_mailbox;
    500				}
    501				mgm->qp[members_count++] =
    502					cpu_to_be32(qpn & MGM_QPN_MASK);
    503				mgm->members_count =
    504					cpu_to_be32(members_count |
    505						    (prot << 30));
    506				err = mlx4_WRITE_ENTRY(dev, entry->index,
    507						       mailbox);
    508				if (err)
    509					goto out_mailbox;
    510			}
    511		}
    512	}
    513
    514	/* add the new qpn to list of promisc qps */
    515	list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
    516	/* now need to add all the promisc qps to default entry */
    517	memset(mgm, 0, sizeof(*mgm));
    518	members_count = 0;
    519	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) {
    520		if (members_count == dev->caps.num_qp_per_mgm) {
    521			/* entry is full */
    522			err = -ENOMEM;
    523			goto out_list;
    524		}
    525		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
    526	}
    527	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
    528
    529	err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
    530	if (err)
    531		goto out_list;
    532
    533	mlx4_free_cmd_mailbox(dev, mailbox);
    534	mutex_unlock(&priv->mcg_table.mutex);
    535	return 0;
    536
    537out_list:
    538	list_del(&pqp->list);
    539out_mailbox:
    540	mlx4_free_cmd_mailbox(dev, mailbox);
    541out_alloc:
    542	kfree(pqp);
    543out_mutex:
    544	mutex_unlock(&priv->mcg_table.mutex);
    545	return err;
    546}
    547
    548static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
    549			     enum mlx4_steer_type steer, u32 qpn)
    550{
    551	struct mlx4_priv *priv = mlx4_priv(dev);
    552	struct mlx4_steer *s_steer;
    553	struct mlx4_cmd_mailbox *mailbox;
    554	struct mlx4_mgm *mgm;
    555	struct mlx4_steer_index *entry, *tmp_entry;
    556	struct mlx4_promisc_qp *pqp;
    557	struct mlx4_promisc_qp *dqp;
    558	u32 members_count;
    559	bool found;
    560	bool back_to_list = false;
    561	int i;
    562	int err;
    563
    564	if (port < 1 || port > dev->caps.num_ports)
    565		return -EINVAL;
    566
    567	s_steer = &mlx4_priv(dev)->steer[port - 1];
    568	mutex_lock(&priv->mcg_table.mutex);
    569
    570	pqp = get_promisc_qp(dev, port, steer, qpn);
    571	if (unlikely(!pqp)) {
    572		mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);
    573		/* nothing to do */
    574		err = 0;
    575		goto out_mutex;
    576	}
    577
    578	/*remove from list of promisc qps */
    579	list_del(&pqp->list);
    580
    581	/* set the default entry not to include the removed one */
    582	mailbox = mlx4_alloc_cmd_mailbox(dev);
    583	if (IS_ERR(mailbox)) {
    584		err = -ENOMEM;
    585		back_to_list = true;
    586		goto out_list;
    587	}
    588	mgm = mailbox->buf;
    589	members_count = 0;
    590	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
    591		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
    592	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
    593
    594	err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
    595	if (err)
    596		goto out_mailbox;
    597
    598	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
    599		/* Remove the QP from all the steering entries */
    600		list_for_each_entry_safe(entry, tmp_entry,
    601					 &s_steer->steer_entries[steer],
    602					 list) {
    603			found = false;
    604			list_for_each_entry(dqp, &entry->duplicates, list) {
    605				if (dqp->qpn == qpn) {
    606					found = true;
    607					break;
    608				}
    609			}
    610			if (found) {
    611				/* A duplicate, no need to change the MGM,
    612				 * only update the duplicates list
    613				 */
    614				list_del(&dqp->list);
    615				kfree(dqp);
    616			} else {
    617				int loc = -1;
    618
    619				err = mlx4_READ_ENTRY(dev,
    620						      entry->index,
    621						      mailbox);
    622				if (err)
    623					goto out_mailbox;
    624				members_count =
    625					be32_to_cpu(mgm->members_count) &
    626					0xffffff;
    627				if (!members_count) {
    628					mlx4_warn(dev, "QP %06x wasn't found in entry %x mcount=0. deleting entry...\n",
    629						  qpn, entry->index);
    630					list_del(&entry->list);
    631					kfree(entry);
    632					continue;
    633				}
    634
    635				for (i = 0; i < members_count; ++i)
    636					if ((be32_to_cpu(mgm->qp[i]) &
    637					     MGM_QPN_MASK) == qpn) {
    638						loc = i;
    639						break;
    640					}
    641
    642				if (loc < 0) {
    643					mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
    644						 qpn, entry->index);
    645					err = -EINVAL;
    646					goto out_mailbox;
    647				}
    648
    649				/* Copy the last QP in this MGM
    650				 * over removed QP
    651				 */
    652				mgm->qp[loc] = mgm->qp[members_count - 1];
    653				mgm->qp[members_count - 1] = 0;
    654				mgm->members_count =
    655					cpu_to_be32(--members_count |
    656						    (MLX4_PROT_ETH << 30));
    657
    658				err = mlx4_WRITE_ENTRY(dev,
    659						       entry->index,
    660						       mailbox);
    661				if (err)
    662					goto out_mailbox;
    663			}
    664		}
    665	}
    666
    667out_mailbox:
    668	mlx4_free_cmd_mailbox(dev, mailbox);
    669out_list:
    670	if (back_to_list)
    671		list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
    672	else
    673		kfree(pqp);
    674out_mutex:
    675	mutex_unlock(&priv->mcg_table.mutex);
    676	return err;
    677}
    678
    679/*
    680 * Caller must hold MCG table semaphore.  gid and mgm parameters must
    681 * be properly aligned for command interface.
    682 *
    683 *  Returns 0 unless a firmware command error occurs.
    684 *
    685 * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1
    686 * and *mgm holds MGM entry.
    687 *
    688 * if GID is found in AMGM, *index = index in AMGM, *prev = index of
    689 * previous entry in hash chain and *mgm holds AMGM entry.
    690 *
    691 * If no AMGM exists for given gid, *index = -1, *prev = index of last
    692 * entry in hash chain and *mgm holds end of hash chain.
    693 */
    694static int find_entry(struct mlx4_dev *dev, u8 port,
    695		      u8 *gid, enum mlx4_protocol prot,
    696		      struct mlx4_cmd_mailbox *mgm_mailbox,
    697		      int *prev, int *index)
    698{
    699	struct mlx4_cmd_mailbox *mailbox;
    700	struct mlx4_mgm *mgm = mgm_mailbox->buf;
    701	u8 *mgid;
    702	int err;
    703	u16 hash;
    704	u8 op_mod = (prot == MLX4_PROT_ETH) ?
    705		!!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0;
    706
    707	mailbox = mlx4_alloc_cmd_mailbox(dev);
    708	if (IS_ERR(mailbox))
    709		return -ENOMEM;
    710	mgid = mailbox->buf;
    711
    712	memcpy(mgid, gid, 16);
    713
    714	err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod);
    715	mlx4_free_cmd_mailbox(dev, mailbox);
    716	if (err)
    717		return err;
    718
    719	if (0)
    720		mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, hash);
    721
    722	*index = hash;
    723	*prev  = -1;
    724
    725	do {
    726		err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox);
    727		if (err)
    728			return err;
    729
    730		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
    731			if (*index != hash) {
    732				mlx4_err(dev, "Found zero MGID in AMGM\n");
    733				err = -EINVAL;
    734			}
    735			return err;
    736		}
    737
    738		if (!memcmp(mgm->gid, gid, 16) &&
    739		    be32_to_cpu(mgm->members_count) >> 30 == prot)
    740			return err;
    741
    742		*prev = *index;
    743		*index = be32_to_cpu(mgm->next_gid_index) >> 6;
    744	} while (*index);
    745
    746	*index = -1;
    747	return err;
    748}
    749
    750static const u8 __promisc_mode[] = {
    751	[MLX4_FS_REGULAR]   = 0x0,
    752	[MLX4_FS_ALL_DEFAULT] = 0x1,
    753	[MLX4_FS_MC_DEFAULT] = 0x3,
    754	[MLX4_FS_MIRROR_RX_PORT] = 0x4,
    755	[MLX4_FS_MIRROR_SX_PORT] = 0x5,
    756	[MLX4_FS_UC_SNIFFER] = 0x6,
    757	[MLX4_FS_MC_SNIFFER] = 0x7,
    758};
    759
    760int mlx4_map_sw_to_hw_steering_mode(struct mlx4_dev *dev,
    761				    enum mlx4_net_trans_promisc_mode flow_type)
    762{
    763	if (flow_type >= MLX4_FS_MODE_NUM) {
    764		mlx4_err(dev, "Invalid flow type. type = %d\n", flow_type);
    765		return -EINVAL;
    766	}
    767	return __promisc_mode[flow_type];
    768}
    769EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_mode);
    770
    771static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,
    772				  struct mlx4_net_trans_rule_hw_ctrl *hw)
    773{
    774	u8 flags = 0;
    775
    776	flags = ctrl->queue_mode == MLX4_NET_TRANS_Q_LIFO ? 1 : 0;
    777	flags |= ctrl->exclusive ? (1 << 2) : 0;
    778	flags |= ctrl->allow_loopback ? (1 << 3) : 0;
    779
    780	hw->flags = flags;
    781	hw->type = __promisc_mode[ctrl->promisc_mode];
    782	hw->prio = cpu_to_be16(ctrl->priority);
    783	hw->port = ctrl->port;
    784	hw->qpn = cpu_to_be32(ctrl->qpn);
    785}
    786
    787const u16 __sw_id_hw[] = {
    788	[MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001,
    789	[MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005,
    790	[MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003,
    791	[MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002,
    792	[MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004,
    793	[MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006,
    794	[MLX4_NET_TRANS_RULE_ID_VXLAN]	 = 0xE008
    795};
    796
    797int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev,
    798				  enum mlx4_net_trans_rule_id id)
    799{
    800	if (id >= MLX4_NET_TRANS_RULE_NUM) {
    801		mlx4_err(dev, "Invalid network rule id. id = %d\n", id);
    802		return -EINVAL;
    803	}
    804	return __sw_id_hw[id];
    805}
    806EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_id);
    807
    808static const int __rule_hw_sz[] = {
    809	[MLX4_NET_TRANS_RULE_ID_ETH] =
    810		sizeof(struct mlx4_net_trans_rule_hw_eth),
    811	[MLX4_NET_TRANS_RULE_ID_IB] =
    812		sizeof(struct mlx4_net_trans_rule_hw_ib),
    813	[MLX4_NET_TRANS_RULE_ID_IPV6] = 0,
    814	[MLX4_NET_TRANS_RULE_ID_IPV4] =
    815		sizeof(struct mlx4_net_trans_rule_hw_ipv4),
    816	[MLX4_NET_TRANS_RULE_ID_TCP] =
    817		sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
    818	[MLX4_NET_TRANS_RULE_ID_UDP] =
    819		sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
    820	[MLX4_NET_TRANS_RULE_ID_VXLAN] =
    821		sizeof(struct mlx4_net_trans_rule_hw_vxlan)
    822};
    823
    824int mlx4_hw_rule_sz(struct mlx4_dev *dev,
    825	       enum mlx4_net_trans_rule_id id)
    826{
    827	if (id >= MLX4_NET_TRANS_RULE_NUM) {
    828		mlx4_err(dev, "Invalid network rule id. id = %d\n", id);
    829		return -EINVAL;
    830	}
    831
    832	return __rule_hw_sz[id];
    833}
    834EXPORT_SYMBOL_GPL(mlx4_hw_rule_sz);
    835
    836static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,
    837			    struct _rule_hw *rule_hw)
    838{
    839	if (mlx4_hw_rule_sz(dev, spec->id) < 0)
    840		return -EINVAL;
    841	memset(rule_hw, 0, mlx4_hw_rule_sz(dev, spec->id));
    842	rule_hw->id = cpu_to_be16(__sw_id_hw[spec->id]);
    843	rule_hw->size = mlx4_hw_rule_sz(dev, spec->id) >> 2;
    844
    845	switch (spec->id) {
    846	case MLX4_NET_TRANS_RULE_ID_ETH:
    847		memcpy(rule_hw->eth.dst_mac, spec->eth.dst_mac, ETH_ALEN);
    848		memcpy(rule_hw->eth.dst_mac_msk, spec->eth.dst_mac_msk,
    849		       ETH_ALEN);
    850		memcpy(rule_hw->eth.src_mac, spec->eth.src_mac, ETH_ALEN);
    851		memcpy(rule_hw->eth.src_mac_msk, spec->eth.src_mac_msk,
    852		       ETH_ALEN);
    853		if (spec->eth.ether_type_enable) {
    854			rule_hw->eth.ether_type_enable = 1;
    855			rule_hw->eth.ether_type = spec->eth.ether_type;
    856		}
    857		rule_hw->eth.vlan_tag = spec->eth.vlan_id;
    858		rule_hw->eth.vlan_tag_msk = spec->eth.vlan_id_msk;
    859		break;
    860
    861	case MLX4_NET_TRANS_RULE_ID_IB:
    862		rule_hw->ib.l3_qpn = spec->ib.l3_qpn;
    863		rule_hw->ib.qpn_mask = spec->ib.qpn_msk;
    864		memcpy(&rule_hw->ib.dst_gid, &spec->ib.dst_gid, 16);
    865		memcpy(&rule_hw->ib.dst_gid_msk, &spec->ib.dst_gid_msk, 16);
    866		break;
    867
    868	case MLX4_NET_TRANS_RULE_ID_IPV6:
    869		return -EOPNOTSUPP;
    870
    871	case MLX4_NET_TRANS_RULE_ID_IPV4:
    872		rule_hw->ipv4.src_ip = spec->ipv4.src_ip;
    873		rule_hw->ipv4.src_ip_msk = spec->ipv4.src_ip_msk;
    874		rule_hw->ipv4.dst_ip = spec->ipv4.dst_ip;
    875		rule_hw->ipv4.dst_ip_msk = spec->ipv4.dst_ip_msk;
    876		break;
    877
    878	case MLX4_NET_TRANS_RULE_ID_TCP:
    879	case MLX4_NET_TRANS_RULE_ID_UDP:
    880		rule_hw->tcp_udp.dst_port = spec->tcp_udp.dst_port;
    881		rule_hw->tcp_udp.dst_port_msk = spec->tcp_udp.dst_port_msk;
    882		rule_hw->tcp_udp.src_port = spec->tcp_udp.src_port;
    883		rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk;
    884		break;
    885
    886	case MLX4_NET_TRANS_RULE_ID_VXLAN:
    887		rule_hw->vxlan.vni =
    888			cpu_to_be32(be32_to_cpu(spec->vxlan.vni) << 8);
    889		rule_hw->vxlan.vni_mask =
    890			cpu_to_be32(be32_to_cpu(spec->vxlan.vni_mask) << 8);
    891		break;
    892
    893	default:
    894		return -EINVAL;
    895	}
    896
    897	return __rule_hw_sz[spec->id];
    898}
    899
    900static void mlx4_err_rule(struct mlx4_dev *dev, char *str,
    901			  struct mlx4_net_trans_rule *rule)
    902{
    903#define BUF_SIZE 256
    904	struct mlx4_spec_list *cur;
    905	char buf[BUF_SIZE];
    906	int len = 0;
    907
    908	mlx4_err(dev, "%s", str);
    909	len += scnprintf(buf + len, BUF_SIZE - len,
    910			 "port = %d prio = 0x%x qp = 0x%x ",
    911			 rule->port, rule->priority, rule->qpn);
    912
    913	list_for_each_entry(cur, &rule->list, list) {
    914		switch (cur->id) {
    915		case MLX4_NET_TRANS_RULE_ID_ETH:
    916			len += scnprintf(buf + len, BUF_SIZE - len,
    917					 "dmac = %pM ", &cur->eth.dst_mac);
    918			if (cur->eth.ether_type)
    919				len += scnprintf(buf + len, BUF_SIZE - len,
    920						 "ethertype = 0x%x ",
    921						 be16_to_cpu(cur->eth.ether_type));
    922			if (cur->eth.vlan_id)
    923				len += scnprintf(buf + len, BUF_SIZE - len,
    924						 "vlan-id = %d ",
    925						 be16_to_cpu(cur->eth.vlan_id));
    926			break;
    927
    928		case MLX4_NET_TRANS_RULE_ID_IPV4:
    929			if (cur->ipv4.src_ip)
    930				len += scnprintf(buf + len, BUF_SIZE - len,
    931						 "src-ip = %pI4 ",
    932						 &cur->ipv4.src_ip);
    933			if (cur->ipv4.dst_ip)
    934				len += scnprintf(buf + len, BUF_SIZE - len,
    935						 "dst-ip = %pI4 ",
    936						 &cur->ipv4.dst_ip);
    937			break;
    938
    939		case MLX4_NET_TRANS_RULE_ID_TCP:
    940		case MLX4_NET_TRANS_RULE_ID_UDP:
    941			if (cur->tcp_udp.src_port)
    942				len += scnprintf(buf + len, BUF_SIZE - len,
    943						 "src-port = %d ",
    944						 be16_to_cpu(cur->tcp_udp.src_port));
    945			if (cur->tcp_udp.dst_port)
    946				len += scnprintf(buf + len, BUF_SIZE - len,
    947						 "dst-port = %d ",
    948						 be16_to_cpu(cur->tcp_udp.dst_port));
    949			break;
    950
    951		case MLX4_NET_TRANS_RULE_ID_IB:
    952			len += scnprintf(buf + len, BUF_SIZE - len,
    953					 "dst-gid = %pI6\n", cur->ib.dst_gid);
    954			len += scnprintf(buf + len, BUF_SIZE - len,
    955					 "dst-gid-mask = %pI6\n",
    956					 cur->ib.dst_gid_msk);
    957			break;
    958
    959		case MLX4_NET_TRANS_RULE_ID_VXLAN:
    960			len += scnprintf(buf + len, BUF_SIZE - len,
    961					 "VNID = %d ", be32_to_cpu(cur->vxlan.vni));
    962			break;
    963		case MLX4_NET_TRANS_RULE_ID_IPV6:
    964			break;
    965
    966		default:
    967			break;
    968		}
    969	}
    970	len += scnprintf(buf + len, BUF_SIZE - len, "\n");
    971	mlx4_err(dev, "%s", buf);
    972
    973	if (len >= BUF_SIZE)
    974		mlx4_err(dev, "Network rule error message was truncated, print buffer is too small\n");
    975}
    976
    977int mlx4_flow_attach(struct mlx4_dev *dev,
    978		     struct mlx4_net_trans_rule *rule, u64 *reg_id)
    979{
    980	struct mlx4_cmd_mailbox *mailbox;
    981	struct mlx4_spec_list *cur;
    982	u32 size = 0;
    983	int ret;
    984
    985	mailbox = mlx4_alloc_cmd_mailbox(dev);
    986	if (IS_ERR(mailbox))
    987		return PTR_ERR(mailbox);
    988
    989	if (!mlx4_qp_lookup(dev, rule->qpn)) {
    990		mlx4_err_rule(dev, "QP doesn't exist\n", rule);
    991		ret = -EINVAL;
    992		goto out;
    993	}
    994
    995	trans_rule_ctrl_to_hw(rule, mailbox->buf);
    996
    997	size += sizeof(struct mlx4_net_trans_rule_hw_ctrl);
    998
    999	list_for_each_entry(cur, &rule->list, list) {
   1000		ret = parse_trans_rule(dev, cur, mailbox->buf + size);
   1001		if (ret < 0)
   1002			goto out;
   1003
   1004		size += ret;
   1005	}
   1006
   1007	ret = mlx4_QP_FLOW_STEERING_ATTACH(dev, mailbox, size >> 2, reg_id);
   1008	if (ret == -ENOMEM) {
   1009		mlx4_err_rule(dev,
   1010			      "mcg table is full. Fail to register network rule\n",
   1011			      rule);
   1012	} else if (ret) {
   1013		if (ret == -ENXIO) {
   1014			if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED)
   1015				mlx4_err_rule(dev,
   1016					      "DMFS is not enabled, "
   1017					      "failed to register network rule.\n",
   1018					      rule);
   1019			else
   1020				mlx4_err_rule(dev,
   1021					      "Rule exceeds the dmfs_high_rate_mode limitations, "
   1022					      "failed to register network rule.\n",
   1023					      rule);
   1024
   1025		} else {
   1026			mlx4_err_rule(dev, "Fail to register network rule.\n", rule);
   1027		}
   1028	}
   1029
   1030out:
   1031	mlx4_free_cmd_mailbox(dev, mailbox);
   1032
   1033	return ret;
   1034}
   1035EXPORT_SYMBOL_GPL(mlx4_flow_attach);
   1036
   1037int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id)
   1038{
   1039	int err;
   1040
   1041	err = mlx4_QP_FLOW_STEERING_DETACH(dev, reg_id);
   1042	if (err)
   1043		mlx4_err(dev, "Fail to detach network rule. registration id = 0x%llx\n",
   1044			 reg_id);
   1045	return err;
   1046}
   1047EXPORT_SYMBOL_GPL(mlx4_flow_detach);
   1048
   1049int mlx4_tunnel_steer_add(struct mlx4_dev *dev, const unsigned char *addr,
   1050			  int port, int qpn, u16 prio, u64 *reg_id)
   1051{
   1052	int err;
   1053	struct mlx4_spec_list spec_eth_outer = { {NULL} };
   1054	struct mlx4_spec_list spec_vxlan     = { {NULL} };
   1055	struct mlx4_spec_list spec_eth_inner = { {NULL} };
   1056
   1057	struct mlx4_net_trans_rule rule = {
   1058		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
   1059		.exclusive = 0,
   1060		.allow_loopback = 1,
   1061		.promisc_mode = MLX4_FS_REGULAR,
   1062	};
   1063
   1064	__be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);
   1065
   1066	rule.port = port;
   1067	rule.qpn = qpn;
   1068	rule.priority = prio;
   1069	INIT_LIST_HEAD(&rule.list);
   1070
   1071	spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH;
   1072	memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN);
   1073	memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN);
   1074
   1075	spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN;    /* any vxlan header */
   1076	spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH;	 /* any inner eth header */
   1077
   1078	list_add_tail(&spec_eth_outer.list, &rule.list);
   1079	list_add_tail(&spec_vxlan.list,     &rule.list);
   1080	list_add_tail(&spec_eth_inner.list, &rule.list);
   1081
   1082	err = mlx4_flow_attach(dev, &rule, reg_id);
   1083	return err;
   1084}
   1085EXPORT_SYMBOL(mlx4_tunnel_steer_add);
   1086
   1087int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
   1088				      u32 max_range_qpn)
   1089{
   1090	int err;
   1091	u64 in_param;
   1092
   1093	in_param = ((u64) min_range_qpn) << 32;
   1094	in_param |= ((u64) max_range_qpn) & 0xFFFFFFFF;
   1095
   1096	err = mlx4_cmd(dev, in_param, 0, 0,
   1097			MLX4_FLOW_STEERING_IB_UC_QP_RANGE,
   1098			MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
   1099
   1100	return err;
   1101}
   1102EXPORT_SYMBOL_GPL(mlx4_FLOW_STEERING_IB_UC_QP_RANGE);
   1103
   1104int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
   1105			  int block_mcast_loopback, enum mlx4_protocol prot,
   1106			  enum mlx4_steer_type steer)
   1107{
   1108	struct mlx4_priv *priv = mlx4_priv(dev);
   1109	struct mlx4_cmd_mailbox *mailbox;
   1110	struct mlx4_mgm *mgm;
   1111	u32 members_count;
   1112	int index = -1, prev;
   1113	int link = 0;
   1114	int i;
   1115	int err;
   1116	u8 port = gid[5];
   1117	u8 new_entry = 0;
   1118
   1119	mailbox = mlx4_alloc_cmd_mailbox(dev);
   1120	if (IS_ERR(mailbox))
   1121		return PTR_ERR(mailbox);
   1122	mgm = mailbox->buf;
   1123
   1124	mutex_lock(&priv->mcg_table.mutex);
   1125	err = find_entry(dev, port, gid, prot,
   1126			 mailbox, &prev, &index);
   1127	if (err)
   1128		goto out;
   1129
   1130	if (index != -1) {
   1131		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
   1132			new_entry = 1;
   1133			memcpy(mgm->gid, gid, 16);
   1134		}
   1135	} else {
   1136		link = 1;
   1137
   1138		index = mlx4_bitmap_alloc(&priv->mcg_table.bitmap);
   1139		if (index == -1) {
   1140			mlx4_err(dev, "No AMGM entries left\n");
   1141			err = -ENOMEM;
   1142			goto out;
   1143		}
   1144		index += dev->caps.num_mgms;
   1145
   1146		new_entry = 1;
   1147		memset(mgm, 0, sizeof(*mgm));
   1148		memcpy(mgm->gid, gid, 16);
   1149	}
   1150
   1151	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
   1152	if (members_count == dev->caps.num_qp_per_mgm) {
   1153		mlx4_err(dev, "MGM at index %x is full\n", index);
   1154		err = -ENOMEM;
   1155		goto out;
   1156	}
   1157
   1158	for (i = 0; i < members_count; ++i)
   1159		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
   1160			mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn);
   1161			err = 0;
   1162			goto out;
   1163		}
   1164
   1165	if (block_mcast_loopback)
   1166		mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) |
   1167						       (1U << MGM_BLCK_LB_BIT));
   1168	else
   1169		mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);
   1170
   1171	mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30);
   1172
   1173	err = mlx4_WRITE_ENTRY(dev, index, mailbox);
   1174	if (err)
   1175		goto out;
   1176
   1177	if (!link)
   1178		goto out;
   1179
   1180	err = mlx4_READ_ENTRY(dev, prev, mailbox);
   1181	if (err)
   1182		goto out;
   1183
   1184	mgm->next_gid_index = cpu_to_be32(index << 6);
   1185
   1186	err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
   1187	if (err)
   1188		goto out;
   1189
   1190out:
   1191	if (prot == MLX4_PROT_ETH && index != -1) {
   1192		/* manage the steering entry for promisc mode */
   1193		if (new_entry)
   1194			err = new_steering_entry(dev, port, steer,
   1195						 index, qp->qpn);
   1196		else
   1197			err = existing_steering_entry(dev, port, steer,
   1198						      index, qp->qpn);
   1199	}
   1200	if (err && link && index != -1) {
   1201		if (index < dev->caps.num_mgms)
   1202			mlx4_warn(dev, "Got AMGM index %d < %d\n",
   1203				  index, dev->caps.num_mgms);
   1204		else
   1205			mlx4_bitmap_free(&priv->mcg_table.bitmap,
   1206					 index - dev->caps.num_mgms, MLX4_USE_RR);
   1207	}
   1208	mutex_unlock(&priv->mcg_table.mutex);
   1209
   1210	mlx4_free_cmd_mailbox(dev, mailbox);
   1211	return err;
   1212}
   1213
   1214int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
   1215			  enum mlx4_protocol prot, enum mlx4_steer_type steer)
   1216{
   1217	struct mlx4_priv *priv = mlx4_priv(dev);
   1218	struct mlx4_cmd_mailbox *mailbox;
   1219	struct mlx4_mgm *mgm;
   1220	u32 members_count;
   1221	int prev, index;
   1222	int i, loc = -1;
   1223	int err;
   1224	u8 port = gid[5];
   1225	bool removed_entry = false;
   1226
   1227	mailbox = mlx4_alloc_cmd_mailbox(dev);
   1228	if (IS_ERR(mailbox))
   1229		return PTR_ERR(mailbox);
   1230	mgm = mailbox->buf;
   1231
   1232	mutex_lock(&priv->mcg_table.mutex);
   1233
   1234	err = find_entry(dev, port, gid, prot,
   1235			 mailbox, &prev, &index);
   1236	if (err)
   1237		goto out;
   1238
   1239	if (index == -1) {
   1240		mlx4_err(dev, "MGID %pI6 not found\n", gid);
   1241		err = -EINVAL;
   1242		goto out;
   1243	}
   1244
   1245	/* If this QP is also a promisc QP, it shouldn't be removed only if
   1246	 * at least one none promisc QP is also attached to this MCG
   1247	 */
   1248	if (prot == MLX4_PROT_ETH &&
   1249	    check_duplicate_entry(dev, port, steer, index, qp->qpn) &&
   1250	    !promisc_steering_entry(dev, port, steer, index, qp->qpn, NULL))
   1251			goto out;
   1252
   1253	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
   1254	for (i = 0; i < members_count; ++i)
   1255		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
   1256			loc = i;
   1257			break;
   1258		}
   1259
   1260	if (loc == -1) {
   1261		mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
   1262		err = -EINVAL;
   1263		goto out;
   1264	}
   1265
   1266	/* copy the last QP in this MGM over removed QP */
   1267	mgm->qp[loc] = mgm->qp[members_count - 1];
   1268	mgm->qp[members_count - 1] = 0;
   1269	mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
   1270
   1271	if (prot == MLX4_PROT_ETH)
   1272		removed_entry = can_remove_steering_entry(dev, port, steer,
   1273								index, qp->qpn);
   1274	if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) {
   1275		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
   1276		goto out;
   1277	}
   1278
   1279	/* We are going to delete the entry, members count should be 0 */
   1280	mgm->members_count = cpu_to_be32((u32) prot << 30);
   1281
   1282	if (prev == -1) {
   1283		/* Remove entry from MGM */
   1284		int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6;
   1285		if (amgm_index) {
   1286			err = mlx4_READ_ENTRY(dev, amgm_index, mailbox);
   1287			if (err)
   1288				goto out;
   1289		} else
   1290			memset(mgm->gid, 0, 16);
   1291
   1292		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
   1293		if (err)
   1294			goto out;
   1295
   1296		if (amgm_index) {
   1297			if (amgm_index < dev->caps.num_mgms)
   1298				mlx4_warn(dev, "MGM entry %d had AMGM index %d < %d\n",
   1299					  index, amgm_index, dev->caps.num_mgms);
   1300			else
   1301				mlx4_bitmap_free(&priv->mcg_table.bitmap,
   1302						 amgm_index - dev->caps.num_mgms, MLX4_USE_RR);
   1303		}
   1304	} else {
   1305		/* Remove entry from AMGM */
   1306		int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6;
   1307		err = mlx4_READ_ENTRY(dev, prev, mailbox);
   1308		if (err)
   1309			goto out;
   1310
   1311		mgm->next_gid_index = cpu_to_be32(cur_next_index << 6);
   1312
   1313		err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
   1314		if (err)
   1315			goto out;
   1316
   1317		if (index < dev->caps.num_mgms)
   1318			mlx4_warn(dev, "entry %d had next AMGM index %d < %d\n",
   1319				  prev, index, dev->caps.num_mgms);
   1320		else
   1321			mlx4_bitmap_free(&priv->mcg_table.bitmap,
   1322					 index - dev->caps.num_mgms, MLX4_USE_RR);
   1323	}
   1324
   1325out:
   1326	mutex_unlock(&priv->mcg_table.mutex);
   1327
   1328	mlx4_free_cmd_mailbox(dev, mailbox);
   1329	if (err && dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR)
   1330		/* In case device is under an error, return success as a closing command */
   1331		err = 0;
   1332	return err;
   1333}
   1334
   1335static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp,
   1336			  u8 gid[16], u8 attach, u8 block_loopback,
   1337			  enum mlx4_protocol prot)
   1338{
   1339	struct mlx4_cmd_mailbox *mailbox;
   1340	int err = 0;
   1341	int qpn;
   1342
   1343	if (!mlx4_is_mfunc(dev))
   1344		return -EBADF;
   1345
   1346	mailbox = mlx4_alloc_cmd_mailbox(dev);
   1347	if (IS_ERR(mailbox))
   1348		return PTR_ERR(mailbox);
   1349
   1350	memcpy(mailbox->buf, gid, 16);
   1351	qpn = qp->qpn;
   1352	qpn |= (prot << 28);
   1353	if (attach && block_loopback)
   1354		qpn |= (1 << 31);
   1355
   1356	err = mlx4_cmd(dev, mailbox->dma, qpn, attach,
   1357		       MLX4_CMD_QP_ATTACH, MLX4_CMD_TIME_CLASS_A,
   1358		       MLX4_CMD_WRAPPED);
   1359
   1360	mlx4_free_cmd_mailbox(dev, mailbox);
   1361	if (err && !attach &&
   1362	    dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR)
   1363		err = 0;
   1364	return err;
   1365}
   1366
   1367int mlx4_trans_to_dmfs_attach(struct mlx4_dev *dev, struct mlx4_qp *qp,
   1368			      u8 gid[16], u8 port,
   1369			      int block_mcast_loopback,
   1370			      enum mlx4_protocol prot, u64 *reg_id)
   1371{
   1372		struct mlx4_spec_list spec = { {NULL} };
   1373		__be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);
   1374
   1375		struct mlx4_net_trans_rule rule = {
   1376			.queue_mode = MLX4_NET_TRANS_Q_FIFO,
   1377			.exclusive = 0,
   1378			.promisc_mode = MLX4_FS_REGULAR,
   1379			.priority = MLX4_DOMAIN_NIC,
   1380		};
   1381
   1382		rule.allow_loopback = !block_mcast_loopback;
   1383		rule.port = port;
   1384		rule.qpn = qp->qpn;
   1385		INIT_LIST_HEAD(&rule.list);
   1386
   1387		switch (prot) {
   1388		case MLX4_PROT_ETH:
   1389			spec.id = MLX4_NET_TRANS_RULE_ID_ETH;
   1390			memcpy(spec.eth.dst_mac, &gid[10], ETH_ALEN);
   1391			memcpy(spec.eth.dst_mac_msk, &mac_mask, ETH_ALEN);
   1392			break;
   1393
   1394		case MLX4_PROT_IB_IPV6:
   1395			spec.id = MLX4_NET_TRANS_RULE_ID_IB;
   1396			memcpy(spec.ib.dst_gid, gid, 16);
   1397			memset(&spec.ib.dst_gid_msk, 0xff, 16);
   1398			break;
   1399		default:
   1400			return -EINVAL;
   1401		}
   1402		list_add_tail(&spec.list, &rule.list);
   1403
   1404		return mlx4_flow_attach(dev, &rule, reg_id);
   1405}
   1406
   1407int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
   1408			  u8 port, int block_mcast_loopback,
   1409			  enum mlx4_protocol prot, u64 *reg_id)
   1410{
   1411	switch (dev->caps.steering_mode) {
   1412	case MLX4_STEERING_MODE_A0:
   1413		if (prot == MLX4_PROT_ETH)
   1414			return 0;
   1415		fallthrough;
   1416
   1417	case MLX4_STEERING_MODE_B0:
   1418		if (prot == MLX4_PROT_ETH)
   1419			gid[7] |= (MLX4_MC_STEER << 1);
   1420
   1421		if (mlx4_is_mfunc(dev))
   1422			return mlx4_QP_ATTACH(dev, qp, gid, 1,
   1423					      block_mcast_loopback, prot);
   1424		return mlx4_qp_attach_common(dev, qp, gid,
   1425					     block_mcast_loopback, prot,
   1426					     MLX4_MC_STEER);
   1427
   1428	case MLX4_STEERING_MODE_DEVICE_MANAGED:
   1429		return mlx4_trans_to_dmfs_attach(dev, qp, gid, port,
   1430						 block_mcast_loopback,
   1431						 prot, reg_id);
   1432	default:
   1433		return -EINVAL;
   1434	}
   1435}
   1436EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
   1437
   1438int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
   1439			  enum mlx4_protocol prot, u64 reg_id)
   1440{
   1441	switch (dev->caps.steering_mode) {
   1442	case MLX4_STEERING_MODE_A0:
   1443		if (prot == MLX4_PROT_ETH)
   1444			return 0;
   1445		fallthrough;
   1446
   1447	case MLX4_STEERING_MODE_B0:
   1448		if (prot == MLX4_PROT_ETH)
   1449			gid[7] |= (MLX4_MC_STEER << 1);
   1450
   1451		if (mlx4_is_mfunc(dev))
   1452			return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
   1453
   1454		return mlx4_qp_detach_common(dev, qp, gid, prot,
   1455					     MLX4_MC_STEER);
   1456
   1457	case MLX4_STEERING_MODE_DEVICE_MANAGED:
   1458		return mlx4_flow_detach(dev, reg_id);
   1459
   1460	default:
   1461		return -EINVAL;
   1462	}
   1463}
   1464EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
   1465
   1466int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
   1467				u32 qpn, enum mlx4_net_trans_promisc_mode mode)
   1468{
   1469	struct mlx4_net_trans_rule rule = {
   1470		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
   1471		.exclusive = 0,
   1472		.allow_loopback = 1,
   1473	};
   1474
   1475	u64 *regid_p;
   1476
   1477	switch (mode) {
   1478	case MLX4_FS_ALL_DEFAULT:
   1479		regid_p = &dev->regid_promisc_array[port];
   1480		break;
   1481	case MLX4_FS_MC_DEFAULT:
   1482		regid_p = &dev->regid_allmulti_array[port];
   1483		break;
   1484	default:
   1485		return -1;
   1486	}
   1487
   1488	if (*regid_p != 0)
   1489		return -1;
   1490
   1491	rule.promisc_mode = mode;
   1492	rule.port = port;
   1493	rule.qpn = qpn;
   1494	INIT_LIST_HEAD(&rule.list);
   1495	mlx4_info(dev, "going promisc on %x\n", port);
   1496
   1497	return  mlx4_flow_attach(dev, &rule, regid_p);
   1498}
   1499EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_add);
   1500
   1501int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
   1502				   enum mlx4_net_trans_promisc_mode mode)
   1503{
   1504	int ret;
   1505	u64 *regid_p;
   1506
   1507	switch (mode) {
   1508	case MLX4_FS_ALL_DEFAULT:
   1509		regid_p = &dev->regid_promisc_array[port];
   1510		break;
   1511	case MLX4_FS_MC_DEFAULT:
   1512		regid_p = &dev->regid_allmulti_array[port];
   1513		break;
   1514	default:
   1515		return -1;
   1516	}
   1517
   1518	if (*regid_p == 0)
   1519		return -1;
   1520
   1521	ret =  mlx4_flow_detach(dev, *regid_p);
   1522	if (ret == 0)
   1523		*regid_p = 0;
   1524
   1525	return ret;
   1526}
   1527EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_remove);
   1528
   1529int mlx4_unicast_attach(struct mlx4_dev *dev,
   1530			struct mlx4_qp *qp, u8 gid[16],
   1531			int block_mcast_loopback, enum mlx4_protocol prot)
   1532{
   1533	if (prot == MLX4_PROT_ETH)
   1534		gid[7] |= (MLX4_UC_STEER << 1);
   1535
   1536	if (mlx4_is_mfunc(dev))
   1537		return mlx4_QP_ATTACH(dev, qp, gid, 1,
   1538					block_mcast_loopback, prot);
   1539
   1540	return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback,
   1541					prot, MLX4_UC_STEER);
   1542}
   1543EXPORT_SYMBOL_GPL(mlx4_unicast_attach);
   1544
   1545int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
   1546			       u8 gid[16], enum mlx4_protocol prot)
   1547{
   1548	if (prot == MLX4_PROT_ETH)
   1549		gid[7] |= (MLX4_UC_STEER << 1);
   1550
   1551	if (mlx4_is_mfunc(dev))
   1552		return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
   1553
   1554	return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_UC_STEER);
   1555}
   1556EXPORT_SYMBOL_GPL(mlx4_unicast_detach);
   1557
   1558int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave,
   1559			 struct mlx4_vhcr *vhcr,
   1560			 struct mlx4_cmd_mailbox *inbox,
   1561			 struct mlx4_cmd_mailbox *outbox,
   1562			 struct mlx4_cmd_info *cmd)
   1563{
   1564	u32 qpn = (u32) vhcr->in_param & 0xffffffff;
   1565	int port = mlx4_slave_convert_port(dev, slave, vhcr->in_param >> 62);
   1566	enum mlx4_steer_type steer = vhcr->in_modifier;
   1567
   1568	if (port < 0)
   1569		return -EINVAL;
   1570
   1571	/* Promiscuous unicast is not allowed in mfunc */
   1572	if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)
   1573		return 0;
   1574
   1575	if (vhcr->op_modifier)
   1576		return add_promisc_qp(dev, port, steer, qpn);
   1577	else
   1578		return remove_promisc_qp(dev, port, steer, qpn);
   1579}
   1580
   1581static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn,
   1582			enum mlx4_steer_type steer, u8 add, u8 port)
   1583{
   1584	return mlx4_cmd(dev, (u64) qpn | (u64) port << 62, (u32) steer, add,
   1585			MLX4_CMD_PROMISC, MLX4_CMD_TIME_CLASS_A,
   1586			MLX4_CMD_WRAPPED);
   1587}
   1588
   1589int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
   1590{
   1591	if (mlx4_is_mfunc(dev))
   1592		return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port);
   1593
   1594	return add_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
   1595}
   1596EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add);
   1597
   1598int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
   1599{
   1600	if (mlx4_is_mfunc(dev))
   1601		return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port);
   1602
   1603	return remove_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
   1604}
   1605EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove);
   1606
   1607int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
   1608{
   1609	if (mlx4_is_mfunc(dev))
   1610		return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port);
   1611
   1612	return add_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
   1613}
   1614EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add);
   1615
   1616int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
   1617{
   1618	if (mlx4_is_mfunc(dev))
   1619		return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port);
   1620
   1621	return remove_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
   1622}
   1623EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove);
   1624
   1625int mlx4_init_mcg_table(struct mlx4_dev *dev)
   1626{
   1627	struct mlx4_priv *priv = mlx4_priv(dev);
   1628	int err;
   1629
   1630	/* No need for mcg_table when fw managed the mcg table*/
   1631	if (dev->caps.steering_mode ==
   1632	    MLX4_STEERING_MODE_DEVICE_MANAGED)
   1633		return 0;
   1634	err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms,
   1635			       dev->caps.num_amgms - 1, 0, 0);
   1636	if (err)
   1637		return err;
   1638
   1639	mutex_init(&priv->mcg_table.mutex);
   1640
   1641	return 0;
   1642}
   1643
   1644void mlx4_cleanup_mcg_table(struct mlx4_dev *dev)
   1645{
   1646	if (dev->caps.steering_mode !=
   1647	    MLX4_STEERING_MODE_DEVICE_MANAGED)
   1648		mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap);
   1649}