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

resource_tracker.c (136019B)


      1/*
      2 * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
      3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies.
      4 * All rights reserved.
      5 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc.  All rights reserved.
      6 *
      7 * This software is available to you under a choice of one of two
      8 * licenses.  You may choose to be licensed under the terms of the GNU
      9 * General Public License (GPL) Version 2, available from the file
     10 * COPYING in the main directory of this source tree, or the
     11 * OpenIB.org BSD license below:
     12 *
     13 *     Redistribution and use in source and binary forms, with or
     14 *     without modification, are permitted provided that the following
     15 *     conditions are met:
     16 *
     17 *      - Redistributions of source code must retain the above
     18 *        copyright notice, this list of conditions and the following
     19 *        disclaimer.
     20 *
     21 *      - Redistributions in binary form must reproduce the above
     22 *        copyright notice, this list of conditions and the following
     23 *        disclaimer in the documentation and/or other materials
     24 *        provided with the distribution.
     25 *
     26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     33 * SOFTWARE.
     34 */
     35
     36#include <linux/sched.h>
     37#include <linux/pci.h>
     38#include <linux/errno.h>
     39#include <linux/kernel.h>
     40#include <linux/io.h>
     41#include <linux/slab.h>
     42#include <linux/mlx4/cmd.h>
     43#include <linux/mlx4/qp.h>
     44#include <linux/if_ether.h>
     45#include <linux/etherdevice.h>
     46
     47#include "mlx4.h"
     48#include "fw.h"
     49#include "mlx4_stats.h"
     50
     51#define MLX4_MAC_VALID		(1ull << 63)
     52#define MLX4_PF_COUNTERS_PER_PORT	2
     53#define MLX4_VF_COUNTERS_PER_PORT	1
     54
     55struct mac_res {
     56	struct list_head list;
     57	u64 mac;
     58	int ref_count;
     59	u8 smac_index;
     60	u8 port;
     61};
     62
     63struct vlan_res {
     64	struct list_head list;
     65	u16 vlan;
     66	int ref_count;
     67	int vlan_index;
     68	u8 port;
     69};
     70
     71struct res_common {
     72	struct list_head	list;
     73	struct rb_node		node;
     74	u64		        res_id;
     75	int			owner;
     76	int			state;
     77	int			from_state;
     78	int			to_state;
     79	int			removing;
     80	const char		*func_name;
     81};
     82
     83enum {
     84	RES_ANY_BUSY = 1
     85};
     86
     87struct res_gid {
     88	struct list_head	list;
     89	u8			gid[16];
     90	enum mlx4_protocol	prot;
     91	enum mlx4_steer_type	steer;
     92	u64			reg_id;
     93};
     94
     95enum res_qp_states {
     96	RES_QP_BUSY = RES_ANY_BUSY,
     97
     98	/* QP number was allocated */
     99	RES_QP_RESERVED,
    100
    101	/* ICM memory for QP context was mapped */
    102	RES_QP_MAPPED,
    103
    104	/* QP is in hw ownership */
    105	RES_QP_HW
    106};
    107
    108struct res_qp {
    109	struct res_common	com;
    110	struct res_mtt	       *mtt;
    111	struct res_cq	       *rcq;
    112	struct res_cq	       *scq;
    113	struct res_srq	       *srq;
    114	struct list_head	mcg_list;
    115	spinlock_t		mcg_spl;
    116	int			local_qpn;
    117	atomic_t		ref_count;
    118	u32			qpc_flags;
    119	/* saved qp params before VST enforcement in order to restore on VGT */
    120	u8			sched_queue;
    121	__be32			param3;
    122	u8			vlan_control;
    123	u8			fvl_rx;
    124	u8			pri_path_fl;
    125	u8			vlan_index;
    126	u8			feup;
    127};
    128
    129enum res_mtt_states {
    130	RES_MTT_BUSY = RES_ANY_BUSY,
    131	RES_MTT_ALLOCATED,
    132};
    133
    134static inline const char *mtt_states_str(enum res_mtt_states state)
    135{
    136	switch (state) {
    137	case RES_MTT_BUSY: return "RES_MTT_BUSY";
    138	case RES_MTT_ALLOCATED: return "RES_MTT_ALLOCATED";
    139	default: return "Unknown";
    140	}
    141}
    142
    143struct res_mtt {
    144	struct res_common	com;
    145	int			order;
    146	atomic_t		ref_count;
    147};
    148
    149enum res_mpt_states {
    150	RES_MPT_BUSY = RES_ANY_BUSY,
    151	RES_MPT_RESERVED,
    152	RES_MPT_MAPPED,
    153	RES_MPT_HW,
    154};
    155
    156struct res_mpt {
    157	struct res_common	com;
    158	struct res_mtt	       *mtt;
    159	int			key;
    160};
    161
    162enum res_eq_states {
    163	RES_EQ_BUSY = RES_ANY_BUSY,
    164	RES_EQ_RESERVED,
    165	RES_EQ_HW,
    166};
    167
    168struct res_eq {
    169	struct res_common	com;
    170	struct res_mtt	       *mtt;
    171};
    172
    173enum res_cq_states {
    174	RES_CQ_BUSY = RES_ANY_BUSY,
    175	RES_CQ_ALLOCATED,
    176	RES_CQ_HW,
    177};
    178
    179struct res_cq {
    180	struct res_common	com;
    181	struct res_mtt	       *mtt;
    182	atomic_t		ref_count;
    183};
    184
    185enum res_srq_states {
    186	RES_SRQ_BUSY = RES_ANY_BUSY,
    187	RES_SRQ_ALLOCATED,
    188	RES_SRQ_HW,
    189};
    190
    191struct res_srq {
    192	struct res_common	com;
    193	struct res_mtt	       *mtt;
    194	struct res_cq	       *cq;
    195	atomic_t		ref_count;
    196};
    197
    198enum res_counter_states {
    199	RES_COUNTER_BUSY = RES_ANY_BUSY,
    200	RES_COUNTER_ALLOCATED,
    201};
    202
    203struct res_counter {
    204	struct res_common	com;
    205	int			port;
    206};
    207
    208enum res_xrcdn_states {
    209	RES_XRCD_BUSY = RES_ANY_BUSY,
    210	RES_XRCD_ALLOCATED,
    211};
    212
    213struct res_xrcdn {
    214	struct res_common	com;
    215	int			port;
    216};
    217
    218enum res_fs_rule_states {
    219	RES_FS_RULE_BUSY = RES_ANY_BUSY,
    220	RES_FS_RULE_ALLOCATED,
    221};
    222
    223struct res_fs_rule {
    224	struct res_common	com;
    225	int			qpn;
    226	/* VF DMFS mbox with port flipped */
    227	void			*mirr_mbox;
    228	/* > 0 --> apply mirror when getting into HA mode      */
    229	/* = 0 --> un-apply mirror when getting out of HA mode */
    230	u32			mirr_mbox_size;
    231	struct list_head	mirr_list;
    232	u64			mirr_rule_id;
    233};
    234
    235static void *res_tracker_lookup(struct rb_root *root, u64 res_id)
    236{
    237	struct rb_node *node = root->rb_node;
    238
    239	while (node) {
    240		struct res_common *res = rb_entry(node, struct res_common,
    241						  node);
    242
    243		if (res_id < res->res_id)
    244			node = node->rb_left;
    245		else if (res_id > res->res_id)
    246			node = node->rb_right;
    247		else
    248			return res;
    249	}
    250	return NULL;
    251}
    252
    253static int res_tracker_insert(struct rb_root *root, struct res_common *res)
    254{
    255	struct rb_node **new = &(root->rb_node), *parent = NULL;
    256
    257	/* Figure out where to put new node */
    258	while (*new) {
    259		struct res_common *this = rb_entry(*new, struct res_common,
    260						   node);
    261
    262		parent = *new;
    263		if (res->res_id < this->res_id)
    264			new = &((*new)->rb_left);
    265		else if (res->res_id > this->res_id)
    266			new = &((*new)->rb_right);
    267		else
    268			return -EEXIST;
    269	}
    270
    271	/* Add new node and rebalance tree. */
    272	rb_link_node(&res->node, parent, new);
    273	rb_insert_color(&res->node, root);
    274
    275	return 0;
    276}
    277
    278enum qp_transition {
    279	QP_TRANS_INIT2RTR,
    280	QP_TRANS_RTR2RTS,
    281	QP_TRANS_RTS2RTS,
    282	QP_TRANS_SQERR2RTS,
    283	QP_TRANS_SQD2SQD,
    284	QP_TRANS_SQD2RTS
    285};
    286
    287/* For Debug uses */
    288static const char *resource_str(enum mlx4_resource rt)
    289{
    290	switch (rt) {
    291	case RES_QP: return "RES_QP";
    292	case RES_CQ: return "RES_CQ";
    293	case RES_SRQ: return "RES_SRQ";
    294	case RES_MPT: return "RES_MPT";
    295	case RES_MTT: return "RES_MTT";
    296	case RES_MAC: return  "RES_MAC";
    297	case RES_VLAN: return  "RES_VLAN";
    298	case RES_EQ: return "RES_EQ";
    299	case RES_COUNTER: return "RES_COUNTER";
    300	case RES_FS_RULE: return "RES_FS_RULE";
    301	case RES_XRCD: return "RES_XRCD";
    302	default: return "Unknown resource type !!!";
    303	}
    304}
    305
    306static void rem_slave_vlans(struct mlx4_dev *dev, int slave);
    307static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
    308				      enum mlx4_resource res_type, int count,
    309				      int port)
    310{
    311	struct mlx4_priv *priv = mlx4_priv(dev);
    312	struct resource_allocator *res_alloc =
    313		&priv->mfunc.master.res_tracker.res_alloc[res_type];
    314	int err = -EDQUOT;
    315	int allocated, free, reserved, guaranteed, from_free;
    316	int from_rsvd;
    317
    318	if (slave > dev->persist->num_vfs)
    319		return -EINVAL;
    320
    321	spin_lock(&res_alloc->alloc_lock);
    322	allocated = (port > 0) ?
    323		res_alloc->allocated[(port - 1) *
    324		(dev->persist->num_vfs + 1) + slave] :
    325		res_alloc->allocated[slave];
    326	free = (port > 0) ? res_alloc->res_port_free[port - 1] :
    327		res_alloc->res_free;
    328	reserved = (port > 0) ? res_alloc->res_port_rsvd[port - 1] :
    329		res_alloc->res_reserved;
    330	guaranteed = res_alloc->guaranteed[slave];
    331
    332	if (allocated + count > res_alloc->quota[slave]) {
    333		mlx4_warn(dev, "VF %d port %d res %s: quota exceeded, count %d alloc %d quota %d\n",
    334			  slave, port, resource_str(res_type), count,
    335			  allocated, res_alloc->quota[slave]);
    336		goto out;
    337	}
    338
    339	if (allocated + count <= guaranteed) {
    340		err = 0;
    341		from_rsvd = count;
    342	} else {
    343		/* portion may need to be obtained from free area */
    344		if (guaranteed - allocated > 0)
    345			from_free = count - (guaranteed - allocated);
    346		else
    347			from_free = count;
    348
    349		from_rsvd = count - from_free;
    350
    351		if (free - from_free >= reserved)
    352			err = 0;
    353		else
    354			mlx4_warn(dev, "VF %d port %d res %s: free pool empty, free %d from_free %d rsvd %d\n",
    355				  slave, port, resource_str(res_type), free,
    356				  from_free, reserved);
    357	}
    358
    359	if (!err) {
    360		/* grant the request */
    361		if (port > 0) {
    362			res_alloc->allocated[(port - 1) *
    363			(dev->persist->num_vfs + 1) + slave] += count;
    364			res_alloc->res_port_free[port - 1] -= count;
    365			res_alloc->res_port_rsvd[port - 1] -= from_rsvd;
    366		} else {
    367			res_alloc->allocated[slave] += count;
    368			res_alloc->res_free -= count;
    369			res_alloc->res_reserved -= from_rsvd;
    370		}
    371	}
    372
    373out:
    374	spin_unlock(&res_alloc->alloc_lock);
    375	return err;
    376}
    377
    378static inline void mlx4_release_resource(struct mlx4_dev *dev, int slave,
    379				    enum mlx4_resource res_type, int count,
    380				    int port)
    381{
    382	struct mlx4_priv *priv = mlx4_priv(dev);
    383	struct resource_allocator *res_alloc =
    384		&priv->mfunc.master.res_tracker.res_alloc[res_type];
    385	int allocated, guaranteed, from_rsvd;
    386
    387	if (slave > dev->persist->num_vfs)
    388		return;
    389
    390	spin_lock(&res_alloc->alloc_lock);
    391
    392	allocated = (port > 0) ?
    393		res_alloc->allocated[(port - 1) *
    394		(dev->persist->num_vfs + 1) + slave] :
    395		res_alloc->allocated[slave];
    396	guaranteed = res_alloc->guaranteed[slave];
    397
    398	if (allocated - count >= guaranteed) {
    399		from_rsvd = 0;
    400	} else {
    401		/* portion may need to be returned to reserved area */
    402		if (allocated - guaranteed > 0)
    403			from_rsvd = count - (allocated - guaranteed);
    404		else
    405			from_rsvd = count;
    406	}
    407
    408	if (port > 0) {
    409		res_alloc->allocated[(port - 1) *
    410		(dev->persist->num_vfs + 1) + slave] -= count;
    411		res_alloc->res_port_free[port - 1] += count;
    412		res_alloc->res_port_rsvd[port - 1] += from_rsvd;
    413	} else {
    414		res_alloc->allocated[slave] -= count;
    415		res_alloc->res_free += count;
    416		res_alloc->res_reserved += from_rsvd;
    417	}
    418
    419	spin_unlock(&res_alloc->alloc_lock);
    420	return;
    421}
    422
    423static inline void initialize_res_quotas(struct mlx4_dev *dev,
    424					 struct resource_allocator *res_alloc,
    425					 enum mlx4_resource res_type,
    426					 int vf, int num_instances)
    427{
    428	res_alloc->guaranteed[vf] = num_instances /
    429				    (2 * (dev->persist->num_vfs + 1));
    430	res_alloc->quota[vf] = (num_instances / 2) + res_alloc->guaranteed[vf];
    431	if (vf == mlx4_master_func_num(dev)) {
    432		res_alloc->res_free = num_instances;
    433		if (res_type == RES_MTT) {
    434			/* reserved mtts will be taken out of the PF allocation */
    435			res_alloc->res_free += dev->caps.reserved_mtts;
    436			res_alloc->guaranteed[vf] += dev->caps.reserved_mtts;
    437			res_alloc->quota[vf] += dev->caps.reserved_mtts;
    438		}
    439	}
    440}
    441
    442void mlx4_init_quotas(struct mlx4_dev *dev)
    443{
    444	struct mlx4_priv *priv = mlx4_priv(dev);
    445	int pf;
    446
    447	/* quotas for VFs are initialized in mlx4_slave_cap */
    448	if (mlx4_is_slave(dev))
    449		return;
    450
    451	if (!mlx4_is_mfunc(dev)) {
    452		dev->quotas.qp = dev->caps.num_qps - dev->caps.reserved_qps -
    453			mlx4_num_reserved_sqps(dev);
    454		dev->quotas.cq = dev->caps.num_cqs - dev->caps.reserved_cqs;
    455		dev->quotas.srq = dev->caps.num_srqs - dev->caps.reserved_srqs;
    456		dev->quotas.mtt = dev->caps.num_mtts - dev->caps.reserved_mtts;
    457		dev->quotas.mpt = dev->caps.num_mpts - dev->caps.reserved_mrws;
    458		return;
    459	}
    460
    461	pf = mlx4_master_func_num(dev);
    462	dev->quotas.qp =
    463		priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[pf];
    464	dev->quotas.cq =
    465		priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[pf];
    466	dev->quotas.srq =
    467		priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[pf];
    468	dev->quotas.mtt =
    469		priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[pf];
    470	dev->quotas.mpt =
    471		priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf];
    472}
    473
    474static int
    475mlx4_calc_res_counter_guaranteed(struct mlx4_dev *dev,
    476				 struct resource_allocator *res_alloc,
    477				 int vf)
    478{
    479	struct mlx4_active_ports actv_ports;
    480	int ports, counters_guaranteed;
    481
    482	/* For master, only allocate according to the number of phys ports */
    483	if (vf == mlx4_master_func_num(dev))
    484		return MLX4_PF_COUNTERS_PER_PORT * dev->caps.num_ports;
    485
    486	/* calculate real number of ports for the VF */
    487	actv_ports = mlx4_get_active_ports(dev, vf);
    488	ports = bitmap_weight(actv_ports.ports, dev->caps.num_ports);
    489	counters_guaranteed = ports * MLX4_VF_COUNTERS_PER_PORT;
    490
    491	/* If we do not have enough counters for this VF, do not
    492	 * allocate any for it. '-1' to reduce the sink counter.
    493	 */
    494	if ((res_alloc->res_reserved + counters_guaranteed) >
    495	    (dev->caps.max_counters - 1))
    496		return 0;
    497
    498	return counters_guaranteed;
    499}
    500
    501int mlx4_init_resource_tracker(struct mlx4_dev *dev)
    502{
    503	struct mlx4_priv *priv = mlx4_priv(dev);
    504	int i, j;
    505	int t;
    506
    507	priv->mfunc.master.res_tracker.slave_list =
    508		kcalloc(dev->num_slaves, sizeof(struct slave_list),
    509			GFP_KERNEL);
    510	if (!priv->mfunc.master.res_tracker.slave_list)
    511		return -ENOMEM;
    512
    513	for (i = 0 ; i < dev->num_slaves; i++) {
    514		for (t = 0; t < MLX4_NUM_OF_RESOURCE_TYPE; ++t)
    515			INIT_LIST_HEAD(&priv->mfunc.master.res_tracker.
    516				       slave_list[i].res_list[t]);
    517		mutex_init(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
    518	}
    519
    520	mlx4_dbg(dev, "Started init_resource_tracker: %ld slaves\n",
    521		 dev->num_slaves);
    522	for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++)
    523		priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT;
    524
    525	for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
    526		struct resource_allocator *res_alloc =
    527			&priv->mfunc.master.res_tracker.res_alloc[i];
    528		res_alloc->quota = kmalloc_array(dev->persist->num_vfs + 1,
    529						 sizeof(int),
    530						 GFP_KERNEL);
    531		res_alloc->guaranteed = kmalloc_array(dev->persist->num_vfs + 1,
    532						      sizeof(int),
    533						      GFP_KERNEL);
    534		if (i == RES_MAC || i == RES_VLAN)
    535			res_alloc->allocated =
    536				kcalloc(MLX4_MAX_PORTS *
    537						(dev->persist->num_vfs + 1),
    538					sizeof(int), GFP_KERNEL);
    539		else
    540			res_alloc->allocated =
    541				kcalloc(dev->persist->num_vfs + 1,
    542					sizeof(int), GFP_KERNEL);
    543		/* Reduce the sink counter */
    544		if (i == RES_COUNTER)
    545			res_alloc->res_free = dev->caps.max_counters - 1;
    546
    547		if (!res_alloc->quota || !res_alloc->guaranteed ||
    548		    !res_alloc->allocated)
    549			goto no_mem_err;
    550
    551		spin_lock_init(&res_alloc->alloc_lock);
    552		for (t = 0; t < dev->persist->num_vfs + 1; t++) {
    553			struct mlx4_active_ports actv_ports =
    554				mlx4_get_active_ports(dev, t);
    555			switch (i) {
    556			case RES_QP:
    557				initialize_res_quotas(dev, res_alloc, RES_QP,
    558						      t, dev->caps.num_qps -
    559						      dev->caps.reserved_qps -
    560						      mlx4_num_reserved_sqps(dev));
    561				break;
    562			case RES_CQ:
    563				initialize_res_quotas(dev, res_alloc, RES_CQ,
    564						      t, dev->caps.num_cqs -
    565						      dev->caps.reserved_cqs);
    566				break;
    567			case RES_SRQ:
    568				initialize_res_quotas(dev, res_alloc, RES_SRQ,
    569						      t, dev->caps.num_srqs -
    570						      dev->caps.reserved_srqs);
    571				break;
    572			case RES_MPT:
    573				initialize_res_quotas(dev, res_alloc, RES_MPT,
    574						      t, dev->caps.num_mpts -
    575						      dev->caps.reserved_mrws);
    576				break;
    577			case RES_MTT:
    578				initialize_res_quotas(dev, res_alloc, RES_MTT,
    579						      t, dev->caps.num_mtts -
    580						      dev->caps.reserved_mtts);
    581				break;
    582			case RES_MAC:
    583				if (t == mlx4_master_func_num(dev)) {
    584					int max_vfs_pport = 0;
    585					/* Calculate the max vfs per port for */
    586					/* both ports.			      */
    587					for (j = 0; j < dev->caps.num_ports;
    588					     j++) {
    589						struct mlx4_slaves_pport slaves_pport =
    590							mlx4_phys_to_slaves_pport(dev, j + 1);
    591						unsigned current_slaves =
    592							bitmap_weight(slaves_pport.slaves,
    593								      dev->caps.num_ports) - 1;
    594						if (max_vfs_pport < current_slaves)
    595							max_vfs_pport =
    596								current_slaves;
    597					}
    598					res_alloc->quota[t] =
    599						MLX4_MAX_MAC_NUM -
    600						2 * max_vfs_pport;
    601					res_alloc->guaranteed[t] = 2;
    602					for (j = 0; j < MLX4_MAX_PORTS; j++)
    603						res_alloc->res_port_free[j] =
    604							MLX4_MAX_MAC_NUM;
    605				} else {
    606					res_alloc->quota[t] = MLX4_MAX_MAC_NUM;
    607					res_alloc->guaranteed[t] = 2;
    608				}
    609				break;
    610			case RES_VLAN:
    611				if (t == mlx4_master_func_num(dev)) {
    612					res_alloc->quota[t] = MLX4_MAX_VLAN_NUM;
    613					res_alloc->guaranteed[t] = MLX4_MAX_VLAN_NUM / 2;
    614					for (j = 0; j < MLX4_MAX_PORTS; j++)
    615						res_alloc->res_port_free[j] =
    616							res_alloc->quota[t];
    617				} else {
    618					res_alloc->quota[t] = MLX4_MAX_VLAN_NUM / 2;
    619					res_alloc->guaranteed[t] = 0;
    620				}
    621				break;
    622			case RES_COUNTER:
    623				res_alloc->quota[t] = dev->caps.max_counters;
    624				res_alloc->guaranteed[t] =
    625					mlx4_calc_res_counter_guaranteed(dev, res_alloc, t);
    626				break;
    627			default:
    628				break;
    629			}
    630			if (i == RES_MAC || i == RES_VLAN) {
    631				for (j = 0; j < dev->caps.num_ports; j++)
    632					if (test_bit(j, actv_ports.ports))
    633						res_alloc->res_port_rsvd[j] +=
    634							res_alloc->guaranteed[t];
    635			} else {
    636				res_alloc->res_reserved += res_alloc->guaranteed[t];
    637			}
    638		}
    639	}
    640	spin_lock_init(&priv->mfunc.master.res_tracker.lock);
    641	return 0;
    642
    643no_mem_err:
    644	for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
    645		kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
    646		priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
    647		kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
    648		priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
    649		kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
    650		priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
    651	}
    652	return -ENOMEM;
    653}
    654
    655void mlx4_free_resource_tracker(struct mlx4_dev *dev,
    656				enum mlx4_res_tracker_free_type type)
    657{
    658	struct mlx4_priv *priv = mlx4_priv(dev);
    659	int i;
    660
    661	if (priv->mfunc.master.res_tracker.slave_list) {
    662		if (type != RES_TR_FREE_STRUCTS_ONLY) {
    663			for (i = 0; i < dev->num_slaves; i++) {
    664				if (type == RES_TR_FREE_ALL ||
    665				    dev->caps.function != i)
    666					mlx4_delete_all_resources_for_slave(dev, i);
    667			}
    668			/* free master's vlans */
    669			i = dev->caps.function;
    670			mlx4_reset_roce_gids(dev, i);
    671			mutex_lock(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
    672			rem_slave_vlans(dev, i);
    673			mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
    674		}
    675
    676		if (type != RES_TR_FREE_SLAVES_ONLY) {
    677			for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
    678				kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
    679				priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
    680				kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
    681				priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
    682				kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
    683				priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
    684			}
    685			kfree(priv->mfunc.master.res_tracker.slave_list);
    686			priv->mfunc.master.res_tracker.slave_list = NULL;
    687		}
    688	}
    689}
    690
    691static void update_pkey_index(struct mlx4_dev *dev, int slave,
    692			      struct mlx4_cmd_mailbox *inbox)
    693{
    694	u8 sched = *(u8 *)(inbox->buf + 64);
    695	u8 orig_index = *(u8 *)(inbox->buf + 35);
    696	u8 new_index;
    697	struct mlx4_priv *priv = mlx4_priv(dev);
    698	int port;
    699
    700	port = (sched >> 6 & 1) + 1;
    701
    702	new_index = priv->virt2phys_pkey[slave][port - 1][orig_index];
    703	*(u8 *)(inbox->buf + 35) = new_index;
    704}
    705
    706static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox,
    707		       u8 slave)
    708{
    709	struct mlx4_qp_context	*qp_ctx = inbox->buf + 8;
    710	enum mlx4_qp_optpar	optpar = be32_to_cpu(*(__be32 *) inbox->buf);
    711	u32			ts = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
    712	int port;
    713
    714	if (MLX4_QP_ST_UD == ts) {
    715		port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
    716		if (mlx4_is_eth(dev, port))
    717			qp_ctx->pri_path.mgid_index =
    718				mlx4_get_base_gid_ix(dev, slave, port) | 0x80;
    719		else
    720			qp_ctx->pri_path.mgid_index = slave | 0x80;
    721
    722	} else if (MLX4_QP_ST_RC == ts || MLX4_QP_ST_XRC == ts || MLX4_QP_ST_UC == ts) {
    723		if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) {
    724			port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
    725			if (mlx4_is_eth(dev, port)) {
    726				qp_ctx->pri_path.mgid_index +=
    727					mlx4_get_base_gid_ix(dev, slave, port);
    728				qp_ctx->pri_path.mgid_index &= 0x7f;
    729			} else {
    730				qp_ctx->pri_path.mgid_index = slave & 0x7F;
    731			}
    732		}
    733		if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
    734			port = (qp_ctx->alt_path.sched_queue >> 6 & 1) + 1;
    735			if (mlx4_is_eth(dev, port)) {
    736				qp_ctx->alt_path.mgid_index +=
    737					mlx4_get_base_gid_ix(dev, slave, port);
    738				qp_ctx->alt_path.mgid_index &= 0x7f;
    739			} else {
    740				qp_ctx->alt_path.mgid_index = slave & 0x7F;
    741			}
    742		}
    743	}
    744}
    745
    746static int handle_counter(struct mlx4_dev *dev, struct mlx4_qp_context *qpc,
    747			  u8 slave, int port);
    748
    749static int update_vport_qp_param(struct mlx4_dev *dev,
    750				 struct mlx4_cmd_mailbox *inbox,
    751				 u8 slave, u32 qpn)
    752{
    753	struct mlx4_qp_context	*qpc = inbox->buf + 8;
    754	struct mlx4_vport_oper_state *vp_oper;
    755	struct mlx4_priv *priv;
    756	u32 qp_type;
    757	int port, err = 0;
    758
    759	port = (qpc->pri_path.sched_queue & 0x40) ? 2 : 1;
    760	priv = mlx4_priv(dev);
    761	vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
    762	qp_type	= (be32_to_cpu(qpc->flags) >> 16) & 0xff;
    763
    764	err = handle_counter(dev, qpc, slave, port);
    765	if (err)
    766		goto out;
    767
    768	if (MLX4_VGT != vp_oper->state.default_vlan) {
    769		/* the reserved QPs (special, proxy, tunnel)
    770		 * do not operate over vlans
    771		 */
    772		if (mlx4_is_qp_reserved(dev, qpn))
    773			return 0;
    774
    775		/* force strip vlan by clear vsd, MLX QP refers to Raw Ethernet */
    776		if (qp_type == MLX4_QP_ST_UD ||
    777		    (qp_type == MLX4_QP_ST_MLX && mlx4_is_eth(dev, port))) {
    778			if (dev->caps.bmme_flags & MLX4_BMME_FLAG_VSD_INIT2RTR) {
    779				*(__be32 *)inbox->buf =
    780					cpu_to_be32(be32_to_cpu(*(__be32 *)inbox->buf) |
    781					MLX4_QP_OPTPAR_VLAN_STRIPPING);
    782				qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN);
    783			} else {
    784				struct mlx4_update_qp_params params = {.flags = 0};
    785
    786				err = mlx4_update_qp(dev, qpn, MLX4_UPDATE_QP_VSD, &params);
    787				if (err)
    788					goto out;
    789			}
    790		}
    791
    792		/* preserve IF_COUNTER flag */
    793		qpc->pri_path.vlan_control &=
    794			MLX4_CTRL_ETH_SRC_CHECK_IF_COUNTER;
    795		if (vp_oper->state.link_state == IFLA_VF_LINK_STATE_DISABLE &&
    796		    dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP) {
    797			qpc->pri_path.vlan_control |=
    798				MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
    799				MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
    800				MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED |
    801				MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
    802				MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED |
    803				MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
    804		} else if (0 != vp_oper->state.default_vlan) {
    805			if (vp_oper->state.vlan_proto == htons(ETH_P_8021AD)) {
    806				/* vst QinQ should block untagged on TX,
    807				 * but cvlan is in payload and phv is set so
    808				 * hw see it as untagged. Block tagged instead.
    809				 */
    810				qpc->pri_path.vlan_control |=
    811					MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
    812					MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
    813					MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
    814					MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
    815			} else { /* vst 802.1Q */
    816				qpc->pri_path.vlan_control |=
    817					MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
    818					MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
    819					MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
    820			}
    821		} else { /* priority tagged */
    822			qpc->pri_path.vlan_control |=
    823				MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
    824				MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
    825		}
    826
    827		qpc->pri_path.fvl_rx |= MLX4_FVL_RX_FORCE_ETH_VLAN;
    828		qpc->pri_path.vlan_index = vp_oper->vlan_idx;
    829		qpc->pri_path.fl |= MLX4_FL_ETH_HIDE_CQE_VLAN;
    830		if (vp_oper->state.vlan_proto == htons(ETH_P_8021AD))
    831			qpc->pri_path.fl |= MLX4_FL_SV;
    832		else
    833			qpc->pri_path.fl |= MLX4_FL_CV;
    834		qpc->pri_path.feup |= MLX4_FEUP_FORCE_ETH_UP | MLX4_FVL_FORCE_ETH_VLAN;
    835		qpc->pri_path.sched_queue &= 0xC7;
    836		qpc->pri_path.sched_queue |= (vp_oper->state.default_qos) << 3;
    837		qpc->qos_vport = vp_oper->state.qos_vport;
    838	}
    839	if (vp_oper->state.spoofchk) {
    840		qpc->pri_path.feup |= MLX4_FSM_FORCE_ETH_SRC_MAC;
    841		qpc->pri_path.grh_mylmc = (0x80 & qpc->pri_path.grh_mylmc) + vp_oper->mac_idx;
    842	}
    843out:
    844	return err;
    845}
    846
    847static int mpt_mask(struct mlx4_dev *dev)
    848{
    849	return dev->caps.num_mpts - 1;
    850}
    851
    852static const char *mlx4_resource_type_to_str(enum mlx4_resource t)
    853{
    854	switch (t) {
    855	case RES_QP:
    856		return "QP";
    857	case RES_CQ:
    858		return "CQ";
    859	case RES_SRQ:
    860		return "SRQ";
    861	case RES_XRCD:
    862		return "XRCD";
    863	case RES_MPT:
    864		return "MPT";
    865	case RES_MTT:
    866		return "MTT";
    867	case RES_MAC:
    868		return "MAC";
    869	case RES_VLAN:
    870		return "VLAN";
    871	case RES_COUNTER:
    872		return "COUNTER";
    873	case RES_FS_RULE:
    874		return "FS_RULE";
    875	case RES_EQ:
    876		return "EQ";
    877	default:
    878		return "INVALID RESOURCE";
    879	}
    880}
    881
    882static void *find_res(struct mlx4_dev *dev, u64 res_id,
    883		      enum mlx4_resource type)
    884{
    885	struct mlx4_priv *priv = mlx4_priv(dev);
    886
    887	return res_tracker_lookup(&priv->mfunc.master.res_tracker.res_tree[type],
    888				  res_id);
    889}
    890
    891static int _get_res(struct mlx4_dev *dev, int slave, u64 res_id,
    892		    enum mlx4_resource type,
    893		    void *res, const char *func_name)
    894{
    895	struct res_common *r;
    896	int err = 0;
    897
    898	spin_lock_irq(mlx4_tlock(dev));
    899	r = find_res(dev, res_id, type);
    900	if (!r) {
    901		err = -ENONET;
    902		goto exit;
    903	}
    904
    905	if (r->state == RES_ANY_BUSY) {
    906		mlx4_warn(dev,
    907			  "%s(%d) trying to get resource %llx of type %s, but it's already taken by %s\n",
    908			  func_name, slave, res_id, mlx4_resource_type_to_str(type),
    909			  r->func_name);
    910		err = -EBUSY;
    911		goto exit;
    912	}
    913
    914	if (r->owner != slave) {
    915		err = -EPERM;
    916		goto exit;
    917	}
    918
    919	r->from_state = r->state;
    920	r->state = RES_ANY_BUSY;
    921	r->func_name = func_name;
    922
    923	if (res)
    924		*((struct res_common **)res) = r;
    925
    926exit:
    927	spin_unlock_irq(mlx4_tlock(dev));
    928	return err;
    929}
    930
    931#define get_res(dev, slave, res_id, type, res) \
    932	_get_res((dev), (slave), (res_id), (type), (res), __func__)
    933
    934int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev,
    935				    enum mlx4_resource type,
    936				    u64 res_id, int *slave)
    937{
    938
    939	struct res_common *r;
    940	int err = -ENOENT;
    941	int id = res_id;
    942
    943	if (type == RES_QP)
    944		id &= 0x7fffff;
    945	spin_lock(mlx4_tlock(dev));
    946
    947	r = find_res(dev, id, type);
    948	if (r) {
    949		*slave = r->owner;
    950		err = 0;
    951	}
    952	spin_unlock(mlx4_tlock(dev));
    953
    954	return err;
    955}
    956
    957static void put_res(struct mlx4_dev *dev, int slave, u64 res_id,
    958		    enum mlx4_resource type)
    959{
    960	struct res_common *r;
    961
    962	spin_lock_irq(mlx4_tlock(dev));
    963	r = find_res(dev, res_id, type);
    964	if (r) {
    965		r->state = r->from_state;
    966		r->func_name = "";
    967	}
    968	spin_unlock_irq(mlx4_tlock(dev));
    969}
    970
    971static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
    972			     u64 in_param, u64 *out_param, int port);
    973
    974static int handle_existing_counter(struct mlx4_dev *dev, u8 slave, int port,
    975				   int counter_index)
    976{
    977	struct res_common *r;
    978	struct res_counter *counter;
    979	int ret = 0;
    980
    981	if (counter_index == MLX4_SINK_COUNTER_INDEX(dev))
    982		return ret;
    983
    984	spin_lock_irq(mlx4_tlock(dev));
    985	r = find_res(dev, counter_index, RES_COUNTER);
    986	if (!r || r->owner != slave) {
    987		ret = -EINVAL;
    988	} else {
    989		counter = container_of(r, struct res_counter, com);
    990		if (!counter->port)
    991			counter->port = port;
    992	}
    993
    994	spin_unlock_irq(mlx4_tlock(dev));
    995	return ret;
    996}
    997
    998static int handle_unexisting_counter(struct mlx4_dev *dev,
    999				     struct mlx4_qp_context *qpc, u8 slave,
   1000				     int port)
   1001{
   1002	struct mlx4_priv *priv = mlx4_priv(dev);
   1003	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1004	struct res_common *tmp;
   1005	struct res_counter *counter;
   1006	u64 counter_idx = MLX4_SINK_COUNTER_INDEX(dev);
   1007	int err = 0;
   1008
   1009	spin_lock_irq(mlx4_tlock(dev));
   1010	list_for_each_entry(tmp,
   1011			    &tracker->slave_list[slave].res_list[RES_COUNTER],
   1012			    list) {
   1013		counter = container_of(tmp, struct res_counter, com);
   1014		if (port == counter->port) {
   1015			qpc->pri_path.counter_index  = counter->com.res_id;
   1016			spin_unlock_irq(mlx4_tlock(dev));
   1017			return 0;
   1018		}
   1019	}
   1020	spin_unlock_irq(mlx4_tlock(dev));
   1021
   1022	/* No existing counter, need to allocate a new counter */
   1023	err = counter_alloc_res(dev, slave, RES_OP_RESERVE, 0, 0, &counter_idx,
   1024				port);
   1025	if (err == -ENOENT) {
   1026		err = 0;
   1027	} else if (err && err != -ENOSPC) {
   1028		mlx4_err(dev, "%s: failed to create new counter for slave %d err %d\n",
   1029			 __func__, slave, err);
   1030	} else {
   1031		qpc->pri_path.counter_index = counter_idx;
   1032		mlx4_dbg(dev, "%s: alloc new counter for slave %d index %d\n",
   1033			 __func__, slave, qpc->pri_path.counter_index);
   1034		err = 0;
   1035	}
   1036
   1037	return err;
   1038}
   1039
   1040static int handle_counter(struct mlx4_dev *dev, struct mlx4_qp_context *qpc,
   1041			  u8 slave, int port)
   1042{
   1043	if (qpc->pri_path.counter_index != MLX4_SINK_COUNTER_INDEX(dev))
   1044		return handle_existing_counter(dev, slave, port,
   1045					       qpc->pri_path.counter_index);
   1046
   1047	return handle_unexisting_counter(dev, qpc, slave, port);
   1048}
   1049
   1050static struct res_common *alloc_qp_tr(int id)
   1051{
   1052	struct res_qp *ret;
   1053
   1054	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1055	if (!ret)
   1056		return NULL;
   1057
   1058	ret->com.res_id = id;
   1059	ret->com.state = RES_QP_RESERVED;
   1060	ret->local_qpn = id;
   1061	INIT_LIST_HEAD(&ret->mcg_list);
   1062	spin_lock_init(&ret->mcg_spl);
   1063	atomic_set(&ret->ref_count, 0);
   1064
   1065	return &ret->com;
   1066}
   1067
   1068static struct res_common *alloc_mtt_tr(int id, int order)
   1069{
   1070	struct res_mtt *ret;
   1071
   1072	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1073	if (!ret)
   1074		return NULL;
   1075
   1076	ret->com.res_id = id;
   1077	ret->order = order;
   1078	ret->com.state = RES_MTT_ALLOCATED;
   1079	atomic_set(&ret->ref_count, 0);
   1080
   1081	return &ret->com;
   1082}
   1083
   1084static struct res_common *alloc_mpt_tr(int id, int key)
   1085{
   1086	struct res_mpt *ret;
   1087
   1088	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1089	if (!ret)
   1090		return NULL;
   1091
   1092	ret->com.res_id = id;
   1093	ret->com.state = RES_MPT_RESERVED;
   1094	ret->key = key;
   1095
   1096	return &ret->com;
   1097}
   1098
   1099static struct res_common *alloc_eq_tr(int id)
   1100{
   1101	struct res_eq *ret;
   1102
   1103	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1104	if (!ret)
   1105		return NULL;
   1106
   1107	ret->com.res_id = id;
   1108	ret->com.state = RES_EQ_RESERVED;
   1109
   1110	return &ret->com;
   1111}
   1112
   1113static struct res_common *alloc_cq_tr(int id)
   1114{
   1115	struct res_cq *ret;
   1116
   1117	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1118	if (!ret)
   1119		return NULL;
   1120
   1121	ret->com.res_id = id;
   1122	ret->com.state = RES_CQ_ALLOCATED;
   1123	atomic_set(&ret->ref_count, 0);
   1124
   1125	return &ret->com;
   1126}
   1127
   1128static struct res_common *alloc_srq_tr(int id)
   1129{
   1130	struct res_srq *ret;
   1131
   1132	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1133	if (!ret)
   1134		return NULL;
   1135
   1136	ret->com.res_id = id;
   1137	ret->com.state = RES_SRQ_ALLOCATED;
   1138	atomic_set(&ret->ref_count, 0);
   1139
   1140	return &ret->com;
   1141}
   1142
   1143static struct res_common *alloc_counter_tr(int id, int port)
   1144{
   1145	struct res_counter *ret;
   1146
   1147	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1148	if (!ret)
   1149		return NULL;
   1150
   1151	ret->com.res_id = id;
   1152	ret->com.state = RES_COUNTER_ALLOCATED;
   1153	ret->port = port;
   1154
   1155	return &ret->com;
   1156}
   1157
   1158static struct res_common *alloc_xrcdn_tr(int id)
   1159{
   1160	struct res_xrcdn *ret;
   1161
   1162	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1163	if (!ret)
   1164		return NULL;
   1165
   1166	ret->com.res_id = id;
   1167	ret->com.state = RES_XRCD_ALLOCATED;
   1168
   1169	return &ret->com;
   1170}
   1171
   1172static struct res_common *alloc_fs_rule_tr(u64 id, int qpn)
   1173{
   1174	struct res_fs_rule *ret;
   1175
   1176	ret = kzalloc(sizeof(*ret), GFP_KERNEL);
   1177	if (!ret)
   1178		return NULL;
   1179
   1180	ret->com.res_id = id;
   1181	ret->com.state = RES_FS_RULE_ALLOCATED;
   1182	ret->qpn = qpn;
   1183	return &ret->com;
   1184}
   1185
   1186static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
   1187				   int extra)
   1188{
   1189	struct res_common *ret;
   1190
   1191	switch (type) {
   1192	case RES_QP:
   1193		ret = alloc_qp_tr(id);
   1194		break;
   1195	case RES_MPT:
   1196		ret = alloc_mpt_tr(id, extra);
   1197		break;
   1198	case RES_MTT:
   1199		ret = alloc_mtt_tr(id, extra);
   1200		break;
   1201	case RES_EQ:
   1202		ret = alloc_eq_tr(id);
   1203		break;
   1204	case RES_CQ:
   1205		ret = alloc_cq_tr(id);
   1206		break;
   1207	case RES_SRQ:
   1208		ret = alloc_srq_tr(id);
   1209		break;
   1210	case RES_MAC:
   1211		pr_err("implementation missing\n");
   1212		return NULL;
   1213	case RES_COUNTER:
   1214		ret = alloc_counter_tr(id, extra);
   1215		break;
   1216	case RES_XRCD:
   1217		ret = alloc_xrcdn_tr(id);
   1218		break;
   1219	case RES_FS_RULE:
   1220		ret = alloc_fs_rule_tr(id, extra);
   1221		break;
   1222	default:
   1223		return NULL;
   1224	}
   1225	if (ret)
   1226		ret->owner = slave;
   1227
   1228	return ret;
   1229}
   1230
   1231int mlx4_calc_vf_counters(struct mlx4_dev *dev, int slave, int port,
   1232			  struct mlx4_counter *data)
   1233{
   1234	struct mlx4_priv *priv = mlx4_priv(dev);
   1235	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1236	struct res_common *tmp;
   1237	struct res_counter *counter;
   1238	int *counters_arr;
   1239	int i = 0, err = 0;
   1240
   1241	memset(data, 0, sizeof(*data));
   1242
   1243	counters_arr = kmalloc_array(dev->caps.max_counters,
   1244				     sizeof(*counters_arr), GFP_KERNEL);
   1245	if (!counters_arr)
   1246		return -ENOMEM;
   1247
   1248	spin_lock_irq(mlx4_tlock(dev));
   1249	list_for_each_entry(tmp,
   1250			    &tracker->slave_list[slave].res_list[RES_COUNTER],
   1251			    list) {
   1252		counter = container_of(tmp, struct res_counter, com);
   1253		if (counter->port == port) {
   1254			counters_arr[i] = (int)tmp->res_id;
   1255			i++;
   1256		}
   1257	}
   1258	spin_unlock_irq(mlx4_tlock(dev));
   1259	counters_arr[i] = -1;
   1260
   1261	i = 0;
   1262
   1263	while (counters_arr[i] != -1) {
   1264		err = mlx4_get_counter_stats(dev, counters_arr[i], data,
   1265					     0);
   1266		if (err) {
   1267			memset(data, 0, sizeof(*data));
   1268			goto table_changed;
   1269		}
   1270		i++;
   1271	}
   1272
   1273table_changed:
   1274	kfree(counters_arr);
   1275	return 0;
   1276}
   1277
   1278static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
   1279			 enum mlx4_resource type, int extra)
   1280{
   1281	int i;
   1282	int err;
   1283	struct mlx4_priv *priv = mlx4_priv(dev);
   1284	struct res_common **res_arr;
   1285	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1286	struct rb_root *root = &tracker->res_tree[type];
   1287
   1288	res_arr = kcalloc(count, sizeof(*res_arr), GFP_KERNEL);
   1289	if (!res_arr)
   1290		return -ENOMEM;
   1291
   1292	for (i = 0; i < count; ++i) {
   1293		res_arr[i] = alloc_tr(base + i, type, slave, extra);
   1294		if (!res_arr[i]) {
   1295			for (--i; i >= 0; --i)
   1296				kfree(res_arr[i]);
   1297
   1298			kfree(res_arr);
   1299			return -ENOMEM;
   1300		}
   1301	}
   1302
   1303	spin_lock_irq(mlx4_tlock(dev));
   1304	for (i = 0; i < count; ++i) {
   1305		if (find_res(dev, base + i, type)) {
   1306			err = -EEXIST;
   1307			goto undo;
   1308		}
   1309		err = res_tracker_insert(root, res_arr[i]);
   1310		if (err)
   1311			goto undo;
   1312		list_add_tail(&res_arr[i]->list,
   1313			      &tracker->slave_list[slave].res_list[type]);
   1314	}
   1315	spin_unlock_irq(mlx4_tlock(dev));
   1316	kfree(res_arr);
   1317
   1318	return 0;
   1319
   1320undo:
   1321	for (--i; i >= 0; --i) {
   1322		rb_erase(&res_arr[i]->node, root);
   1323		list_del_init(&res_arr[i]->list);
   1324	}
   1325
   1326	spin_unlock_irq(mlx4_tlock(dev));
   1327
   1328	for (i = 0; i < count; ++i)
   1329		kfree(res_arr[i]);
   1330
   1331	kfree(res_arr);
   1332
   1333	return err;
   1334}
   1335
   1336static int remove_qp_ok(struct res_qp *res)
   1337{
   1338	if (res->com.state == RES_QP_BUSY || atomic_read(&res->ref_count) ||
   1339	    !list_empty(&res->mcg_list)) {
   1340		pr_err("resource tracker: fail to remove qp, state %d, ref_count %d\n",
   1341		       res->com.state, atomic_read(&res->ref_count));
   1342		return -EBUSY;
   1343	} else if (res->com.state != RES_QP_RESERVED) {
   1344		return -EPERM;
   1345	}
   1346
   1347	return 0;
   1348}
   1349
   1350static int remove_mtt_ok(struct res_mtt *res, int order)
   1351{
   1352	if (res->com.state == RES_MTT_BUSY ||
   1353	    atomic_read(&res->ref_count)) {
   1354		pr_devel("%s-%d: state %s, ref_count %d\n",
   1355			 __func__, __LINE__,
   1356			 mtt_states_str(res->com.state),
   1357			 atomic_read(&res->ref_count));
   1358		return -EBUSY;
   1359	} else if (res->com.state != RES_MTT_ALLOCATED)
   1360		return -EPERM;
   1361	else if (res->order != order)
   1362		return -EINVAL;
   1363
   1364	return 0;
   1365}
   1366
   1367static int remove_mpt_ok(struct res_mpt *res)
   1368{
   1369	if (res->com.state == RES_MPT_BUSY)
   1370		return -EBUSY;
   1371	else if (res->com.state != RES_MPT_RESERVED)
   1372		return -EPERM;
   1373
   1374	return 0;
   1375}
   1376
   1377static int remove_eq_ok(struct res_eq *res)
   1378{
   1379	if (res->com.state == RES_MPT_BUSY)
   1380		return -EBUSY;
   1381	else if (res->com.state != RES_MPT_RESERVED)
   1382		return -EPERM;
   1383
   1384	return 0;
   1385}
   1386
   1387static int remove_counter_ok(struct res_counter *res)
   1388{
   1389	if (res->com.state == RES_COUNTER_BUSY)
   1390		return -EBUSY;
   1391	else if (res->com.state != RES_COUNTER_ALLOCATED)
   1392		return -EPERM;
   1393
   1394	return 0;
   1395}
   1396
   1397static int remove_xrcdn_ok(struct res_xrcdn *res)
   1398{
   1399	if (res->com.state == RES_XRCD_BUSY)
   1400		return -EBUSY;
   1401	else if (res->com.state != RES_XRCD_ALLOCATED)
   1402		return -EPERM;
   1403
   1404	return 0;
   1405}
   1406
   1407static int remove_fs_rule_ok(struct res_fs_rule *res)
   1408{
   1409	if (res->com.state == RES_FS_RULE_BUSY)
   1410		return -EBUSY;
   1411	else if (res->com.state != RES_FS_RULE_ALLOCATED)
   1412		return -EPERM;
   1413
   1414	return 0;
   1415}
   1416
   1417static int remove_cq_ok(struct res_cq *res)
   1418{
   1419	if (res->com.state == RES_CQ_BUSY)
   1420		return -EBUSY;
   1421	else if (res->com.state != RES_CQ_ALLOCATED)
   1422		return -EPERM;
   1423
   1424	return 0;
   1425}
   1426
   1427static int remove_srq_ok(struct res_srq *res)
   1428{
   1429	if (res->com.state == RES_SRQ_BUSY)
   1430		return -EBUSY;
   1431	else if (res->com.state != RES_SRQ_ALLOCATED)
   1432		return -EPERM;
   1433
   1434	return 0;
   1435}
   1436
   1437static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra)
   1438{
   1439	switch (type) {
   1440	case RES_QP:
   1441		return remove_qp_ok((struct res_qp *)res);
   1442	case RES_CQ:
   1443		return remove_cq_ok((struct res_cq *)res);
   1444	case RES_SRQ:
   1445		return remove_srq_ok((struct res_srq *)res);
   1446	case RES_MPT:
   1447		return remove_mpt_ok((struct res_mpt *)res);
   1448	case RES_MTT:
   1449		return remove_mtt_ok((struct res_mtt *)res, extra);
   1450	case RES_MAC:
   1451		return -EOPNOTSUPP;
   1452	case RES_EQ:
   1453		return remove_eq_ok((struct res_eq *)res);
   1454	case RES_COUNTER:
   1455		return remove_counter_ok((struct res_counter *)res);
   1456	case RES_XRCD:
   1457		return remove_xrcdn_ok((struct res_xrcdn *)res);
   1458	case RES_FS_RULE:
   1459		return remove_fs_rule_ok((struct res_fs_rule *)res);
   1460	default:
   1461		return -EINVAL;
   1462	}
   1463}
   1464
   1465static int rem_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
   1466			 enum mlx4_resource type, int extra)
   1467{
   1468	u64 i;
   1469	int err;
   1470	struct mlx4_priv *priv = mlx4_priv(dev);
   1471	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1472	struct res_common *r;
   1473
   1474	spin_lock_irq(mlx4_tlock(dev));
   1475	for (i = base; i < base + count; ++i) {
   1476		r = res_tracker_lookup(&tracker->res_tree[type], i);
   1477		if (!r) {
   1478			err = -ENOENT;
   1479			goto out;
   1480		}
   1481		if (r->owner != slave) {
   1482			err = -EPERM;
   1483			goto out;
   1484		}
   1485		err = remove_ok(r, type, extra);
   1486		if (err)
   1487			goto out;
   1488	}
   1489
   1490	for (i = base; i < base + count; ++i) {
   1491		r = res_tracker_lookup(&tracker->res_tree[type], i);
   1492		rb_erase(&r->node, &tracker->res_tree[type]);
   1493		list_del(&r->list);
   1494		kfree(r);
   1495	}
   1496	err = 0;
   1497
   1498out:
   1499	spin_unlock_irq(mlx4_tlock(dev));
   1500
   1501	return err;
   1502}
   1503
   1504static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn,
   1505				enum res_qp_states state, struct res_qp **qp,
   1506				int alloc)
   1507{
   1508	struct mlx4_priv *priv = mlx4_priv(dev);
   1509	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1510	struct res_qp *r;
   1511	int err = 0;
   1512
   1513	spin_lock_irq(mlx4_tlock(dev));
   1514	r = res_tracker_lookup(&tracker->res_tree[RES_QP], qpn);
   1515	if (!r)
   1516		err = -ENOENT;
   1517	else if (r->com.owner != slave)
   1518		err = -EPERM;
   1519	else {
   1520		switch (state) {
   1521		case RES_QP_BUSY:
   1522			mlx4_dbg(dev, "%s: failed RES_QP, 0x%llx\n",
   1523				 __func__, r->com.res_id);
   1524			err = -EBUSY;
   1525			break;
   1526
   1527		case RES_QP_RESERVED:
   1528			if (r->com.state == RES_QP_MAPPED && !alloc)
   1529				break;
   1530
   1531			mlx4_dbg(dev, "failed RES_QP, 0x%llx\n", r->com.res_id);
   1532			err = -EINVAL;
   1533			break;
   1534
   1535		case RES_QP_MAPPED:
   1536			if ((r->com.state == RES_QP_RESERVED && alloc) ||
   1537			    r->com.state == RES_QP_HW)
   1538				break;
   1539			else {
   1540				mlx4_dbg(dev, "failed RES_QP, 0x%llx\n",
   1541					  r->com.res_id);
   1542				err = -EINVAL;
   1543			}
   1544
   1545			break;
   1546
   1547		case RES_QP_HW:
   1548			if (r->com.state != RES_QP_MAPPED)
   1549				err = -EINVAL;
   1550			break;
   1551		default:
   1552			err = -EINVAL;
   1553		}
   1554
   1555		if (!err) {
   1556			r->com.from_state = r->com.state;
   1557			r->com.to_state = state;
   1558			r->com.state = RES_QP_BUSY;
   1559			if (qp)
   1560				*qp = r;
   1561		}
   1562	}
   1563
   1564	spin_unlock_irq(mlx4_tlock(dev));
   1565
   1566	return err;
   1567}
   1568
   1569static int mr_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
   1570				enum res_mpt_states state, struct res_mpt **mpt)
   1571{
   1572	struct mlx4_priv *priv = mlx4_priv(dev);
   1573	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1574	struct res_mpt *r;
   1575	int err = 0;
   1576
   1577	spin_lock_irq(mlx4_tlock(dev));
   1578	r = res_tracker_lookup(&tracker->res_tree[RES_MPT], index);
   1579	if (!r)
   1580		err = -ENOENT;
   1581	else if (r->com.owner != slave)
   1582		err = -EPERM;
   1583	else {
   1584		switch (state) {
   1585		case RES_MPT_BUSY:
   1586			err = -EINVAL;
   1587			break;
   1588
   1589		case RES_MPT_RESERVED:
   1590			if (r->com.state != RES_MPT_MAPPED)
   1591				err = -EINVAL;
   1592			break;
   1593
   1594		case RES_MPT_MAPPED:
   1595			if (r->com.state != RES_MPT_RESERVED &&
   1596			    r->com.state != RES_MPT_HW)
   1597				err = -EINVAL;
   1598			break;
   1599
   1600		case RES_MPT_HW:
   1601			if (r->com.state != RES_MPT_MAPPED)
   1602				err = -EINVAL;
   1603			break;
   1604		default:
   1605			err = -EINVAL;
   1606		}
   1607
   1608		if (!err) {
   1609			r->com.from_state = r->com.state;
   1610			r->com.to_state = state;
   1611			r->com.state = RES_MPT_BUSY;
   1612			if (mpt)
   1613				*mpt = r;
   1614		}
   1615	}
   1616
   1617	spin_unlock_irq(mlx4_tlock(dev));
   1618
   1619	return err;
   1620}
   1621
   1622static int eq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
   1623				enum res_eq_states state, struct res_eq **eq)
   1624{
   1625	struct mlx4_priv *priv = mlx4_priv(dev);
   1626	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1627	struct res_eq *r;
   1628	int err = 0;
   1629
   1630	spin_lock_irq(mlx4_tlock(dev));
   1631	r = res_tracker_lookup(&tracker->res_tree[RES_EQ], index);
   1632	if (!r)
   1633		err = -ENOENT;
   1634	else if (r->com.owner != slave)
   1635		err = -EPERM;
   1636	else {
   1637		switch (state) {
   1638		case RES_EQ_BUSY:
   1639			err = -EINVAL;
   1640			break;
   1641
   1642		case RES_EQ_RESERVED:
   1643			if (r->com.state != RES_EQ_HW)
   1644				err = -EINVAL;
   1645			break;
   1646
   1647		case RES_EQ_HW:
   1648			if (r->com.state != RES_EQ_RESERVED)
   1649				err = -EINVAL;
   1650			break;
   1651
   1652		default:
   1653			err = -EINVAL;
   1654		}
   1655
   1656		if (!err) {
   1657			r->com.from_state = r->com.state;
   1658			r->com.to_state = state;
   1659			r->com.state = RES_EQ_BUSY;
   1660		}
   1661	}
   1662
   1663	spin_unlock_irq(mlx4_tlock(dev));
   1664
   1665	if (!err && eq)
   1666		*eq = r;
   1667
   1668	return err;
   1669}
   1670
   1671static int cq_res_start_move_to(struct mlx4_dev *dev, int slave, int cqn,
   1672				enum res_cq_states state, struct res_cq **cq)
   1673{
   1674	struct mlx4_priv *priv = mlx4_priv(dev);
   1675	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1676	struct res_cq *r;
   1677	int err;
   1678
   1679	spin_lock_irq(mlx4_tlock(dev));
   1680	r = res_tracker_lookup(&tracker->res_tree[RES_CQ], cqn);
   1681	if (!r) {
   1682		err = -ENOENT;
   1683	} else if (r->com.owner != slave) {
   1684		err = -EPERM;
   1685	} else if (state == RES_CQ_ALLOCATED) {
   1686		if (r->com.state != RES_CQ_HW)
   1687			err = -EINVAL;
   1688		else if (atomic_read(&r->ref_count))
   1689			err = -EBUSY;
   1690		else
   1691			err = 0;
   1692	} else if (state != RES_CQ_HW || r->com.state != RES_CQ_ALLOCATED) {
   1693		err = -EINVAL;
   1694	} else {
   1695		err = 0;
   1696	}
   1697
   1698	if (!err) {
   1699		r->com.from_state = r->com.state;
   1700		r->com.to_state = state;
   1701		r->com.state = RES_CQ_BUSY;
   1702		if (cq)
   1703			*cq = r;
   1704	}
   1705
   1706	spin_unlock_irq(mlx4_tlock(dev));
   1707
   1708	return err;
   1709}
   1710
   1711static int srq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
   1712				 enum res_srq_states state, struct res_srq **srq)
   1713{
   1714	struct mlx4_priv *priv = mlx4_priv(dev);
   1715	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1716	struct res_srq *r;
   1717	int err = 0;
   1718
   1719	spin_lock_irq(mlx4_tlock(dev));
   1720	r = res_tracker_lookup(&tracker->res_tree[RES_SRQ], index);
   1721	if (!r) {
   1722		err = -ENOENT;
   1723	} else if (r->com.owner != slave) {
   1724		err = -EPERM;
   1725	} else if (state == RES_SRQ_ALLOCATED) {
   1726		if (r->com.state != RES_SRQ_HW)
   1727			err = -EINVAL;
   1728		else if (atomic_read(&r->ref_count))
   1729			err = -EBUSY;
   1730	} else if (state != RES_SRQ_HW || r->com.state != RES_SRQ_ALLOCATED) {
   1731		err = -EINVAL;
   1732	}
   1733
   1734	if (!err) {
   1735		r->com.from_state = r->com.state;
   1736		r->com.to_state = state;
   1737		r->com.state = RES_SRQ_BUSY;
   1738		if (srq)
   1739			*srq = r;
   1740	}
   1741
   1742	spin_unlock_irq(mlx4_tlock(dev));
   1743
   1744	return err;
   1745}
   1746
   1747static void res_abort_move(struct mlx4_dev *dev, int slave,
   1748			   enum mlx4_resource type, int id)
   1749{
   1750	struct mlx4_priv *priv = mlx4_priv(dev);
   1751	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1752	struct res_common *r;
   1753
   1754	spin_lock_irq(mlx4_tlock(dev));
   1755	r = res_tracker_lookup(&tracker->res_tree[type], id);
   1756	if (r && (r->owner == slave))
   1757		r->state = r->from_state;
   1758	spin_unlock_irq(mlx4_tlock(dev));
   1759}
   1760
   1761static void res_end_move(struct mlx4_dev *dev, int slave,
   1762			 enum mlx4_resource type, int id)
   1763{
   1764	struct mlx4_priv *priv = mlx4_priv(dev);
   1765	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   1766	struct res_common *r;
   1767
   1768	spin_lock_irq(mlx4_tlock(dev));
   1769	r = res_tracker_lookup(&tracker->res_tree[type], id);
   1770	if (r && (r->owner == slave))
   1771		r->state = r->to_state;
   1772	spin_unlock_irq(mlx4_tlock(dev));
   1773}
   1774
   1775static int valid_reserved(struct mlx4_dev *dev, int slave, int qpn)
   1776{
   1777	return mlx4_is_qp_reserved(dev, qpn) &&
   1778		(mlx4_is_master(dev) || mlx4_is_guest_proxy(dev, slave, qpn));
   1779}
   1780
   1781static int fw_reserved(struct mlx4_dev *dev, int qpn)
   1782{
   1783	return qpn < dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW];
   1784}
   1785
   1786static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   1787			u64 in_param, u64 *out_param)
   1788{
   1789	int err;
   1790	int count;
   1791	int align;
   1792	int base;
   1793	int qpn;
   1794	u8 flags;
   1795
   1796	switch (op) {
   1797	case RES_OP_RESERVE:
   1798		count = get_param_l(&in_param) & 0xffffff;
   1799		/* Turn off all unsupported QP allocation flags that the
   1800		 * slave tries to set.
   1801		 */
   1802		flags = (get_param_l(&in_param) >> 24) & dev->caps.alloc_res_qp_mask;
   1803		align = get_param_h(&in_param);
   1804		err = mlx4_grant_resource(dev, slave, RES_QP, count, 0);
   1805		if (err)
   1806			return err;
   1807
   1808		err = __mlx4_qp_reserve_range(dev, count, align, &base, flags);
   1809		if (err) {
   1810			mlx4_release_resource(dev, slave, RES_QP, count, 0);
   1811			return err;
   1812		}
   1813
   1814		err = add_res_range(dev, slave, base, count, RES_QP, 0);
   1815		if (err) {
   1816			mlx4_release_resource(dev, slave, RES_QP, count, 0);
   1817			__mlx4_qp_release_range(dev, base, count);
   1818			return err;
   1819		}
   1820		set_param_l(out_param, base);
   1821		break;
   1822	case RES_OP_MAP_ICM:
   1823		qpn = get_param_l(&in_param) & 0x7fffff;
   1824		if (valid_reserved(dev, slave, qpn)) {
   1825			err = add_res_range(dev, slave, qpn, 1, RES_QP, 0);
   1826			if (err)
   1827				return err;
   1828		}
   1829
   1830		err = qp_res_start_move_to(dev, slave, qpn, RES_QP_MAPPED,
   1831					   NULL, 1);
   1832		if (err)
   1833			return err;
   1834
   1835		if (!fw_reserved(dev, qpn)) {
   1836			err = __mlx4_qp_alloc_icm(dev, qpn);
   1837			if (err) {
   1838				res_abort_move(dev, slave, RES_QP, qpn);
   1839				return err;
   1840			}
   1841		}
   1842
   1843		res_end_move(dev, slave, RES_QP, qpn);
   1844		break;
   1845
   1846	default:
   1847		err = -EINVAL;
   1848		break;
   1849	}
   1850	return err;
   1851}
   1852
   1853static int mtt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   1854			 u64 in_param, u64 *out_param)
   1855{
   1856	int err = -EINVAL;
   1857	int base;
   1858	int order;
   1859
   1860	if (op != RES_OP_RESERVE_AND_MAP)
   1861		return err;
   1862
   1863	order = get_param_l(&in_param);
   1864
   1865	err = mlx4_grant_resource(dev, slave, RES_MTT, 1 << order, 0);
   1866	if (err)
   1867		return err;
   1868
   1869	base = __mlx4_alloc_mtt_range(dev, order);
   1870	if (base == -1) {
   1871		mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
   1872		return -ENOMEM;
   1873	}
   1874
   1875	err = add_res_range(dev, slave, base, 1, RES_MTT, order);
   1876	if (err) {
   1877		mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
   1878		__mlx4_free_mtt_range(dev, base, order);
   1879	} else {
   1880		set_param_l(out_param, base);
   1881	}
   1882
   1883	return err;
   1884}
   1885
   1886static int mpt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   1887			 u64 in_param, u64 *out_param)
   1888{
   1889	int err = -EINVAL;
   1890	int index;
   1891	int id;
   1892	struct res_mpt *mpt;
   1893
   1894	switch (op) {
   1895	case RES_OP_RESERVE:
   1896		err = mlx4_grant_resource(dev, slave, RES_MPT, 1, 0);
   1897		if (err)
   1898			break;
   1899
   1900		index = __mlx4_mpt_reserve(dev);
   1901		if (index == -1) {
   1902			mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
   1903			break;
   1904		}
   1905		id = index & mpt_mask(dev);
   1906
   1907		err = add_res_range(dev, slave, id, 1, RES_MPT, index);
   1908		if (err) {
   1909			mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
   1910			__mlx4_mpt_release(dev, index);
   1911			break;
   1912		}
   1913		set_param_l(out_param, index);
   1914		break;
   1915	case RES_OP_MAP_ICM:
   1916		index = get_param_l(&in_param);
   1917		id = index & mpt_mask(dev);
   1918		err = mr_res_start_move_to(dev, slave, id,
   1919					   RES_MPT_MAPPED, &mpt);
   1920		if (err)
   1921			return err;
   1922
   1923		err = __mlx4_mpt_alloc_icm(dev, mpt->key);
   1924		if (err) {
   1925			res_abort_move(dev, slave, RES_MPT, id);
   1926			return err;
   1927		}
   1928
   1929		res_end_move(dev, slave, RES_MPT, id);
   1930		break;
   1931	}
   1932	return err;
   1933}
   1934
   1935static int cq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   1936			u64 in_param, u64 *out_param)
   1937{
   1938	int cqn;
   1939	int err;
   1940
   1941	switch (op) {
   1942	case RES_OP_RESERVE_AND_MAP:
   1943		err = mlx4_grant_resource(dev, slave, RES_CQ, 1, 0);
   1944		if (err)
   1945			break;
   1946
   1947		err = __mlx4_cq_alloc_icm(dev, &cqn);
   1948		if (err) {
   1949			mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
   1950			break;
   1951		}
   1952
   1953		err = add_res_range(dev, slave, cqn, 1, RES_CQ, 0);
   1954		if (err) {
   1955			mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
   1956			__mlx4_cq_free_icm(dev, cqn);
   1957			break;
   1958		}
   1959
   1960		set_param_l(out_param, cqn);
   1961		break;
   1962
   1963	default:
   1964		err = -EINVAL;
   1965	}
   1966
   1967	return err;
   1968}
   1969
   1970static int srq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   1971			 u64 in_param, u64 *out_param)
   1972{
   1973	int srqn;
   1974	int err;
   1975
   1976	switch (op) {
   1977	case RES_OP_RESERVE_AND_MAP:
   1978		err = mlx4_grant_resource(dev, slave, RES_SRQ, 1, 0);
   1979		if (err)
   1980			break;
   1981
   1982		err = __mlx4_srq_alloc_icm(dev, &srqn);
   1983		if (err) {
   1984			mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
   1985			break;
   1986		}
   1987
   1988		err = add_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
   1989		if (err) {
   1990			mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
   1991			__mlx4_srq_free_icm(dev, srqn);
   1992			break;
   1993		}
   1994
   1995		set_param_l(out_param, srqn);
   1996		break;
   1997
   1998	default:
   1999		err = -EINVAL;
   2000	}
   2001
   2002	return err;
   2003}
   2004
   2005static int mac_find_smac_ix_in_slave(struct mlx4_dev *dev, int slave, int port,
   2006				     u8 smac_index, u64 *mac)
   2007{
   2008	struct mlx4_priv *priv = mlx4_priv(dev);
   2009	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   2010	struct list_head *mac_list =
   2011		&tracker->slave_list[slave].res_list[RES_MAC];
   2012	struct mac_res *res, *tmp;
   2013
   2014	list_for_each_entry_safe(res, tmp, mac_list, list) {
   2015		if (res->smac_index == smac_index && res->port == (u8) port) {
   2016			*mac = res->mac;
   2017			return 0;
   2018		}
   2019	}
   2020	return -ENOENT;
   2021}
   2022
   2023static int mac_add_to_slave(struct mlx4_dev *dev, int slave, u64 mac, int port, u8 smac_index)
   2024{
   2025	struct mlx4_priv *priv = mlx4_priv(dev);
   2026	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   2027	struct list_head *mac_list =
   2028		&tracker->slave_list[slave].res_list[RES_MAC];
   2029	struct mac_res *res, *tmp;
   2030
   2031	list_for_each_entry_safe(res, tmp, mac_list, list) {
   2032		if (res->mac == mac && res->port == (u8) port) {
   2033			/* mac found. update ref count */
   2034			++res->ref_count;
   2035			return 0;
   2036		}
   2037	}
   2038
   2039	if (mlx4_grant_resource(dev, slave, RES_MAC, 1, port))
   2040		return -EINVAL;
   2041	res = kzalloc(sizeof(*res), GFP_KERNEL);
   2042	if (!res) {
   2043		mlx4_release_resource(dev, slave, RES_MAC, 1, port);
   2044		return -ENOMEM;
   2045	}
   2046	res->mac = mac;
   2047	res->port = (u8) port;
   2048	res->smac_index = smac_index;
   2049	res->ref_count = 1;
   2050	list_add_tail(&res->list,
   2051		      &tracker->slave_list[slave].res_list[RES_MAC]);
   2052	return 0;
   2053}
   2054
   2055static void mac_del_from_slave(struct mlx4_dev *dev, int slave, u64 mac,
   2056			       int port)
   2057{
   2058	struct mlx4_priv *priv = mlx4_priv(dev);
   2059	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   2060	struct list_head *mac_list =
   2061		&tracker->slave_list[slave].res_list[RES_MAC];
   2062	struct mac_res *res, *tmp;
   2063
   2064	list_for_each_entry_safe(res, tmp, mac_list, list) {
   2065		if (res->mac == mac && res->port == (u8) port) {
   2066			if (!--res->ref_count) {
   2067				list_del(&res->list);
   2068				mlx4_release_resource(dev, slave, RES_MAC, 1, port);
   2069				kfree(res);
   2070			}
   2071			break;
   2072		}
   2073	}
   2074}
   2075
   2076static void rem_slave_macs(struct mlx4_dev *dev, int slave)
   2077{
   2078	struct mlx4_priv *priv = mlx4_priv(dev);
   2079	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   2080	struct list_head *mac_list =
   2081		&tracker->slave_list[slave].res_list[RES_MAC];
   2082	struct mac_res *res, *tmp;
   2083	int i;
   2084
   2085	list_for_each_entry_safe(res, tmp, mac_list, list) {
   2086		list_del(&res->list);
   2087		/* dereference the mac the num times the slave referenced it */
   2088		for (i = 0; i < res->ref_count; i++)
   2089			__mlx4_unregister_mac(dev, res->port, res->mac);
   2090		mlx4_release_resource(dev, slave, RES_MAC, 1, res->port);
   2091		kfree(res);
   2092	}
   2093}
   2094
   2095static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2096			 u64 in_param, u64 *out_param, int in_port)
   2097{
   2098	int err = -EINVAL;
   2099	int port;
   2100	u64 mac;
   2101	u8 smac_index;
   2102
   2103	if (op != RES_OP_RESERVE_AND_MAP)
   2104		return err;
   2105
   2106	port = !in_port ? get_param_l(out_param) : in_port;
   2107	port = mlx4_slave_convert_port(
   2108			dev, slave, port);
   2109
   2110	if (port < 0)
   2111		return -EINVAL;
   2112	mac = in_param;
   2113
   2114	err = __mlx4_register_mac(dev, port, mac);
   2115	if (err >= 0) {
   2116		smac_index = err;
   2117		set_param_l(out_param, err);
   2118		err = 0;
   2119	}
   2120
   2121	if (!err) {
   2122		err = mac_add_to_slave(dev, slave, mac, port, smac_index);
   2123		if (err)
   2124			__mlx4_unregister_mac(dev, port, mac);
   2125	}
   2126	return err;
   2127}
   2128
   2129static int vlan_add_to_slave(struct mlx4_dev *dev, int slave, u16 vlan,
   2130			     int port, int vlan_index)
   2131{
   2132	struct mlx4_priv *priv = mlx4_priv(dev);
   2133	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   2134	struct list_head *vlan_list =
   2135		&tracker->slave_list[slave].res_list[RES_VLAN];
   2136	struct vlan_res *res, *tmp;
   2137
   2138	list_for_each_entry_safe(res, tmp, vlan_list, list) {
   2139		if (res->vlan == vlan && res->port == (u8) port) {
   2140			/* vlan found. update ref count */
   2141			++res->ref_count;
   2142			return 0;
   2143		}
   2144	}
   2145
   2146	if (mlx4_grant_resource(dev, slave, RES_VLAN, 1, port))
   2147		return -EINVAL;
   2148	res = kzalloc(sizeof(*res), GFP_KERNEL);
   2149	if (!res) {
   2150		mlx4_release_resource(dev, slave, RES_VLAN, 1, port);
   2151		return -ENOMEM;
   2152	}
   2153	res->vlan = vlan;
   2154	res->port = (u8) port;
   2155	res->vlan_index = vlan_index;
   2156	res->ref_count = 1;
   2157	list_add_tail(&res->list,
   2158		      &tracker->slave_list[slave].res_list[RES_VLAN]);
   2159	return 0;
   2160}
   2161
   2162
   2163static void vlan_del_from_slave(struct mlx4_dev *dev, int slave, u16 vlan,
   2164				int port)
   2165{
   2166	struct mlx4_priv *priv = mlx4_priv(dev);
   2167	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   2168	struct list_head *vlan_list =
   2169		&tracker->slave_list[slave].res_list[RES_VLAN];
   2170	struct vlan_res *res, *tmp;
   2171
   2172	list_for_each_entry_safe(res, tmp, vlan_list, list) {
   2173		if (res->vlan == vlan && res->port == (u8) port) {
   2174			if (!--res->ref_count) {
   2175				list_del(&res->list);
   2176				mlx4_release_resource(dev, slave, RES_VLAN,
   2177						      1, port);
   2178				kfree(res);
   2179			}
   2180			break;
   2181		}
   2182	}
   2183}
   2184
   2185static void rem_slave_vlans(struct mlx4_dev *dev, int slave)
   2186{
   2187	struct mlx4_priv *priv = mlx4_priv(dev);
   2188	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   2189	struct list_head *vlan_list =
   2190		&tracker->slave_list[slave].res_list[RES_VLAN];
   2191	struct vlan_res *res, *tmp;
   2192	int i;
   2193
   2194	list_for_each_entry_safe(res, tmp, vlan_list, list) {
   2195		list_del(&res->list);
   2196		/* dereference the vlan the num times the slave referenced it */
   2197		for (i = 0; i < res->ref_count; i++)
   2198			__mlx4_unregister_vlan(dev, res->port, res->vlan);
   2199		mlx4_release_resource(dev, slave, RES_VLAN, 1, res->port);
   2200		kfree(res);
   2201	}
   2202}
   2203
   2204static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2205			  u64 in_param, u64 *out_param, int in_port)
   2206{
   2207	struct mlx4_priv *priv = mlx4_priv(dev);
   2208	struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
   2209	int err;
   2210	u16 vlan;
   2211	int vlan_index;
   2212	int port;
   2213
   2214	port = !in_port ? get_param_l(out_param) : in_port;
   2215
   2216	if (!port || op != RES_OP_RESERVE_AND_MAP)
   2217		return -EINVAL;
   2218
   2219	port = mlx4_slave_convert_port(
   2220			dev, slave, port);
   2221
   2222	if (port < 0)
   2223		return -EINVAL;
   2224	/* upstream kernels had NOP for reg/unreg vlan. Continue this. */
   2225	if (!in_port && port > 0 && port <= dev->caps.num_ports) {
   2226		slave_state[slave].old_vlan_api = true;
   2227		return 0;
   2228	}
   2229
   2230	vlan = (u16) in_param;
   2231
   2232	err = __mlx4_register_vlan(dev, port, vlan, &vlan_index);
   2233	if (!err) {
   2234		set_param_l(out_param, (u32) vlan_index);
   2235		err = vlan_add_to_slave(dev, slave, vlan, port, vlan_index);
   2236		if (err)
   2237			__mlx4_unregister_vlan(dev, port, vlan);
   2238	}
   2239	return err;
   2240}
   2241
   2242static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2243			     u64 in_param, u64 *out_param, int port)
   2244{
   2245	u32 index;
   2246	int err;
   2247
   2248	if (op != RES_OP_RESERVE)
   2249		return -EINVAL;
   2250
   2251	err = mlx4_grant_resource(dev, slave, RES_COUNTER, 1, 0);
   2252	if (err)
   2253		return err;
   2254
   2255	err = __mlx4_counter_alloc(dev, &index);
   2256	if (err) {
   2257		mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
   2258		return err;
   2259	}
   2260
   2261	err = add_res_range(dev, slave, index, 1, RES_COUNTER, port);
   2262	if (err) {
   2263		__mlx4_counter_free(dev, index);
   2264		mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
   2265	} else {
   2266		set_param_l(out_param, index);
   2267	}
   2268
   2269	return err;
   2270}
   2271
   2272static int xrcdn_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2273			   u64 in_param, u64 *out_param)
   2274{
   2275	u32 xrcdn;
   2276	int err;
   2277
   2278	if (op != RES_OP_RESERVE)
   2279		return -EINVAL;
   2280
   2281	err = __mlx4_xrcd_alloc(dev, &xrcdn);
   2282	if (err)
   2283		return err;
   2284
   2285	err = add_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
   2286	if (err)
   2287		__mlx4_xrcd_free(dev, xrcdn);
   2288	else
   2289		set_param_l(out_param, xrcdn);
   2290
   2291	return err;
   2292}
   2293
   2294int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
   2295			   struct mlx4_vhcr *vhcr,
   2296			   struct mlx4_cmd_mailbox *inbox,
   2297			   struct mlx4_cmd_mailbox *outbox,
   2298			   struct mlx4_cmd_info *cmd)
   2299{
   2300	int err;
   2301	int alop = vhcr->op_modifier;
   2302
   2303	switch (vhcr->in_modifier & 0xFF) {
   2304	case RES_QP:
   2305		err = qp_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2306				   vhcr->in_param, &vhcr->out_param);
   2307		break;
   2308
   2309	case RES_MTT:
   2310		err = mtt_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2311				    vhcr->in_param, &vhcr->out_param);
   2312		break;
   2313
   2314	case RES_MPT:
   2315		err = mpt_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2316				    vhcr->in_param, &vhcr->out_param);
   2317		break;
   2318
   2319	case RES_CQ:
   2320		err = cq_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2321				   vhcr->in_param, &vhcr->out_param);
   2322		break;
   2323
   2324	case RES_SRQ:
   2325		err = srq_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2326				    vhcr->in_param, &vhcr->out_param);
   2327		break;
   2328
   2329	case RES_MAC:
   2330		err = mac_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2331				    vhcr->in_param, &vhcr->out_param,
   2332				    (vhcr->in_modifier >> 8) & 0xFF);
   2333		break;
   2334
   2335	case RES_VLAN:
   2336		err = vlan_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2337				     vhcr->in_param, &vhcr->out_param,
   2338				     (vhcr->in_modifier >> 8) & 0xFF);
   2339		break;
   2340
   2341	case RES_COUNTER:
   2342		err = counter_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2343					vhcr->in_param, &vhcr->out_param, 0);
   2344		break;
   2345
   2346	case RES_XRCD:
   2347		err = xrcdn_alloc_res(dev, slave, vhcr->op_modifier, alop,
   2348				      vhcr->in_param, &vhcr->out_param);
   2349		break;
   2350
   2351	default:
   2352		err = -EINVAL;
   2353		break;
   2354	}
   2355
   2356	return err;
   2357}
   2358
   2359static int qp_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2360		       u64 in_param)
   2361{
   2362	int err;
   2363	int count;
   2364	int base;
   2365	int qpn;
   2366
   2367	switch (op) {
   2368	case RES_OP_RESERVE:
   2369		base = get_param_l(&in_param) & 0x7fffff;
   2370		count = get_param_h(&in_param);
   2371		err = rem_res_range(dev, slave, base, count, RES_QP, 0);
   2372		if (err)
   2373			break;
   2374		mlx4_release_resource(dev, slave, RES_QP, count, 0);
   2375		__mlx4_qp_release_range(dev, base, count);
   2376		break;
   2377	case RES_OP_MAP_ICM:
   2378		qpn = get_param_l(&in_param) & 0x7fffff;
   2379		err = qp_res_start_move_to(dev, slave, qpn, RES_QP_RESERVED,
   2380					   NULL, 0);
   2381		if (err)
   2382			return err;
   2383
   2384		if (!fw_reserved(dev, qpn))
   2385			__mlx4_qp_free_icm(dev, qpn);
   2386
   2387		res_end_move(dev, slave, RES_QP, qpn);
   2388
   2389		if (valid_reserved(dev, slave, qpn))
   2390			err = rem_res_range(dev, slave, qpn, 1, RES_QP, 0);
   2391		break;
   2392	default:
   2393		err = -EINVAL;
   2394		break;
   2395	}
   2396	return err;
   2397}
   2398
   2399static int mtt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2400			u64 in_param, u64 *out_param)
   2401{
   2402	int err = -EINVAL;
   2403	int base;
   2404	int order;
   2405
   2406	if (op != RES_OP_RESERVE_AND_MAP)
   2407		return err;
   2408
   2409	base = get_param_l(&in_param);
   2410	order = get_param_h(&in_param);
   2411	err = rem_res_range(dev, slave, base, 1, RES_MTT, order);
   2412	if (!err) {
   2413		mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
   2414		__mlx4_free_mtt_range(dev, base, order);
   2415	}
   2416	return err;
   2417}
   2418
   2419static int mpt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2420			u64 in_param)
   2421{
   2422	int err = -EINVAL;
   2423	int index;
   2424	int id;
   2425	struct res_mpt *mpt;
   2426
   2427	switch (op) {
   2428	case RES_OP_RESERVE:
   2429		index = get_param_l(&in_param);
   2430		id = index & mpt_mask(dev);
   2431		err = get_res(dev, slave, id, RES_MPT, &mpt);
   2432		if (err)
   2433			break;
   2434		index = mpt->key;
   2435		put_res(dev, slave, id, RES_MPT);
   2436
   2437		err = rem_res_range(dev, slave, id, 1, RES_MPT, 0);
   2438		if (err)
   2439			break;
   2440		mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
   2441		__mlx4_mpt_release(dev, index);
   2442		break;
   2443	case RES_OP_MAP_ICM:
   2444		index = get_param_l(&in_param);
   2445		id = index & mpt_mask(dev);
   2446		err = mr_res_start_move_to(dev, slave, id,
   2447					   RES_MPT_RESERVED, &mpt);
   2448		if (err)
   2449			return err;
   2450
   2451		__mlx4_mpt_free_icm(dev, mpt->key);
   2452		res_end_move(dev, slave, RES_MPT, id);
   2453		break;
   2454	default:
   2455		err = -EINVAL;
   2456		break;
   2457	}
   2458	return err;
   2459}
   2460
   2461static int cq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2462		       u64 in_param, u64 *out_param)
   2463{
   2464	int cqn;
   2465	int err;
   2466
   2467	switch (op) {
   2468	case RES_OP_RESERVE_AND_MAP:
   2469		cqn = get_param_l(&in_param);
   2470		err = rem_res_range(dev, slave, cqn, 1, RES_CQ, 0);
   2471		if (err)
   2472			break;
   2473
   2474		mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
   2475		__mlx4_cq_free_icm(dev, cqn);
   2476		break;
   2477
   2478	default:
   2479		err = -EINVAL;
   2480		break;
   2481	}
   2482
   2483	return err;
   2484}
   2485
   2486static int srq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2487			u64 in_param, u64 *out_param)
   2488{
   2489	int srqn;
   2490	int err;
   2491
   2492	switch (op) {
   2493	case RES_OP_RESERVE_AND_MAP:
   2494		srqn = get_param_l(&in_param);
   2495		err = rem_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
   2496		if (err)
   2497			break;
   2498
   2499		mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
   2500		__mlx4_srq_free_icm(dev, srqn);
   2501		break;
   2502
   2503	default:
   2504		err = -EINVAL;
   2505		break;
   2506	}
   2507
   2508	return err;
   2509}
   2510
   2511static int mac_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2512			    u64 in_param, u64 *out_param, int in_port)
   2513{
   2514	int port;
   2515	int err = 0;
   2516
   2517	switch (op) {
   2518	case RES_OP_RESERVE_AND_MAP:
   2519		port = !in_port ? get_param_l(out_param) : in_port;
   2520		port = mlx4_slave_convert_port(
   2521				dev, slave, port);
   2522
   2523		if (port < 0)
   2524			return -EINVAL;
   2525		mac_del_from_slave(dev, slave, in_param, port);
   2526		__mlx4_unregister_mac(dev, port, in_param);
   2527		break;
   2528	default:
   2529		err = -EINVAL;
   2530		break;
   2531	}
   2532
   2533	return err;
   2534
   2535}
   2536
   2537static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2538			    u64 in_param, u64 *out_param, int port)
   2539{
   2540	struct mlx4_priv *priv = mlx4_priv(dev);
   2541	struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
   2542	int err = 0;
   2543
   2544	port = mlx4_slave_convert_port(
   2545			dev, slave, port);
   2546
   2547	if (port < 0)
   2548		return -EINVAL;
   2549	switch (op) {
   2550	case RES_OP_RESERVE_AND_MAP:
   2551		if (slave_state[slave].old_vlan_api)
   2552			return 0;
   2553		if (!port)
   2554			return -EINVAL;
   2555		vlan_del_from_slave(dev, slave, in_param, port);
   2556		__mlx4_unregister_vlan(dev, port, in_param);
   2557		break;
   2558	default:
   2559		err = -EINVAL;
   2560		break;
   2561	}
   2562
   2563	return err;
   2564}
   2565
   2566static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2567			    u64 in_param, u64 *out_param)
   2568{
   2569	int index;
   2570	int err;
   2571
   2572	if (op != RES_OP_RESERVE)
   2573		return -EINVAL;
   2574
   2575	index = get_param_l(&in_param);
   2576	if (index == MLX4_SINK_COUNTER_INDEX(dev))
   2577		return 0;
   2578
   2579	err = rem_res_range(dev, slave, index, 1, RES_COUNTER, 0);
   2580	if (err)
   2581		return err;
   2582
   2583	__mlx4_counter_free(dev, index);
   2584	mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
   2585
   2586	return err;
   2587}
   2588
   2589static int xrcdn_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
   2590			  u64 in_param, u64 *out_param)
   2591{
   2592	int xrcdn;
   2593	int err;
   2594
   2595	if (op != RES_OP_RESERVE)
   2596		return -EINVAL;
   2597
   2598	xrcdn = get_param_l(&in_param);
   2599	err = rem_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
   2600	if (err)
   2601		return err;
   2602
   2603	__mlx4_xrcd_free(dev, xrcdn);
   2604
   2605	return err;
   2606}
   2607
   2608int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
   2609			  struct mlx4_vhcr *vhcr,
   2610			  struct mlx4_cmd_mailbox *inbox,
   2611			  struct mlx4_cmd_mailbox *outbox,
   2612			  struct mlx4_cmd_info *cmd)
   2613{
   2614	int err = -EINVAL;
   2615	int alop = vhcr->op_modifier;
   2616
   2617	switch (vhcr->in_modifier & 0xFF) {
   2618	case RES_QP:
   2619		err = qp_free_res(dev, slave, vhcr->op_modifier, alop,
   2620				  vhcr->in_param);
   2621		break;
   2622
   2623	case RES_MTT:
   2624		err = mtt_free_res(dev, slave, vhcr->op_modifier, alop,
   2625				   vhcr->in_param, &vhcr->out_param);
   2626		break;
   2627
   2628	case RES_MPT:
   2629		err = mpt_free_res(dev, slave, vhcr->op_modifier, alop,
   2630				   vhcr->in_param);
   2631		break;
   2632
   2633	case RES_CQ:
   2634		err = cq_free_res(dev, slave, vhcr->op_modifier, alop,
   2635				  vhcr->in_param, &vhcr->out_param);
   2636		break;
   2637
   2638	case RES_SRQ:
   2639		err = srq_free_res(dev, slave, vhcr->op_modifier, alop,
   2640				   vhcr->in_param, &vhcr->out_param);
   2641		break;
   2642
   2643	case RES_MAC:
   2644		err = mac_free_res(dev, slave, vhcr->op_modifier, alop,
   2645				   vhcr->in_param, &vhcr->out_param,
   2646				   (vhcr->in_modifier >> 8) & 0xFF);
   2647		break;
   2648
   2649	case RES_VLAN:
   2650		err = vlan_free_res(dev, slave, vhcr->op_modifier, alop,
   2651				    vhcr->in_param, &vhcr->out_param,
   2652				    (vhcr->in_modifier >> 8) & 0xFF);
   2653		break;
   2654
   2655	case RES_COUNTER:
   2656		err = counter_free_res(dev, slave, vhcr->op_modifier, alop,
   2657				       vhcr->in_param, &vhcr->out_param);
   2658		break;
   2659
   2660	case RES_XRCD:
   2661		err = xrcdn_free_res(dev, slave, vhcr->op_modifier, alop,
   2662				     vhcr->in_param, &vhcr->out_param);
   2663		break;
   2664
   2665	default:
   2666		break;
   2667	}
   2668	return err;
   2669}
   2670
   2671/* ugly but other choices are uglier */
   2672static int mr_phys_mpt(struct mlx4_mpt_entry *mpt)
   2673{
   2674	return (be32_to_cpu(mpt->flags) >> 9) & 1;
   2675}
   2676
   2677static int mr_get_mtt_addr(struct mlx4_mpt_entry *mpt)
   2678{
   2679	return (int)be64_to_cpu(mpt->mtt_addr) & 0xfffffff8;
   2680}
   2681
   2682static int mr_get_mtt_size(struct mlx4_mpt_entry *mpt)
   2683{
   2684	return be32_to_cpu(mpt->mtt_sz);
   2685}
   2686
   2687static u32 mr_get_pd(struct mlx4_mpt_entry *mpt)
   2688{
   2689	return be32_to_cpu(mpt->pd_flags) & 0x00ffffff;
   2690}
   2691
   2692static int mr_is_fmr(struct mlx4_mpt_entry *mpt)
   2693{
   2694	return be32_to_cpu(mpt->pd_flags) & MLX4_MPT_PD_FLAG_FAST_REG;
   2695}
   2696
   2697static int mr_is_bind_enabled(struct mlx4_mpt_entry *mpt)
   2698{
   2699	return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_BIND_ENABLE;
   2700}
   2701
   2702static int mr_is_region(struct mlx4_mpt_entry *mpt)
   2703{
   2704	return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_REGION;
   2705}
   2706
   2707static int qp_get_mtt_addr(struct mlx4_qp_context *qpc)
   2708{
   2709	return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8;
   2710}
   2711
   2712static int srq_get_mtt_addr(struct mlx4_srq_context *srqc)
   2713{
   2714	return be32_to_cpu(srqc->mtt_base_addr_l) & 0xfffffff8;
   2715}
   2716
   2717static int qp_get_mtt_size(struct mlx4_qp_context *qpc)
   2718{
   2719	int page_shift = (qpc->log_page_size & 0x3f) + 12;
   2720	int log_sq_size = (qpc->sq_size_stride >> 3) & 0xf;
   2721	int log_sq_sride = qpc->sq_size_stride & 7;
   2722	int log_rq_size = (qpc->rq_size_stride >> 3) & 0xf;
   2723	int log_rq_stride = qpc->rq_size_stride & 7;
   2724	int srq = (be32_to_cpu(qpc->srqn) >> 24) & 1;
   2725	int rss = (be32_to_cpu(qpc->flags) >> 13) & 1;
   2726	u32 ts = (be32_to_cpu(qpc->flags) >> 16) & 0xff;
   2727	int xrc = (ts == MLX4_QP_ST_XRC) ? 1 : 0;
   2728	int sq_size;
   2729	int rq_size;
   2730	int total_pages;
   2731	int total_mem;
   2732	int page_offset = (be32_to_cpu(qpc->params2) >> 6) & 0x3f;
   2733	int tot;
   2734
   2735	sq_size = 1 << (log_sq_size + log_sq_sride + 4);
   2736	rq_size = (srq|rss|xrc) ? 0 : (1 << (log_rq_size + log_rq_stride + 4));
   2737	total_mem = sq_size + rq_size;
   2738	tot = (total_mem + (page_offset << 6)) >> page_shift;
   2739	total_pages = !tot ? 1 : roundup_pow_of_two(tot);
   2740
   2741	return total_pages;
   2742}
   2743
   2744static int check_mtt_range(struct mlx4_dev *dev, int slave, int start,
   2745			   int size, struct res_mtt *mtt)
   2746{
   2747	int res_start = mtt->com.res_id;
   2748	int res_size = (1 << mtt->order);
   2749
   2750	if (start < res_start || start + size > res_start + res_size)
   2751		return -EPERM;
   2752	return 0;
   2753}
   2754
   2755int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev *dev, int slave,
   2756			   struct mlx4_vhcr *vhcr,
   2757			   struct mlx4_cmd_mailbox *inbox,
   2758			   struct mlx4_cmd_mailbox *outbox,
   2759			   struct mlx4_cmd_info *cmd)
   2760{
   2761	int err;
   2762	int index = vhcr->in_modifier;
   2763	struct res_mtt *mtt;
   2764	struct res_mpt *mpt = NULL;
   2765	int mtt_base = mr_get_mtt_addr(inbox->buf) / dev->caps.mtt_entry_sz;
   2766	int phys;
   2767	int id;
   2768	u32 pd;
   2769	int pd_slave;
   2770
   2771	id = index & mpt_mask(dev);
   2772	err = mr_res_start_move_to(dev, slave, id, RES_MPT_HW, &mpt);
   2773	if (err)
   2774		return err;
   2775
   2776	/* Disable memory windows for VFs. */
   2777	if (!mr_is_region(inbox->buf)) {
   2778		err = -EPERM;
   2779		goto ex_abort;
   2780	}
   2781
   2782	/* Make sure that the PD bits related to the slave id are zeros. */
   2783	pd = mr_get_pd(inbox->buf);
   2784	pd_slave = (pd >> 17) & 0x7f;
   2785	if (pd_slave != 0 && --pd_slave != slave) {
   2786		err = -EPERM;
   2787		goto ex_abort;
   2788	}
   2789
   2790	if (mr_is_fmr(inbox->buf)) {
   2791		/* FMR and Bind Enable are forbidden in slave devices. */
   2792		if (mr_is_bind_enabled(inbox->buf)) {
   2793			err = -EPERM;
   2794			goto ex_abort;
   2795		}
   2796		/* FMR and Memory Windows are also forbidden. */
   2797		if (!mr_is_region(inbox->buf)) {
   2798			err = -EPERM;
   2799			goto ex_abort;
   2800		}
   2801	}
   2802
   2803	phys = mr_phys_mpt(inbox->buf);
   2804	if (!phys) {
   2805		err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
   2806		if (err)
   2807			goto ex_abort;
   2808
   2809		err = check_mtt_range(dev, slave, mtt_base,
   2810				      mr_get_mtt_size(inbox->buf), mtt);
   2811		if (err)
   2812			goto ex_put;
   2813
   2814		mpt->mtt = mtt;
   2815	}
   2816
   2817	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   2818	if (err)
   2819		goto ex_put;
   2820
   2821	if (!phys) {
   2822		atomic_inc(&mtt->ref_count);
   2823		put_res(dev, slave, mtt->com.res_id, RES_MTT);
   2824	}
   2825
   2826	res_end_move(dev, slave, RES_MPT, id);
   2827	return 0;
   2828
   2829ex_put:
   2830	if (!phys)
   2831		put_res(dev, slave, mtt->com.res_id, RES_MTT);
   2832ex_abort:
   2833	res_abort_move(dev, slave, RES_MPT, id);
   2834
   2835	return err;
   2836}
   2837
   2838int mlx4_HW2SW_MPT_wrapper(struct mlx4_dev *dev, int slave,
   2839			   struct mlx4_vhcr *vhcr,
   2840			   struct mlx4_cmd_mailbox *inbox,
   2841			   struct mlx4_cmd_mailbox *outbox,
   2842			   struct mlx4_cmd_info *cmd)
   2843{
   2844	int err;
   2845	int index = vhcr->in_modifier;
   2846	struct res_mpt *mpt;
   2847	int id;
   2848
   2849	id = index & mpt_mask(dev);
   2850	err = mr_res_start_move_to(dev, slave, id, RES_MPT_MAPPED, &mpt);
   2851	if (err)
   2852		return err;
   2853
   2854	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   2855	if (err)
   2856		goto ex_abort;
   2857
   2858	if (mpt->mtt)
   2859		atomic_dec(&mpt->mtt->ref_count);
   2860
   2861	res_end_move(dev, slave, RES_MPT, id);
   2862	return 0;
   2863
   2864ex_abort:
   2865	res_abort_move(dev, slave, RES_MPT, id);
   2866
   2867	return err;
   2868}
   2869
   2870int mlx4_QUERY_MPT_wrapper(struct mlx4_dev *dev, int slave,
   2871			   struct mlx4_vhcr *vhcr,
   2872			   struct mlx4_cmd_mailbox *inbox,
   2873			   struct mlx4_cmd_mailbox *outbox,
   2874			   struct mlx4_cmd_info *cmd)
   2875{
   2876	int err;
   2877	int index = vhcr->in_modifier;
   2878	struct res_mpt *mpt;
   2879	int id;
   2880
   2881	id = index & mpt_mask(dev);
   2882	err = get_res(dev, slave, id, RES_MPT, &mpt);
   2883	if (err)
   2884		return err;
   2885
   2886	if (mpt->com.from_state == RES_MPT_MAPPED) {
   2887		/* In order to allow rereg in SRIOV, we need to alter the MPT entry. To do
   2888		 * that, the VF must read the MPT. But since the MPT entry memory is not
   2889		 * in the VF's virtual memory space, it must use QUERY_MPT to obtain the
   2890		 * entry contents. To guarantee that the MPT cannot be changed, the driver
   2891		 * must perform HW2SW_MPT before this query and return the MPT entry to HW
   2892		 * ownership fofollowing the change. The change here allows the VF to
   2893		 * perform QUERY_MPT also when the entry is in SW ownership.
   2894		 */
   2895		struct mlx4_mpt_entry *mpt_entry = mlx4_table_find(
   2896					&mlx4_priv(dev)->mr_table.dmpt_table,
   2897					mpt->key, NULL);
   2898
   2899		if (NULL == mpt_entry || NULL == outbox->buf) {
   2900			err = -EINVAL;
   2901			goto out;
   2902		}
   2903
   2904		memcpy(outbox->buf, mpt_entry, sizeof(*mpt_entry));
   2905
   2906		err = 0;
   2907	} else if (mpt->com.from_state == RES_MPT_HW) {
   2908		err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   2909	} else {
   2910		err = -EBUSY;
   2911		goto out;
   2912	}
   2913
   2914
   2915out:
   2916	put_res(dev, slave, id, RES_MPT);
   2917	return err;
   2918}
   2919
   2920static int qp_get_rcqn(struct mlx4_qp_context *qpc)
   2921{
   2922	return be32_to_cpu(qpc->cqn_recv) & 0xffffff;
   2923}
   2924
   2925static int qp_get_scqn(struct mlx4_qp_context *qpc)
   2926{
   2927	return be32_to_cpu(qpc->cqn_send) & 0xffffff;
   2928}
   2929
   2930static u32 qp_get_srqn(struct mlx4_qp_context *qpc)
   2931{
   2932	return be32_to_cpu(qpc->srqn) & 0x1ffffff;
   2933}
   2934
   2935static void adjust_proxy_tun_qkey(struct mlx4_dev *dev, struct mlx4_vhcr *vhcr,
   2936				  struct mlx4_qp_context *context)
   2937{
   2938	u32 qpn = vhcr->in_modifier & 0xffffff;
   2939	u32 qkey = 0;
   2940
   2941	if (mlx4_get_parav_qkey(dev, qpn, &qkey))
   2942		return;
   2943
   2944	/* adjust qkey in qp context */
   2945	context->qkey = cpu_to_be32(qkey);
   2946}
   2947
   2948static int adjust_qp_sched_queue(struct mlx4_dev *dev, int slave,
   2949				 struct mlx4_qp_context *qpc,
   2950				 struct mlx4_cmd_mailbox *inbox);
   2951
   2952int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
   2953			     struct mlx4_vhcr *vhcr,
   2954			     struct mlx4_cmd_mailbox *inbox,
   2955			     struct mlx4_cmd_mailbox *outbox,
   2956			     struct mlx4_cmd_info *cmd)
   2957{
   2958	int err;
   2959	int qpn = vhcr->in_modifier & 0x7fffff;
   2960	struct res_mtt *mtt;
   2961	struct res_qp *qp;
   2962	struct mlx4_qp_context *qpc = inbox->buf + 8;
   2963	int mtt_base = qp_get_mtt_addr(qpc) / dev->caps.mtt_entry_sz;
   2964	int mtt_size = qp_get_mtt_size(qpc);
   2965	struct res_cq *rcq;
   2966	struct res_cq *scq;
   2967	int rcqn = qp_get_rcqn(qpc);
   2968	int scqn = qp_get_scqn(qpc);
   2969	u32 srqn = qp_get_srqn(qpc) & 0xffffff;
   2970	int use_srq = (qp_get_srqn(qpc) >> 24) & 1;
   2971	struct res_srq *srq;
   2972	int local_qpn = vhcr->in_modifier & 0xffffff;
   2973
   2974	err = adjust_qp_sched_queue(dev, slave, qpc, inbox);
   2975	if (err)
   2976		return err;
   2977
   2978	err = qp_res_start_move_to(dev, slave, qpn, RES_QP_HW, &qp, 0);
   2979	if (err)
   2980		return err;
   2981	qp->local_qpn = local_qpn;
   2982	qp->sched_queue = 0;
   2983	qp->param3 = 0;
   2984	qp->vlan_control = 0;
   2985	qp->fvl_rx = 0;
   2986	qp->pri_path_fl = 0;
   2987	qp->vlan_index = 0;
   2988	qp->feup = 0;
   2989	qp->qpc_flags = be32_to_cpu(qpc->flags);
   2990
   2991	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
   2992	if (err)
   2993		goto ex_abort;
   2994
   2995	err = check_mtt_range(dev, slave, mtt_base, mtt_size, mtt);
   2996	if (err)
   2997		goto ex_put_mtt;
   2998
   2999	err = get_res(dev, slave, rcqn, RES_CQ, &rcq);
   3000	if (err)
   3001		goto ex_put_mtt;
   3002
   3003	if (scqn != rcqn) {
   3004		err = get_res(dev, slave, scqn, RES_CQ, &scq);
   3005		if (err)
   3006			goto ex_put_rcq;
   3007	} else
   3008		scq = rcq;
   3009
   3010	if (use_srq) {
   3011		err = get_res(dev, slave, srqn, RES_SRQ, &srq);
   3012		if (err)
   3013			goto ex_put_scq;
   3014	}
   3015
   3016	adjust_proxy_tun_qkey(dev, vhcr, qpc);
   3017	update_pkey_index(dev, slave, inbox);
   3018	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3019	if (err)
   3020		goto ex_put_srq;
   3021	atomic_inc(&mtt->ref_count);
   3022	qp->mtt = mtt;
   3023	atomic_inc(&rcq->ref_count);
   3024	qp->rcq = rcq;
   3025	atomic_inc(&scq->ref_count);
   3026	qp->scq = scq;
   3027
   3028	if (scqn != rcqn)
   3029		put_res(dev, slave, scqn, RES_CQ);
   3030
   3031	if (use_srq) {
   3032		atomic_inc(&srq->ref_count);
   3033		put_res(dev, slave, srqn, RES_SRQ);
   3034		qp->srq = srq;
   3035	}
   3036
   3037	/* Save param3 for dynamic changes from VST back to VGT */
   3038	qp->param3 = qpc->param3;
   3039	put_res(dev, slave, rcqn, RES_CQ);
   3040	put_res(dev, slave, mtt_base, RES_MTT);
   3041	res_end_move(dev, slave, RES_QP, qpn);
   3042
   3043	return 0;
   3044
   3045ex_put_srq:
   3046	if (use_srq)
   3047		put_res(dev, slave, srqn, RES_SRQ);
   3048ex_put_scq:
   3049	if (scqn != rcqn)
   3050		put_res(dev, slave, scqn, RES_CQ);
   3051ex_put_rcq:
   3052	put_res(dev, slave, rcqn, RES_CQ);
   3053ex_put_mtt:
   3054	put_res(dev, slave, mtt_base, RES_MTT);
   3055ex_abort:
   3056	res_abort_move(dev, slave, RES_QP, qpn);
   3057
   3058	return err;
   3059}
   3060
   3061static int eq_get_mtt_addr(struct mlx4_eq_context *eqc)
   3062{
   3063	return be32_to_cpu(eqc->mtt_base_addr_l) & 0xfffffff8;
   3064}
   3065
   3066static int eq_get_mtt_size(struct mlx4_eq_context *eqc)
   3067{
   3068	int log_eq_size = eqc->log_eq_size & 0x1f;
   3069	int page_shift = (eqc->log_page_size & 0x3f) + 12;
   3070
   3071	if (log_eq_size + 5 < page_shift)
   3072		return 1;
   3073
   3074	return 1 << (log_eq_size + 5 - page_shift);
   3075}
   3076
   3077static int cq_get_mtt_addr(struct mlx4_cq_context *cqc)
   3078{
   3079	return be32_to_cpu(cqc->mtt_base_addr_l) & 0xfffffff8;
   3080}
   3081
   3082static int cq_get_mtt_size(struct mlx4_cq_context *cqc)
   3083{
   3084	int log_cq_size = (be32_to_cpu(cqc->logsize_usrpage) >> 24) & 0x1f;
   3085	int page_shift = (cqc->log_page_size & 0x3f) + 12;
   3086
   3087	if (log_cq_size + 5 < page_shift)
   3088		return 1;
   3089
   3090	return 1 << (log_cq_size + 5 - page_shift);
   3091}
   3092
   3093int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave,
   3094			  struct mlx4_vhcr *vhcr,
   3095			  struct mlx4_cmd_mailbox *inbox,
   3096			  struct mlx4_cmd_mailbox *outbox,
   3097			  struct mlx4_cmd_info *cmd)
   3098{
   3099	int err;
   3100	int eqn = vhcr->in_modifier;
   3101	int res_id = (slave << 10) | eqn;
   3102	struct mlx4_eq_context *eqc = inbox->buf;
   3103	int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz;
   3104	int mtt_size = eq_get_mtt_size(eqc);
   3105	struct res_eq *eq;
   3106	struct res_mtt *mtt;
   3107
   3108	err = add_res_range(dev, slave, res_id, 1, RES_EQ, 0);
   3109	if (err)
   3110		return err;
   3111	err = eq_res_start_move_to(dev, slave, res_id, RES_EQ_HW, &eq);
   3112	if (err)
   3113		goto out_add;
   3114
   3115	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
   3116	if (err)
   3117		goto out_move;
   3118
   3119	err = check_mtt_range(dev, slave, mtt_base, mtt_size, mtt);
   3120	if (err)
   3121		goto out_put;
   3122
   3123	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3124	if (err)
   3125		goto out_put;
   3126
   3127	atomic_inc(&mtt->ref_count);
   3128	eq->mtt = mtt;
   3129	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3130	res_end_move(dev, slave, RES_EQ, res_id);
   3131	return 0;
   3132
   3133out_put:
   3134	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3135out_move:
   3136	res_abort_move(dev, slave, RES_EQ, res_id);
   3137out_add:
   3138	rem_res_range(dev, slave, res_id, 1, RES_EQ, 0);
   3139	return err;
   3140}
   3141
   3142int mlx4_CONFIG_DEV_wrapper(struct mlx4_dev *dev, int slave,
   3143			    struct mlx4_vhcr *vhcr,
   3144			    struct mlx4_cmd_mailbox *inbox,
   3145			    struct mlx4_cmd_mailbox *outbox,
   3146			    struct mlx4_cmd_info *cmd)
   3147{
   3148	int err;
   3149	u8 get = vhcr->op_modifier;
   3150
   3151	if (get != 1)
   3152		return -EPERM;
   3153
   3154	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3155
   3156	return err;
   3157}
   3158
   3159static int get_containing_mtt(struct mlx4_dev *dev, int slave, int start,
   3160			      int len, struct res_mtt **res)
   3161{
   3162	struct mlx4_priv *priv = mlx4_priv(dev);
   3163	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   3164	struct res_mtt *mtt;
   3165	int err = -EINVAL;
   3166
   3167	spin_lock_irq(mlx4_tlock(dev));
   3168	list_for_each_entry(mtt, &tracker->slave_list[slave].res_list[RES_MTT],
   3169			    com.list) {
   3170		if (!check_mtt_range(dev, slave, start, len, mtt)) {
   3171			*res = mtt;
   3172			mtt->com.from_state = mtt->com.state;
   3173			mtt->com.state = RES_MTT_BUSY;
   3174			err = 0;
   3175			break;
   3176		}
   3177	}
   3178	spin_unlock_irq(mlx4_tlock(dev));
   3179
   3180	return err;
   3181}
   3182
   3183static int verify_qp_parameters(struct mlx4_dev *dev,
   3184				struct mlx4_vhcr *vhcr,
   3185				struct mlx4_cmd_mailbox *inbox,
   3186				enum qp_transition transition, u8 slave)
   3187{
   3188	u32			qp_type;
   3189	u32			qpn;
   3190	struct mlx4_qp_context	*qp_ctx;
   3191	enum mlx4_qp_optpar	optpar;
   3192	int port;
   3193	int num_gids;
   3194
   3195	qp_ctx  = inbox->buf + 8;
   3196	qp_type	= (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
   3197	optpar	= be32_to_cpu(*(__be32 *) inbox->buf);
   3198
   3199	if (slave != mlx4_master_func_num(dev)) {
   3200		qp_ctx->params2 &= ~cpu_to_be32(MLX4_QP_BIT_FPP);
   3201		/* setting QP rate-limit is disallowed for VFs */
   3202		if (qp_ctx->rate_limit_params)
   3203			return -EPERM;
   3204	}
   3205
   3206	switch (qp_type) {
   3207	case MLX4_QP_ST_RC:
   3208	case MLX4_QP_ST_XRC:
   3209	case MLX4_QP_ST_UC:
   3210		switch (transition) {
   3211		case QP_TRANS_INIT2RTR:
   3212		case QP_TRANS_RTR2RTS:
   3213		case QP_TRANS_RTS2RTS:
   3214		case QP_TRANS_SQD2SQD:
   3215		case QP_TRANS_SQD2RTS:
   3216			if (slave != mlx4_master_func_num(dev)) {
   3217				if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) {
   3218					port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
   3219					if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB)
   3220						num_gids = mlx4_get_slave_num_gids(dev, slave, port);
   3221					else
   3222						num_gids = 1;
   3223					if (qp_ctx->pri_path.mgid_index >= num_gids)
   3224						return -EINVAL;
   3225				}
   3226				if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
   3227					port = (qp_ctx->alt_path.sched_queue >> 6 & 1) + 1;
   3228					if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB)
   3229						num_gids = mlx4_get_slave_num_gids(dev, slave, port);
   3230					else
   3231						num_gids = 1;
   3232					if (qp_ctx->alt_path.mgid_index >= num_gids)
   3233						return -EINVAL;
   3234				}
   3235			}
   3236			break;
   3237		default:
   3238			break;
   3239		}
   3240		break;
   3241
   3242	case MLX4_QP_ST_MLX:
   3243		qpn = vhcr->in_modifier & 0x7fffff;
   3244		port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
   3245		if (transition == QP_TRANS_INIT2RTR &&
   3246		    slave != mlx4_master_func_num(dev) &&
   3247		    mlx4_is_qp_reserved(dev, qpn) &&
   3248		    !mlx4_vf_smi_enabled(dev, slave, port)) {
   3249			/* only enabled VFs may create MLX proxy QPs */
   3250			mlx4_err(dev, "%s: unprivileged slave %d attempting to create an MLX proxy special QP on port %d\n",
   3251				 __func__, slave, port);
   3252			return -EPERM;
   3253		}
   3254		break;
   3255
   3256	default:
   3257		break;
   3258	}
   3259
   3260	return 0;
   3261}
   3262
   3263int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave,
   3264			   struct mlx4_vhcr *vhcr,
   3265			   struct mlx4_cmd_mailbox *inbox,
   3266			   struct mlx4_cmd_mailbox *outbox,
   3267			   struct mlx4_cmd_info *cmd)
   3268{
   3269	struct mlx4_mtt mtt;
   3270	__be64 *page_list = inbox->buf;
   3271	u64 *pg_list = (u64 *)page_list;
   3272	int i;
   3273	struct res_mtt *rmtt = NULL;
   3274	int start = be64_to_cpu(page_list[0]);
   3275	int npages = vhcr->in_modifier;
   3276	int err;
   3277
   3278	err = get_containing_mtt(dev, slave, start, npages, &rmtt);
   3279	if (err)
   3280		return err;
   3281
   3282	/* Call the SW implementation of write_mtt:
   3283	 * - Prepare a dummy mtt struct
   3284	 * - Translate inbox contents to simple addresses in host endianness */
   3285	mtt.offset = 0;  /* TBD this is broken but I don't handle it since
   3286			    we don't really use it */
   3287	mtt.order = 0;
   3288	mtt.page_shift = 0;
   3289	for (i = 0; i < npages; ++i)
   3290		pg_list[i + 2] = (be64_to_cpu(page_list[i + 2]) & ~1ULL);
   3291
   3292	err = __mlx4_write_mtt(dev, &mtt, be64_to_cpu(page_list[0]), npages,
   3293			       ((u64 *)page_list + 2));
   3294
   3295	if (rmtt)
   3296		put_res(dev, slave, rmtt->com.res_id, RES_MTT);
   3297
   3298	return err;
   3299}
   3300
   3301int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave,
   3302			  struct mlx4_vhcr *vhcr,
   3303			  struct mlx4_cmd_mailbox *inbox,
   3304			  struct mlx4_cmd_mailbox *outbox,
   3305			  struct mlx4_cmd_info *cmd)
   3306{
   3307	int eqn = vhcr->in_modifier;
   3308	int res_id = eqn | (slave << 10);
   3309	struct res_eq *eq;
   3310	int err;
   3311
   3312	err = eq_res_start_move_to(dev, slave, res_id, RES_EQ_RESERVED, &eq);
   3313	if (err)
   3314		return err;
   3315
   3316	err = get_res(dev, slave, eq->mtt->com.res_id, RES_MTT, NULL);
   3317	if (err)
   3318		goto ex_abort;
   3319
   3320	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3321	if (err)
   3322		goto ex_put;
   3323
   3324	atomic_dec(&eq->mtt->ref_count);
   3325	put_res(dev, slave, eq->mtt->com.res_id, RES_MTT);
   3326	res_end_move(dev, slave, RES_EQ, res_id);
   3327	rem_res_range(dev, slave, res_id, 1, RES_EQ, 0);
   3328
   3329	return 0;
   3330
   3331ex_put:
   3332	put_res(dev, slave, eq->mtt->com.res_id, RES_MTT);
   3333ex_abort:
   3334	res_abort_move(dev, slave, RES_EQ, res_id);
   3335
   3336	return err;
   3337}
   3338
   3339int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
   3340{
   3341	struct mlx4_priv *priv = mlx4_priv(dev);
   3342	struct mlx4_slave_event_eq_info *event_eq;
   3343	struct mlx4_cmd_mailbox *mailbox;
   3344	u32 in_modifier = 0;
   3345	int err;
   3346	int res_id;
   3347	struct res_eq *req;
   3348
   3349	if (!priv->mfunc.master.slave_state)
   3350		return -EINVAL;
   3351
   3352	/* check for slave valid, slave not PF, and slave active */
   3353	if (slave < 0 || slave > dev->persist->num_vfs ||
   3354	    slave == dev->caps.function ||
   3355	    !priv->mfunc.master.slave_state[slave].active)
   3356		return 0;
   3357
   3358	event_eq = &priv->mfunc.master.slave_state[slave].event_eq[eqe->type];
   3359
   3360	/* Create the event only if the slave is registered */
   3361	if (event_eq->eqn < 0)
   3362		return 0;
   3363
   3364	mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]);
   3365	res_id = (slave << 10) | event_eq->eqn;
   3366	err = get_res(dev, slave, res_id, RES_EQ, &req);
   3367	if (err)
   3368		goto unlock;
   3369
   3370	if (req->com.from_state != RES_EQ_HW) {
   3371		err = -EINVAL;
   3372		goto put;
   3373	}
   3374
   3375	mailbox = mlx4_alloc_cmd_mailbox(dev);
   3376	if (IS_ERR(mailbox)) {
   3377		err = PTR_ERR(mailbox);
   3378		goto put;
   3379	}
   3380
   3381	if (eqe->type == MLX4_EVENT_TYPE_CMD) {
   3382		++event_eq->token;
   3383		eqe->event.cmd.token = cpu_to_be16(event_eq->token);
   3384	}
   3385
   3386	memcpy(mailbox->buf, (u8 *) eqe, 28);
   3387
   3388	in_modifier = (slave & 0xff) | ((event_eq->eqn & 0x3ff) << 16);
   3389
   3390	err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0,
   3391		       MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B,
   3392		       MLX4_CMD_NATIVE);
   3393
   3394	put_res(dev, slave, res_id, RES_EQ);
   3395	mutex_unlock(&priv->mfunc.master.gen_eqe_mutex[slave]);
   3396	mlx4_free_cmd_mailbox(dev, mailbox);
   3397	return err;
   3398
   3399put:
   3400	put_res(dev, slave, res_id, RES_EQ);
   3401
   3402unlock:
   3403	mutex_unlock(&priv->mfunc.master.gen_eqe_mutex[slave]);
   3404	return err;
   3405}
   3406
   3407int mlx4_QUERY_EQ_wrapper(struct mlx4_dev *dev, int slave,
   3408			  struct mlx4_vhcr *vhcr,
   3409			  struct mlx4_cmd_mailbox *inbox,
   3410			  struct mlx4_cmd_mailbox *outbox,
   3411			  struct mlx4_cmd_info *cmd)
   3412{
   3413	int eqn = vhcr->in_modifier;
   3414	int res_id = eqn | (slave << 10);
   3415	struct res_eq *eq;
   3416	int err;
   3417
   3418	err = get_res(dev, slave, res_id, RES_EQ, &eq);
   3419	if (err)
   3420		return err;
   3421
   3422	if (eq->com.from_state != RES_EQ_HW) {
   3423		err = -EINVAL;
   3424		goto ex_put;
   3425	}
   3426
   3427	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3428
   3429ex_put:
   3430	put_res(dev, slave, res_id, RES_EQ);
   3431	return err;
   3432}
   3433
   3434int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev *dev, int slave,
   3435			  struct mlx4_vhcr *vhcr,
   3436			  struct mlx4_cmd_mailbox *inbox,
   3437			  struct mlx4_cmd_mailbox *outbox,
   3438			  struct mlx4_cmd_info *cmd)
   3439{
   3440	int err;
   3441	int cqn = vhcr->in_modifier;
   3442	struct mlx4_cq_context *cqc = inbox->buf;
   3443	int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
   3444	struct res_cq *cq = NULL;
   3445	struct res_mtt *mtt;
   3446
   3447	err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_HW, &cq);
   3448	if (err)
   3449		return err;
   3450	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
   3451	if (err)
   3452		goto out_move;
   3453	err = check_mtt_range(dev, slave, mtt_base, cq_get_mtt_size(cqc), mtt);
   3454	if (err)
   3455		goto out_put;
   3456	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3457	if (err)
   3458		goto out_put;
   3459	atomic_inc(&mtt->ref_count);
   3460	cq->mtt = mtt;
   3461	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3462	res_end_move(dev, slave, RES_CQ, cqn);
   3463	return 0;
   3464
   3465out_put:
   3466	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3467out_move:
   3468	res_abort_move(dev, slave, RES_CQ, cqn);
   3469	return err;
   3470}
   3471
   3472int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev *dev, int slave,
   3473			  struct mlx4_vhcr *vhcr,
   3474			  struct mlx4_cmd_mailbox *inbox,
   3475			  struct mlx4_cmd_mailbox *outbox,
   3476			  struct mlx4_cmd_info *cmd)
   3477{
   3478	int err;
   3479	int cqn = vhcr->in_modifier;
   3480	struct res_cq *cq = NULL;
   3481
   3482	err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_ALLOCATED, &cq);
   3483	if (err)
   3484		return err;
   3485	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3486	if (err)
   3487		goto out_move;
   3488	atomic_dec(&cq->mtt->ref_count);
   3489	res_end_move(dev, slave, RES_CQ, cqn);
   3490	return 0;
   3491
   3492out_move:
   3493	res_abort_move(dev, slave, RES_CQ, cqn);
   3494	return err;
   3495}
   3496
   3497int mlx4_QUERY_CQ_wrapper(struct mlx4_dev *dev, int slave,
   3498			  struct mlx4_vhcr *vhcr,
   3499			  struct mlx4_cmd_mailbox *inbox,
   3500			  struct mlx4_cmd_mailbox *outbox,
   3501			  struct mlx4_cmd_info *cmd)
   3502{
   3503	int cqn = vhcr->in_modifier;
   3504	struct res_cq *cq;
   3505	int err;
   3506
   3507	err = get_res(dev, slave, cqn, RES_CQ, &cq);
   3508	if (err)
   3509		return err;
   3510
   3511	if (cq->com.from_state != RES_CQ_HW)
   3512		goto ex_put;
   3513
   3514	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3515ex_put:
   3516	put_res(dev, slave, cqn, RES_CQ);
   3517
   3518	return err;
   3519}
   3520
   3521static int handle_resize(struct mlx4_dev *dev, int slave,
   3522			 struct mlx4_vhcr *vhcr,
   3523			 struct mlx4_cmd_mailbox *inbox,
   3524			 struct mlx4_cmd_mailbox *outbox,
   3525			 struct mlx4_cmd_info *cmd,
   3526			 struct res_cq *cq)
   3527{
   3528	int err;
   3529	struct res_mtt *orig_mtt;
   3530	struct res_mtt *mtt;
   3531	struct mlx4_cq_context *cqc = inbox->buf;
   3532	int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
   3533
   3534	err = get_res(dev, slave, cq->mtt->com.res_id, RES_MTT, &orig_mtt);
   3535	if (err)
   3536		return err;
   3537
   3538	if (orig_mtt != cq->mtt) {
   3539		err = -EINVAL;
   3540		goto ex_put;
   3541	}
   3542
   3543	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
   3544	if (err)
   3545		goto ex_put;
   3546
   3547	err = check_mtt_range(dev, slave, mtt_base, cq_get_mtt_size(cqc), mtt);
   3548	if (err)
   3549		goto ex_put1;
   3550	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3551	if (err)
   3552		goto ex_put1;
   3553	atomic_dec(&orig_mtt->ref_count);
   3554	put_res(dev, slave, orig_mtt->com.res_id, RES_MTT);
   3555	atomic_inc(&mtt->ref_count);
   3556	cq->mtt = mtt;
   3557	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3558	return 0;
   3559
   3560ex_put1:
   3561	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3562ex_put:
   3563	put_res(dev, slave, orig_mtt->com.res_id, RES_MTT);
   3564
   3565	return err;
   3566
   3567}
   3568
   3569int mlx4_MODIFY_CQ_wrapper(struct mlx4_dev *dev, int slave,
   3570			   struct mlx4_vhcr *vhcr,
   3571			   struct mlx4_cmd_mailbox *inbox,
   3572			   struct mlx4_cmd_mailbox *outbox,
   3573			   struct mlx4_cmd_info *cmd)
   3574{
   3575	int cqn = vhcr->in_modifier;
   3576	struct res_cq *cq;
   3577	int err;
   3578
   3579	err = get_res(dev, slave, cqn, RES_CQ, &cq);
   3580	if (err)
   3581		return err;
   3582
   3583	if (cq->com.from_state != RES_CQ_HW)
   3584		goto ex_put;
   3585
   3586	if (vhcr->op_modifier == 0) {
   3587		err = handle_resize(dev, slave, vhcr, inbox, outbox, cmd, cq);
   3588		goto ex_put;
   3589	}
   3590
   3591	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3592ex_put:
   3593	put_res(dev, slave, cqn, RES_CQ);
   3594
   3595	return err;
   3596}
   3597
   3598static int srq_get_mtt_size(struct mlx4_srq_context *srqc)
   3599{
   3600	int log_srq_size = (be32_to_cpu(srqc->state_logsize_srqn) >> 24) & 0xf;
   3601	int log_rq_stride = srqc->logstride & 7;
   3602	int page_shift = (srqc->log_page_size & 0x3f) + 12;
   3603
   3604	if (log_srq_size + log_rq_stride + 4 < page_shift)
   3605		return 1;
   3606
   3607	return 1 << (log_srq_size + log_rq_stride + 4 - page_shift);
   3608}
   3609
   3610int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
   3611			   struct mlx4_vhcr *vhcr,
   3612			   struct mlx4_cmd_mailbox *inbox,
   3613			   struct mlx4_cmd_mailbox *outbox,
   3614			   struct mlx4_cmd_info *cmd)
   3615{
   3616	int err;
   3617	int srqn = vhcr->in_modifier;
   3618	struct res_mtt *mtt;
   3619	struct res_srq *srq = NULL;
   3620	struct mlx4_srq_context *srqc = inbox->buf;
   3621	int mtt_base = srq_get_mtt_addr(srqc) / dev->caps.mtt_entry_sz;
   3622
   3623	if (srqn != (be32_to_cpu(srqc->state_logsize_srqn) & 0xffffff))
   3624		return -EINVAL;
   3625
   3626	err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_HW, &srq);
   3627	if (err)
   3628		return err;
   3629	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
   3630	if (err)
   3631		goto ex_abort;
   3632	err = check_mtt_range(dev, slave, mtt_base, srq_get_mtt_size(srqc),
   3633			      mtt);
   3634	if (err)
   3635		goto ex_put_mtt;
   3636
   3637	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3638	if (err)
   3639		goto ex_put_mtt;
   3640
   3641	atomic_inc(&mtt->ref_count);
   3642	srq->mtt = mtt;
   3643	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3644	res_end_move(dev, slave, RES_SRQ, srqn);
   3645	return 0;
   3646
   3647ex_put_mtt:
   3648	put_res(dev, slave, mtt->com.res_id, RES_MTT);
   3649ex_abort:
   3650	res_abort_move(dev, slave, RES_SRQ, srqn);
   3651
   3652	return err;
   3653}
   3654
   3655int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
   3656			   struct mlx4_vhcr *vhcr,
   3657			   struct mlx4_cmd_mailbox *inbox,
   3658			   struct mlx4_cmd_mailbox *outbox,
   3659			   struct mlx4_cmd_info *cmd)
   3660{
   3661	int err;
   3662	int srqn = vhcr->in_modifier;
   3663	struct res_srq *srq = NULL;
   3664
   3665	err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_ALLOCATED, &srq);
   3666	if (err)
   3667		return err;
   3668	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3669	if (err)
   3670		goto ex_abort;
   3671	atomic_dec(&srq->mtt->ref_count);
   3672	if (srq->cq)
   3673		atomic_dec(&srq->cq->ref_count);
   3674	res_end_move(dev, slave, RES_SRQ, srqn);
   3675
   3676	return 0;
   3677
   3678ex_abort:
   3679	res_abort_move(dev, slave, RES_SRQ, srqn);
   3680
   3681	return err;
   3682}
   3683
   3684int mlx4_QUERY_SRQ_wrapper(struct mlx4_dev *dev, int slave,
   3685			   struct mlx4_vhcr *vhcr,
   3686			   struct mlx4_cmd_mailbox *inbox,
   3687			   struct mlx4_cmd_mailbox *outbox,
   3688			   struct mlx4_cmd_info *cmd)
   3689{
   3690	int err;
   3691	int srqn = vhcr->in_modifier;
   3692	struct res_srq *srq;
   3693
   3694	err = get_res(dev, slave, srqn, RES_SRQ, &srq);
   3695	if (err)
   3696		return err;
   3697	if (srq->com.from_state != RES_SRQ_HW) {
   3698		err = -EBUSY;
   3699		goto out;
   3700	}
   3701	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3702out:
   3703	put_res(dev, slave, srqn, RES_SRQ);
   3704	return err;
   3705}
   3706
   3707int mlx4_ARM_SRQ_wrapper(struct mlx4_dev *dev, int slave,
   3708			 struct mlx4_vhcr *vhcr,
   3709			 struct mlx4_cmd_mailbox *inbox,
   3710			 struct mlx4_cmd_mailbox *outbox,
   3711			 struct mlx4_cmd_info *cmd)
   3712{
   3713	int err;
   3714	int srqn = vhcr->in_modifier;
   3715	struct res_srq *srq;
   3716
   3717	err = get_res(dev, slave, srqn, RES_SRQ, &srq);
   3718	if (err)
   3719		return err;
   3720
   3721	if (srq->com.from_state != RES_SRQ_HW) {
   3722		err = -EBUSY;
   3723		goto out;
   3724	}
   3725
   3726	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3727out:
   3728	put_res(dev, slave, srqn, RES_SRQ);
   3729	return err;
   3730}
   3731
   3732int mlx4_GEN_QP_wrapper(struct mlx4_dev *dev, int slave,
   3733			struct mlx4_vhcr *vhcr,
   3734			struct mlx4_cmd_mailbox *inbox,
   3735			struct mlx4_cmd_mailbox *outbox,
   3736			struct mlx4_cmd_info *cmd)
   3737{
   3738	int err;
   3739	int qpn = vhcr->in_modifier & 0x7fffff;
   3740	struct res_qp *qp;
   3741
   3742	err = get_res(dev, slave, qpn, RES_QP, &qp);
   3743	if (err)
   3744		return err;
   3745	if (qp->com.from_state != RES_QP_HW) {
   3746		err = -EBUSY;
   3747		goto out;
   3748	}
   3749
   3750	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3751out:
   3752	put_res(dev, slave, qpn, RES_QP);
   3753	return err;
   3754}
   3755
   3756int mlx4_INIT2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
   3757			      struct mlx4_vhcr *vhcr,
   3758			      struct mlx4_cmd_mailbox *inbox,
   3759			      struct mlx4_cmd_mailbox *outbox,
   3760			      struct mlx4_cmd_info *cmd)
   3761{
   3762	struct mlx4_qp_context *context = inbox->buf + 8;
   3763	adjust_proxy_tun_qkey(dev, vhcr, context);
   3764	update_pkey_index(dev, slave, inbox);
   3765	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3766}
   3767
   3768static int adjust_qp_sched_queue(struct mlx4_dev *dev, int slave,
   3769				  struct mlx4_qp_context *qpc,
   3770				  struct mlx4_cmd_mailbox *inbox)
   3771{
   3772	enum mlx4_qp_optpar optpar = be32_to_cpu(*(__be32 *)inbox->buf);
   3773	u8 pri_sched_queue;
   3774	int port = mlx4_slave_convert_port(
   3775		   dev, slave, (qpc->pri_path.sched_queue >> 6 & 1) + 1) - 1;
   3776
   3777	if (port < 0)
   3778		return -EINVAL;
   3779
   3780	pri_sched_queue = (qpc->pri_path.sched_queue & ~(1 << 6)) |
   3781			  ((port & 1) << 6);
   3782
   3783	if (optpar & (MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH | MLX4_QP_OPTPAR_SCHED_QUEUE) ||
   3784	    qpc->pri_path.sched_queue || mlx4_is_eth(dev, port + 1)) {
   3785		qpc->pri_path.sched_queue = pri_sched_queue;
   3786	}
   3787
   3788	if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
   3789		port = mlx4_slave_convert_port(
   3790				dev, slave, (qpc->alt_path.sched_queue >> 6 & 1)
   3791				+ 1) - 1;
   3792		if (port < 0)
   3793			return -EINVAL;
   3794		qpc->alt_path.sched_queue =
   3795			(qpc->alt_path.sched_queue & ~(1 << 6)) |
   3796			(port & 1) << 6;
   3797	}
   3798	return 0;
   3799}
   3800
   3801static int roce_verify_mac(struct mlx4_dev *dev, int slave,
   3802				struct mlx4_qp_context *qpc,
   3803				struct mlx4_cmd_mailbox *inbox)
   3804{
   3805	u64 mac;
   3806	int port;
   3807	u32 ts = (be32_to_cpu(qpc->flags) >> 16) & 0xff;
   3808	u8 sched = *(u8 *)(inbox->buf + 64);
   3809	u8 smac_ix;
   3810
   3811	port = (sched >> 6 & 1) + 1;
   3812	if (mlx4_is_eth(dev, port) && (ts != MLX4_QP_ST_MLX)) {
   3813		smac_ix = qpc->pri_path.grh_mylmc & 0x7f;
   3814		if (mac_find_smac_ix_in_slave(dev, slave, port, smac_ix, &mac))
   3815			return -ENOENT;
   3816	}
   3817	return 0;
   3818}
   3819
   3820int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
   3821			     struct mlx4_vhcr *vhcr,
   3822			     struct mlx4_cmd_mailbox *inbox,
   3823			     struct mlx4_cmd_mailbox *outbox,
   3824			     struct mlx4_cmd_info *cmd)
   3825{
   3826	int err;
   3827	struct mlx4_qp_context *qpc = inbox->buf + 8;
   3828	int qpn = vhcr->in_modifier & 0x7fffff;
   3829	struct res_qp *qp;
   3830	u8 orig_sched_queue;
   3831	u8 orig_vlan_control = qpc->pri_path.vlan_control;
   3832	u8 orig_fvl_rx = qpc->pri_path.fvl_rx;
   3833	u8 orig_pri_path_fl = qpc->pri_path.fl;
   3834	u8 orig_vlan_index = qpc->pri_path.vlan_index;
   3835	u8 orig_feup = qpc->pri_path.feup;
   3836
   3837	err = adjust_qp_sched_queue(dev, slave, qpc, inbox);
   3838	if (err)
   3839		return err;
   3840	err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_INIT2RTR, slave);
   3841	if (err)
   3842		return err;
   3843
   3844	if (roce_verify_mac(dev, slave, qpc, inbox))
   3845		return -EINVAL;
   3846
   3847	update_pkey_index(dev, slave, inbox);
   3848	update_gid(dev, inbox, (u8)slave);
   3849	adjust_proxy_tun_qkey(dev, vhcr, qpc);
   3850	orig_sched_queue = qpc->pri_path.sched_queue;
   3851
   3852	err = get_res(dev, slave, qpn, RES_QP, &qp);
   3853	if (err)
   3854		return err;
   3855	if (qp->com.from_state != RES_QP_HW) {
   3856		err = -EBUSY;
   3857		goto out;
   3858	}
   3859
   3860	err = update_vport_qp_param(dev, inbox, slave, qpn);
   3861	if (err)
   3862		goto out;
   3863
   3864	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3865out:
   3866	/* if no error, save sched queue value passed in by VF. This is
   3867	 * essentially the QOS value provided by the VF. This will be useful
   3868	 * if we allow dynamic changes from VST back to VGT
   3869	 */
   3870	if (!err) {
   3871		qp->sched_queue = orig_sched_queue;
   3872		qp->vlan_control = orig_vlan_control;
   3873		qp->fvl_rx	=  orig_fvl_rx;
   3874		qp->pri_path_fl = orig_pri_path_fl;
   3875		qp->vlan_index  = orig_vlan_index;
   3876		qp->feup	= orig_feup;
   3877	}
   3878	put_res(dev, slave, qpn, RES_QP);
   3879	return err;
   3880}
   3881
   3882int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
   3883			    struct mlx4_vhcr *vhcr,
   3884			    struct mlx4_cmd_mailbox *inbox,
   3885			    struct mlx4_cmd_mailbox *outbox,
   3886			    struct mlx4_cmd_info *cmd)
   3887{
   3888	int err;
   3889	struct mlx4_qp_context *context = inbox->buf + 8;
   3890
   3891	err = adjust_qp_sched_queue(dev, slave, context, inbox);
   3892	if (err)
   3893		return err;
   3894	err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_RTR2RTS, slave);
   3895	if (err)
   3896		return err;
   3897
   3898	update_pkey_index(dev, slave, inbox);
   3899	update_gid(dev, inbox, (u8)slave);
   3900	adjust_proxy_tun_qkey(dev, vhcr, context);
   3901	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3902}
   3903
   3904int mlx4_RTS2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
   3905			    struct mlx4_vhcr *vhcr,
   3906			    struct mlx4_cmd_mailbox *inbox,
   3907			    struct mlx4_cmd_mailbox *outbox,
   3908			    struct mlx4_cmd_info *cmd)
   3909{
   3910	int err;
   3911	struct mlx4_qp_context *context = inbox->buf + 8;
   3912
   3913	err = adjust_qp_sched_queue(dev, slave, context, inbox);
   3914	if (err)
   3915		return err;
   3916	err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_RTS2RTS, slave);
   3917	if (err)
   3918		return err;
   3919
   3920	update_pkey_index(dev, slave, inbox);
   3921	update_gid(dev, inbox, (u8)slave);
   3922	adjust_proxy_tun_qkey(dev, vhcr, context);
   3923	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3924}
   3925
   3926
   3927int mlx4_SQERR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
   3928			      struct mlx4_vhcr *vhcr,
   3929			      struct mlx4_cmd_mailbox *inbox,
   3930			      struct mlx4_cmd_mailbox *outbox,
   3931			      struct mlx4_cmd_info *cmd)
   3932{
   3933	struct mlx4_qp_context *context = inbox->buf + 8;
   3934	int err = adjust_qp_sched_queue(dev, slave, context, inbox);
   3935	if (err)
   3936		return err;
   3937	adjust_proxy_tun_qkey(dev, vhcr, context);
   3938	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3939}
   3940
   3941int mlx4_SQD2SQD_QP_wrapper(struct mlx4_dev *dev, int slave,
   3942			    struct mlx4_vhcr *vhcr,
   3943			    struct mlx4_cmd_mailbox *inbox,
   3944			    struct mlx4_cmd_mailbox *outbox,
   3945			    struct mlx4_cmd_info *cmd)
   3946{
   3947	int err;
   3948	struct mlx4_qp_context *context = inbox->buf + 8;
   3949
   3950	err = adjust_qp_sched_queue(dev, slave, context, inbox);
   3951	if (err)
   3952		return err;
   3953	err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_SQD2SQD, slave);
   3954	if (err)
   3955		return err;
   3956
   3957	adjust_proxy_tun_qkey(dev, vhcr, context);
   3958	update_gid(dev, inbox, (u8)slave);
   3959	update_pkey_index(dev, slave, inbox);
   3960	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3961}
   3962
   3963int mlx4_SQD2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
   3964			    struct mlx4_vhcr *vhcr,
   3965			    struct mlx4_cmd_mailbox *inbox,
   3966			    struct mlx4_cmd_mailbox *outbox,
   3967			    struct mlx4_cmd_info *cmd)
   3968{
   3969	int err;
   3970	struct mlx4_qp_context *context = inbox->buf + 8;
   3971
   3972	err = adjust_qp_sched_queue(dev, slave, context, inbox);
   3973	if (err)
   3974		return err;
   3975	err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_SQD2RTS, slave);
   3976	if (err)
   3977		return err;
   3978
   3979	adjust_proxy_tun_qkey(dev, vhcr, context);
   3980	update_gid(dev, inbox, (u8)slave);
   3981	update_pkey_index(dev, slave, inbox);
   3982	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3983}
   3984
   3985int mlx4_2RST_QP_wrapper(struct mlx4_dev *dev, int slave,
   3986			 struct mlx4_vhcr *vhcr,
   3987			 struct mlx4_cmd_mailbox *inbox,
   3988			 struct mlx4_cmd_mailbox *outbox,
   3989			 struct mlx4_cmd_info *cmd)
   3990{
   3991	int err;
   3992	int qpn = vhcr->in_modifier & 0x7fffff;
   3993	struct res_qp *qp;
   3994
   3995	err = qp_res_start_move_to(dev, slave, qpn, RES_QP_MAPPED, &qp, 0);
   3996	if (err)
   3997		return err;
   3998	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   3999	if (err)
   4000		goto ex_abort;
   4001
   4002	atomic_dec(&qp->mtt->ref_count);
   4003	atomic_dec(&qp->rcq->ref_count);
   4004	atomic_dec(&qp->scq->ref_count);
   4005	if (qp->srq)
   4006		atomic_dec(&qp->srq->ref_count);
   4007	res_end_move(dev, slave, RES_QP, qpn);
   4008	return 0;
   4009
   4010ex_abort:
   4011	res_abort_move(dev, slave, RES_QP, qpn);
   4012
   4013	return err;
   4014}
   4015
   4016static struct res_gid *find_gid(struct mlx4_dev *dev, int slave,
   4017				struct res_qp *rqp, u8 *gid)
   4018{
   4019	struct res_gid *res;
   4020
   4021	list_for_each_entry(res, &rqp->mcg_list, list) {
   4022		if (!memcmp(res->gid, gid, 16))
   4023			return res;
   4024	}
   4025	return NULL;
   4026}
   4027
   4028static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
   4029		       u8 *gid, enum mlx4_protocol prot,
   4030		       enum mlx4_steer_type steer, u64 reg_id)
   4031{
   4032	struct res_gid *res;
   4033	int err;
   4034
   4035	res = kzalloc(sizeof(*res), GFP_KERNEL);
   4036	if (!res)
   4037		return -ENOMEM;
   4038
   4039	spin_lock_irq(&rqp->mcg_spl);
   4040	if (find_gid(dev, slave, rqp, gid)) {
   4041		kfree(res);
   4042		err = -EEXIST;
   4043	} else {
   4044		memcpy(res->gid, gid, 16);
   4045		res->prot = prot;
   4046		res->steer = steer;
   4047		res->reg_id = reg_id;
   4048		list_add_tail(&res->list, &rqp->mcg_list);
   4049		err = 0;
   4050	}
   4051	spin_unlock_irq(&rqp->mcg_spl);
   4052
   4053	return err;
   4054}
   4055
   4056static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
   4057		       u8 *gid, enum mlx4_protocol prot,
   4058		       enum mlx4_steer_type steer, u64 *reg_id)
   4059{
   4060	struct res_gid *res;
   4061	int err;
   4062
   4063	spin_lock_irq(&rqp->mcg_spl);
   4064	res = find_gid(dev, slave, rqp, gid);
   4065	if (!res || res->prot != prot || res->steer != steer)
   4066		err = -EINVAL;
   4067	else {
   4068		*reg_id = res->reg_id;
   4069		list_del(&res->list);
   4070		kfree(res);
   4071		err = 0;
   4072	}
   4073	spin_unlock_irq(&rqp->mcg_spl);
   4074
   4075	return err;
   4076}
   4077
   4078static int qp_attach(struct mlx4_dev *dev, int slave, struct mlx4_qp *qp,
   4079		     u8 gid[16], int block_loopback, enum mlx4_protocol prot,
   4080		     enum mlx4_steer_type type, u64 *reg_id)
   4081{
   4082	switch (dev->caps.steering_mode) {
   4083	case MLX4_STEERING_MODE_DEVICE_MANAGED: {
   4084		int port = mlx4_slave_convert_port(dev, slave, gid[5]);
   4085		if (port < 0)
   4086			return port;
   4087		return mlx4_trans_to_dmfs_attach(dev, qp, gid, port,
   4088						block_loopback, prot,
   4089						reg_id);
   4090	}
   4091	case MLX4_STEERING_MODE_B0:
   4092		if (prot == MLX4_PROT_ETH) {
   4093			int port = mlx4_slave_convert_port(dev, slave, gid[5]);
   4094			if (port < 0)
   4095				return port;
   4096			gid[5] = port;
   4097		}
   4098		return mlx4_qp_attach_common(dev, qp, gid,
   4099					    block_loopback, prot, type);
   4100	default:
   4101		return -EINVAL;
   4102	}
   4103}
   4104
   4105static int qp_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
   4106		     u8 gid[16], enum mlx4_protocol prot,
   4107		     enum mlx4_steer_type type, u64 reg_id)
   4108{
   4109	switch (dev->caps.steering_mode) {
   4110	case MLX4_STEERING_MODE_DEVICE_MANAGED:
   4111		return mlx4_flow_detach(dev, reg_id);
   4112	case MLX4_STEERING_MODE_B0:
   4113		return mlx4_qp_detach_common(dev, qp, gid, prot, type);
   4114	default:
   4115		return -EINVAL;
   4116	}
   4117}
   4118
   4119static int mlx4_adjust_port(struct mlx4_dev *dev, int slave,
   4120			    u8 *gid, enum mlx4_protocol prot)
   4121{
   4122	int real_port;
   4123
   4124	if (prot != MLX4_PROT_ETH)
   4125		return 0;
   4126
   4127	if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0 ||
   4128	    dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) {
   4129		real_port = mlx4_slave_convert_port(dev, slave, gid[5]);
   4130		if (real_port < 0)
   4131			return -EINVAL;
   4132		gid[5] = real_port;
   4133	}
   4134
   4135	return 0;
   4136}
   4137
   4138int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
   4139			       struct mlx4_vhcr *vhcr,
   4140			       struct mlx4_cmd_mailbox *inbox,
   4141			       struct mlx4_cmd_mailbox *outbox,
   4142			       struct mlx4_cmd_info *cmd)
   4143{
   4144	struct mlx4_qp qp; /* dummy for calling attach/detach */
   4145	u8 *gid = inbox->buf;
   4146	enum mlx4_protocol prot = (vhcr->in_modifier >> 28) & 0x7;
   4147	int err;
   4148	int qpn;
   4149	struct res_qp *rqp;
   4150	u64 reg_id = 0;
   4151	int attach = vhcr->op_modifier;
   4152	int block_loopback = vhcr->in_modifier >> 31;
   4153	u8 steer_type_mask = 2;
   4154	enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
   4155
   4156	qpn = vhcr->in_modifier & 0xffffff;
   4157	err = get_res(dev, slave, qpn, RES_QP, &rqp);
   4158	if (err)
   4159		return err;
   4160
   4161	qp.qpn = qpn;
   4162	if (attach) {
   4163		err = qp_attach(dev, slave, &qp, gid, block_loopback, prot,
   4164				type, &reg_id);
   4165		if (err) {
   4166			pr_err("Fail to attach rule to qp 0x%x\n", qpn);
   4167			goto ex_put;
   4168		}
   4169		err = add_mcg_res(dev, slave, rqp, gid, prot, type, reg_id);
   4170		if (err)
   4171			goto ex_detach;
   4172	} else {
   4173		err = mlx4_adjust_port(dev, slave, gid, prot);
   4174		if (err)
   4175			goto ex_put;
   4176
   4177		err = rem_mcg_res(dev, slave, rqp, gid, prot, type, &reg_id);
   4178		if (err)
   4179			goto ex_put;
   4180
   4181		err = qp_detach(dev, &qp, gid, prot, type, reg_id);
   4182		if (err)
   4183			pr_err("Fail to detach rule from qp 0x%x reg_id = 0x%llx\n",
   4184			       qpn, reg_id);
   4185	}
   4186	put_res(dev, slave, qpn, RES_QP);
   4187	return err;
   4188
   4189ex_detach:
   4190	qp_detach(dev, &qp, gid, prot, type, reg_id);
   4191ex_put:
   4192	put_res(dev, slave, qpn, RES_QP);
   4193	return err;
   4194}
   4195
   4196/*
   4197 * MAC validation for Flow Steering rules.
   4198 * VF can attach rules only with a mac address which is assigned to it.
   4199 */
   4200static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header,
   4201				   struct list_head *rlist)
   4202{
   4203	struct mac_res *res, *tmp;
   4204	__be64 be_mac;
   4205
   4206	/* make sure it isn't multicast or broadcast mac*/
   4207	if (!is_multicast_ether_addr(eth_header->eth.dst_mac) &&
   4208	    !is_broadcast_ether_addr(eth_header->eth.dst_mac)) {
   4209		list_for_each_entry_safe(res, tmp, rlist, list) {
   4210			be_mac = cpu_to_be64(res->mac << 16);
   4211			if (ether_addr_equal((u8 *)&be_mac, eth_header->eth.dst_mac))
   4212				return 0;
   4213		}
   4214		pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n",
   4215		       eth_header->eth.dst_mac, slave);
   4216		return -EINVAL;
   4217	}
   4218	return 0;
   4219}
   4220
   4221/*
   4222 * In case of missing eth header, append eth header with a MAC address
   4223 * assigned to the VF.
   4224 */
   4225static int add_eth_header(struct mlx4_dev *dev, int slave,
   4226			  struct mlx4_cmd_mailbox *inbox,
   4227			  struct list_head *rlist, int header_id)
   4228{
   4229	struct mac_res *res, *tmp;
   4230	u8 port;
   4231	struct mlx4_net_trans_rule_hw_ctrl *ctrl;
   4232	struct mlx4_net_trans_rule_hw_eth *eth_header;
   4233	struct mlx4_net_trans_rule_hw_ipv4 *ip_header;
   4234	struct mlx4_net_trans_rule_hw_tcp_udp *l4_header;
   4235	__be64 be_mac = 0;
   4236	__be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16);
   4237
   4238	ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
   4239	port = ctrl->port;
   4240	eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1);
   4241
   4242	/* Clear a space in the inbox for eth header */
   4243	switch (header_id) {
   4244	case MLX4_NET_TRANS_RULE_ID_IPV4:
   4245		ip_header =
   4246			(struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1);
   4247		memmove(ip_header, eth_header,
   4248			sizeof(*ip_header) + sizeof(*l4_header));
   4249		break;
   4250	case MLX4_NET_TRANS_RULE_ID_TCP:
   4251	case MLX4_NET_TRANS_RULE_ID_UDP:
   4252		l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *)
   4253			    (eth_header + 1);
   4254		memmove(l4_header, eth_header, sizeof(*l4_header));
   4255		break;
   4256	default:
   4257		return -EINVAL;
   4258	}
   4259	list_for_each_entry_safe(res, tmp, rlist, list) {
   4260		if (port == res->port) {
   4261			be_mac = cpu_to_be64(res->mac << 16);
   4262			break;
   4263		}
   4264	}
   4265	if (!be_mac) {
   4266		pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d\n",
   4267		       port);
   4268		return -EINVAL;
   4269	}
   4270
   4271	memset(eth_header, 0, sizeof(*eth_header));
   4272	eth_header->size = sizeof(*eth_header) >> 2;
   4273	eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]);
   4274	memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN);
   4275	memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN);
   4276
   4277	return 0;
   4278
   4279}
   4280
   4281#define MLX4_UPD_QP_PATH_MASK_SUPPORTED      (                                \
   4282	1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX                     |\
   4283	1ULL << MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB)
   4284int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
   4285			   struct mlx4_vhcr *vhcr,
   4286			   struct mlx4_cmd_mailbox *inbox,
   4287			   struct mlx4_cmd_mailbox *outbox,
   4288			   struct mlx4_cmd_info *cmd_info)
   4289{
   4290	int err;
   4291	u32 qpn = vhcr->in_modifier & 0xffffff;
   4292	struct res_qp *rqp;
   4293	u64 mac;
   4294	unsigned port;
   4295	u64 pri_addr_path_mask;
   4296	struct mlx4_update_qp_context *cmd;
   4297	int smac_index;
   4298
   4299	cmd = (struct mlx4_update_qp_context *)inbox->buf;
   4300
   4301	pri_addr_path_mask = be64_to_cpu(cmd->primary_addr_path_mask);
   4302	if (cmd->qp_mask || cmd->secondary_addr_path_mask ||
   4303	    (pri_addr_path_mask & ~MLX4_UPD_QP_PATH_MASK_SUPPORTED))
   4304		return -EPERM;
   4305
   4306	if ((pri_addr_path_mask &
   4307	     (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB)) &&
   4308		!(dev->caps.flags2 &
   4309		  MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB)) {
   4310		mlx4_warn(dev, "Src check LB for slave %d isn't supported\n",
   4311			  slave);
   4312		return -EOPNOTSUPP;
   4313	}
   4314
   4315	/* Just change the smac for the QP */
   4316	err = get_res(dev, slave, qpn, RES_QP, &rqp);
   4317	if (err) {
   4318		mlx4_err(dev, "Updating qpn 0x%x for slave %d rejected\n", qpn, slave);
   4319		return err;
   4320	}
   4321
   4322	port = (rqp->sched_queue >> 6 & 1) + 1;
   4323
   4324	if (pri_addr_path_mask & (1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX)) {
   4325		smac_index = cmd->qp_context.pri_path.grh_mylmc;
   4326		err = mac_find_smac_ix_in_slave(dev, slave, port,
   4327						smac_index, &mac);
   4328
   4329		if (err) {
   4330			mlx4_err(dev, "Failed to update qpn 0x%x, MAC is invalid. smac_ix: %d\n",
   4331				 qpn, smac_index);
   4332			goto err_mac;
   4333		}
   4334	}
   4335
   4336	err = mlx4_cmd(dev, inbox->dma,
   4337		       vhcr->in_modifier, 0,
   4338		       MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A,
   4339		       MLX4_CMD_NATIVE);
   4340	if (err) {
   4341		mlx4_err(dev, "Failed to update qpn on qpn 0x%x, command failed\n", qpn);
   4342		goto err_mac;
   4343	}
   4344
   4345err_mac:
   4346	put_res(dev, slave, qpn, RES_QP);
   4347	return err;
   4348}
   4349
   4350static u32 qp_attach_mbox_size(void *mbox)
   4351{
   4352	u32 size = sizeof(struct mlx4_net_trans_rule_hw_ctrl);
   4353	struct _rule_hw  *rule_header;
   4354
   4355	rule_header = (struct _rule_hw *)(mbox + size);
   4356
   4357	while (rule_header->size) {
   4358		size += rule_header->size * sizeof(u32);
   4359		rule_header += 1;
   4360	}
   4361	return size;
   4362}
   4363
   4364static int mlx4_do_mirror_rule(struct mlx4_dev *dev, struct res_fs_rule *fs_rule);
   4365
   4366int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
   4367					 struct mlx4_vhcr *vhcr,
   4368					 struct mlx4_cmd_mailbox *inbox,
   4369					 struct mlx4_cmd_mailbox *outbox,
   4370					 struct mlx4_cmd_info *cmd)
   4371{
   4372
   4373	struct mlx4_priv *priv = mlx4_priv(dev);
   4374	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   4375	struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC];
   4376	int err;
   4377	int qpn;
   4378	struct res_qp *rqp;
   4379	struct mlx4_net_trans_rule_hw_ctrl *ctrl;
   4380	struct _rule_hw  *rule_header;
   4381	int header_id;
   4382	struct res_fs_rule *rrule;
   4383	u32 mbox_size;
   4384
   4385	if (dev->caps.steering_mode !=
   4386	    MLX4_STEERING_MODE_DEVICE_MANAGED)
   4387		return -EOPNOTSUPP;
   4388
   4389	ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
   4390	err = mlx4_slave_convert_port(dev, slave, ctrl->port);
   4391	if (err <= 0)
   4392		return -EINVAL;
   4393	ctrl->port = err;
   4394	qpn = be32_to_cpu(ctrl->qpn) & 0xffffff;
   4395	err = get_res(dev, slave, qpn, RES_QP, &rqp);
   4396	if (err) {
   4397		pr_err("Steering rule with qpn 0x%x rejected\n", qpn);
   4398		return err;
   4399	}
   4400	rule_header = (struct _rule_hw *)(ctrl + 1);
   4401	header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id));
   4402
   4403	if (header_id == MLX4_NET_TRANS_RULE_ID_ETH)
   4404		mlx4_handle_eth_header_mcast_prio(ctrl, rule_header);
   4405
   4406	switch (header_id) {
   4407	case MLX4_NET_TRANS_RULE_ID_ETH:
   4408		if (validate_eth_header_mac(slave, rule_header, rlist)) {
   4409			err = -EINVAL;
   4410			goto err_put_qp;
   4411		}
   4412		break;
   4413	case MLX4_NET_TRANS_RULE_ID_IB:
   4414		break;
   4415	case MLX4_NET_TRANS_RULE_ID_IPV4:
   4416	case MLX4_NET_TRANS_RULE_ID_TCP:
   4417	case MLX4_NET_TRANS_RULE_ID_UDP:
   4418		pr_warn("Can't attach FS rule without L2 headers, adding L2 header\n");
   4419		if (add_eth_header(dev, slave, inbox, rlist, header_id)) {
   4420			err = -EINVAL;
   4421			goto err_put_qp;
   4422		}
   4423		vhcr->in_modifier +=
   4424			sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2;
   4425		break;
   4426	default:
   4427		pr_err("Corrupted mailbox\n");
   4428		err = -EINVAL;
   4429		goto err_put_qp;
   4430	}
   4431
   4432	err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,
   4433			   vhcr->in_modifier, 0,
   4434			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
   4435			   MLX4_CMD_NATIVE);
   4436	if (err)
   4437		goto err_put_qp;
   4438
   4439
   4440	err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, qpn);
   4441	if (err) {
   4442		mlx4_err(dev, "Fail to add flow steering resources\n");
   4443		goto err_detach;
   4444	}
   4445
   4446	err = get_res(dev, slave, vhcr->out_param, RES_FS_RULE, &rrule);
   4447	if (err)
   4448		goto err_detach;
   4449
   4450	mbox_size = qp_attach_mbox_size(inbox->buf);
   4451	rrule->mirr_mbox = kmalloc(mbox_size, GFP_KERNEL);
   4452	if (!rrule->mirr_mbox) {
   4453		err = -ENOMEM;
   4454		goto err_put_rule;
   4455	}
   4456	rrule->mirr_mbox_size = mbox_size;
   4457	rrule->mirr_rule_id = 0;
   4458	memcpy(rrule->mirr_mbox, inbox->buf, mbox_size);
   4459
   4460	/* set different port */
   4461	ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)rrule->mirr_mbox;
   4462	if (ctrl->port == 1)
   4463		ctrl->port = 2;
   4464	else
   4465		ctrl->port = 1;
   4466
   4467	if (mlx4_is_bonded(dev))
   4468		mlx4_do_mirror_rule(dev, rrule);
   4469
   4470	atomic_inc(&rqp->ref_count);
   4471
   4472err_put_rule:
   4473	put_res(dev, slave, vhcr->out_param, RES_FS_RULE);
   4474err_detach:
   4475	/* detach rule on error */
   4476	if (err)
   4477		mlx4_cmd(dev, vhcr->out_param, 0, 0,
   4478			 MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
   4479			 MLX4_CMD_NATIVE);
   4480err_put_qp:
   4481	put_res(dev, slave, qpn, RES_QP);
   4482	return err;
   4483}
   4484
   4485static int mlx4_undo_mirror_rule(struct mlx4_dev *dev, struct res_fs_rule *fs_rule)
   4486{
   4487	int err;
   4488
   4489	err = rem_res_range(dev, fs_rule->com.owner, fs_rule->com.res_id, 1, RES_FS_RULE, 0);
   4490	if (err) {
   4491		mlx4_err(dev, "Fail to remove flow steering resources\n");
   4492		return err;
   4493	}
   4494
   4495	mlx4_cmd(dev, fs_rule->com.res_id, 0, 0, MLX4_QP_FLOW_STEERING_DETACH,
   4496		 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
   4497	return 0;
   4498}
   4499
   4500int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
   4501					 struct mlx4_vhcr *vhcr,
   4502					 struct mlx4_cmd_mailbox *inbox,
   4503					 struct mlx4_cmd_mailbox *outbox,
   4504					 struct mlx4_cmd_info *cmd)
   4505{
   4506	int err;
   4507	struct res_qp *rqp;
   4508	struct res_fs_rule *rrule;
   4509	u64 mirr_reg_id;
   4510	int qpn;
   4511
   4512	if (dev->caps.steering_mode !=
   4513	    MLX4_STEERING_MODE_DEVICE_MANAGED)
   4514		return -EOPNOTSUPP;
   4515
   4516	err = get_res(dev, slave, vhcr->in_param, RES_FS_RULE, &rrule);
   4517	if (err)
   4518		return err;
   4519
   4520	if (!rrule->mirr_mbox) {
   4521		mlx4_err(dev, "Mirror rules cannot be removed explicitly\n");
   4522		put_res(dev, slave, vhcr->in_param, RES_FS_RULE);
   4523		return -EINVAL;
   4524	}
   4525	mirr_reg_id = rrule->mirr_rule_id;
   4526	kfree(rrule->mirr_mbox);
   4527	qpn = rrule->qpn;
   4528
   4529	/* Release the rule form busy state before removal */
   4530	put_res(dev, slave, vhcr->in_param, RES_FS_RULE);
   4531	err = get_res(dev, slave, qpn, RES_QP, &rqp);
   4532	if (err)
   4533		return err;
   4534
   4535	if (mirr_reg_id && mlx4_is_bonded(dev)) {
   4536		err = get_res(dev, slave, mirr_reg_id, RES_FS_RULE, &rrule);
   4537		if (err) {
   4538			mlx4_err(dev, "Fail to get resource of mirror rule\n");
   4539		} else {
   4540			put_res(dev, slave, mirr_reg_id, RES_FS_RULE);
   4541			mlx4_undo_mirror_rule(dev, rrule);
   4542		}
   4543	}
   4544	err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0);
   4545	if (err) {
   4546		mlx4_err(dev, "Fail to remove flow steering resources\n");
   4547		goto out;
   4548	}
   4549
   4550	err = mlx4_cmd(dev, vhcr->in_param, 0, 0,
   4551		       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
   4552		       MLX4_CMD_NATIVE);
   4553	if (!err)
   4554		atomic_dec(&rqp->ref_count);
   4555out:
   4556	put_res(dev, slave, qpn, RES_QP);
   4557	return err;
   4558}
   4559
   4560enum {
   4561	BUSY_MAX_RETRIES = 10
   4562};
   4563
   4564int mlx4_QUERY_IF_STAT_wrapper(struct mlx4_dev *dev, int slave,
   4565			       struct mlx4_vhcr *vhcr,
   4566			       struct mlx4_cmd_mailbox *inbox,
   4567			       struct mlx4_cmd_mailbox *outbox,
   4568			       struct mlx4_cmd_info *cmd)
   4569{
   4570	int err;
   4571	int index = vhcr->in_modifier & 0xffff;
   4572
   4573	err = get_res(dev, slave, index, RES_COUNTER, NULL);
   4574	if (err)
   4575		return err;
   4576
   4577	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
   4578	put_res(dev, slave, index, RES_COUNTER);
   4579	return err;
   4580}
   4581
   4582static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
   4583{
   4584	struct res_gid *rgid;
   4585	struct res_gid *tmp;
   4586	struct mlx4_qp qp; /* dummy for calling attach/detach */
   4587
   4588	list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) {
   4589		switch (dev->caps.steering_mode) {
   4590		case MLX4_STEERING_MODE_DEVICE_MANAGED:
   4591			mlx4_flow_detach(dev, rgid->reg_id);
   4592			break;
   4593		case MLX4_STEERING_MODE_B0:
   4594			qp.qpn = rqp->local_qpn;
   4595			(void) mlx4_qp_detach_common(dev, &qp, rgid->gid,
   4596						     rgid->prot, rgid->steer);
   4597			break;
   4598		}
   4599		list_del(&rgid->list);
   4600		kfree(rgid);
   4601	}
   4602}
   4603
   4604static int _move_all_busy(struct mlx4_dev *dev, int slave,
   4605			  enum mlx4_resource type, int print)
   4606{
   4607	struct mlx4_priv *priv = mlx4_priv(dev);
   4608	struct mlx4_resource_tracker *tracker =
   4609		&priv->mfunc.master.res_tracker;
   4610	struct list_head *rlist = &tracker->slave_list[slave].res_list[type];
   4611	struct res_common *r;
   4612	struct res_common *tmp;
   4613	int busy;
   4614
   4615	busy = 0;
   4616	spin_lock_irq(mlx4_tlock(dev));
   4617	list_for_each_entry_safe(r, tmp, rlist, list) {
   4618		if (r->owner == slave) {
   4619			if (!r->removing) {
   4620				if (r->state == RES_ANY_BUSY) {
   4621					if (print)
   4622						mlx4_dbg(dev,
   4623							 "%s id 0x%llx is busy\n",
   4624							  resource_str(type),
   4625							  r->res_id);
   4626					++busy;
   4627				} else {
   4628					r->from_state = r->state;
   4629					r->state = RES_ANY_BUSY;
   4630					r->removing = 1;
   4631				}
   4632			}
   4633		}
   4634	}
   4635	spin_unlock_irq(mlx4_tlock(dev));
   4636
   4637	return busy;
   4638}
   4639
   4640static int move_all_busy(struct mlx4_dev *dev, int slave,
   4641			 enum mlx4_resource type)
   4642{
   4643	unsigned long begin;
   4644	int busy;
   4645
   4646	begin = jiffies;
   4647	do {
   4648		busy = _move_all_busy(dev, slave, type, 0);
   4649		if (time_after(jiffies, begin + 5 * HZ))
   4650			break;
   4651		if (busy)
   4652			cond_resched();
   4653	} while (busy);
   4654
   4655	if (busy)
   4656		busy = _move_all_busy(dev, slave, type, 1);
   4657
   4658	return busy;
   4659}
   4660static void rem_slave_qps(struct mlx4_dev *dev, int slave)
   4661{
   4662	struct mlx4_priv *priv = mlx4_priv(dev);
   4663	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   4664	struct list_head *qp_list =
   4665		&tracker->slave_list[slave].res_list[RES_QP];
   4666	struct res_qp *qp;
   4667	struct res_qp *tmp;
   4668	int state;
   4669	u64 in_param;
   4670	int qpn;
   4671	int err;
   4672
   4673	err = move_all_busy(dev, slave, RES_QP);
   4674	if (err)
   4675		mlx4_warn(dev, "rem_slave_qps: Could not move all qps to busy for slave %d\n",
   4676			  slave);
   4677
   4678	spin_lock_irq(mlx4_tlock(dev));
   4679	list_for_each_entry_safe(qp, tmp, qp_list, com.list) {
   4680		spin_unlock_irq(mlx4_tlock(dev));
   4681		if (qp->com.owner == slave) {
   4682			qpn = qp->com.res_id;
   4683			detach_qp(dev, slave, qp);
   4684			state = qp->com.from_state;
   4685			while (state != 0) {
   4686				switch (state) {
   4687				case RES_QP_RESERVED:
   4688					spin_lock_irq(mlx4_tlock(dev));
   4689					rb_erase(&qp->com.node,
   4690						 &tracker->res_tree[RES_QP]);
   4691					list_del(&qp->com.list);
   4692					spin_unlock_irq(mlx4_tlock(dev));
   4693					if (!valid_reserved(dev, slave, qpn)) {
   4694						__mlx4_qp_release_range(dev, qpn, 1);
   4695						mlx4_release_resource(dev, slave,
   4696								      RES_QP, 1, 0);
   4697					}
   4698					kfree(qp);
   4699					state = 0;
   4700					break;
   4701				case RES_QP_MAPPED:
   4702					if (!valid_reserved(dev, slave, qpn))
   4703						__mlx4_qp_free_icm(dev, qpn);
   4704					state = RES_QP_RESERVED;
   4705					break;
   4706				case RES_QP_HW:
   4707					in_param = slave;
   4708					err = mlx4_cmd(dev, in_param,
   4709						       qp->local_qpn, 2,
   4710						       MLX4_CMD_2RST_QP,
   4711						       MLX4_CMD_TIME_CLASS_A,
   4712						       MLX4_CMD_NATIVE);
   4713					if (err)
   4714						mlx4_dbg(dev, "rem_slave_qps: failed to move slave %d qpn %d to reset\n",
   4715							 slave, qp->local_qpn);
   4716					atomic_dec(&qp->rcq->ref_count);
   4717					atomic_dec(&qp->scq->ref_count);
   4718					atomic_dec(&qp->mtt->ref_count);
   4719					if (qp->srq)
   4720						atomic_dec(&qp->srq->ref_count);
   4721					state = RES_QP_MAPPED;
   4722					break;
   4723				default:
   4724					state = 0;
   4725				}
   4726			}
   4727		}
   4728		spin_lock_irq(mlx4_tlock(dev));
   4729	}
   4730	spin_unlock_irq(mlx4_tlock(dev));
   4731}
   4732
   4733static void rem_slave_srqs(struct mlx4_dev *dev, int slave)
   4734{
   4735	struct mlx4_priv *priv = mlx4_priv(dev);
   4736	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   4737	struct list_head *srq_list =
   4738		&tracker->slave_list[slave].res_list[RES_SRQ];
   4739	struct res_srq *srq;
   4740	struct res_srq *tmp;
   4741	int state;
   4742	u64 in_param;
   4743	int srqn;
   4744	int err;
   4745
   4746	err = move_all_busy(dev, slave, RES_SRQ);
   4747	if (err)
   4748		mlx4_warn(dev, "rem_slave_srqs: Could not move all srqs - too busy for slave %d\n",
   4749			  slave);
   4750
   4751	spin_lock_irq(mlx4_tlock(dev));
   4752	list_for_each_entry_safe(srq, tmp, srq_list, com.list) {
   4753		spin_unlock_irq(mlx4_tlock(dev));
   4754		if (srq->com.owner == slave) {
   4755			srqn = srq->com.res_id;
   4756			state = srq->com.from_state;
   4757			while (state != 0) {
   4758				switch (state) {
   4759				case RES_SRQ_ALLOCATED:
   4760					__mlx4_srq_free_icm(dev, srqn);
   4761					spin_lock_irq(mlx4_tlock(dev));
   4762					rb_erase(&srq->com.node,
   4763						 &tracker->res_tree[RES_SRQ]);
   4764					list_del(&srq->com.list);
   4765					spin_unlock_irq(mlx4_tlock(dev));
   4766					mlx4_release_resource(dev, slave,
   4767							      RES_SRQ, 1, 0);
   4768					kfree(srq);
   4769					state = 0;
   4770					break;
   4771
   4772				case RES_SRQ_HW:
   4773					in_param = slave;
   4774					err = mlx4_cmd(dev, in_param, srqn, 1,
   4775						       MLX4_CMD_HW2SW_SRQ,
   4776						       MLX4_CMD_TIME_CLASS_A,
   4777						       MLX4_CMD_NATIVE);
   4778					if (err)
   4779						mlx4_dbg(dev, "rem_slave_srqs: failed to move slave %d srq %d to SW ownership\n",
   4780							 slave, srqn);
   4781
   4782					atomic_dec(&srq->mtt->ref_count);
   4783					if (srq->cq)
   4784						atomic_dec(&srq->cq->ref_count);
   4785					state = RES_SRQ_ALLOCATED;
   4786					break;
   4787
   4788				default:
   4789					state = 0;
   4790				}
   4791			}
   4792		}
   4793		spin_lock_irq(mlx4_tlock(dev));
   4794	}
   4795	spin_unlock_irq(mlx4_tlock(dev));
   4796}
   4797
   4798static void rem_slave_cqs(struct mlx4_dev *dev, int slave)
   4799{
   4800	struct mlx4_priv *priv = mlx4_priv(dev);
   4801	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   4802	struct list_head *cq_list =
   4803		&tracker->slave_list[slave].res_list[RES_CQ];
   4804	struct res_cq *cq;
   4805	struct res_cq *tmp;
   4806	int state;
   4807	u64 in_param;
   4808	int cqn;
   4809	int err;
   4810
   4811	err = move_all_busy(dev, slave, RES_CQ);
   4812	if (err)
   4813		mlx4_warn(dev, "rem_slave_cqs: Could not move all cqs - too busy for slave %d\n",
   4814			  slave);
   4815
   4816	spin_lock_irq(mlx4_tlock(dev));
   4817	list_for_each_entry_safe(cq, tmp, cq_list, com.list) {
   4818		spin_unlock_irq(mlx4_tlock(dev));
   4819		if (cq->com.owner == slave && !atomic_read(&cq->ref_count)) {
   4820			cqn = cq->com.res_id;
   4821			state = cq->com.from_state;
   4822			while (state != 0) {
   4823				switch (state) {
   4824				case RES_CQ_ALLOCATED:
   4825					__mlx4_cq_free_icm(dev, cqn);
   4826					spin_lock_irq(mlx4_tlock(dev));
   4827					rb_erase(&cq->com.node,
   4828						 &tracker->res_tree[RES_CQ]);
   4829					list_del(&cq->com.list);
   4830					spin_unlock_irq(mlx4_tlock(dev));
   4831					mlx4_release_resource(dev, slave,
   4832							      RES_CQ, 1, 0);
   4833					kfree(cq);
   4834					state = 0;
   4835					break;
   4836
   4837				case RES_CQ_HW:
   4838					in_param = slave;
   4839					err = mlx4_cmd(dev, in_param, cqn, 1,
   4840						       MLX4_CMD_HW2SW_CQ,
   4841						       MLX4_CMD_TIME_CLASS_A,
   4842						       MLX4_CMD_NATIVE);
   4843					if (err)
   4844						mlx4_dbg(dev, "rem_slave_cqs: failed to move slave %d cq %d to SW ownership\n",
   4845							 slave, cqn);
   4846					atomic_dec(&cq->mtt->ref_count);
   4847					state = RES_CQ_ALLOCATED;
   4848					break;
   4849
   4850				default:
   4851					state = 0;
   4852				}
   4853			}
   4854		}
   4855		spin_lock_irq(mlx4_tlock(dev));
   4856	}
   4857	spin_unlock_irq(mlx4_tlock(dev));
   4858}
   4859
   4860static void rem_slave_mrs(struct mlx4_dev *dev, int slave)
   4861{
   4862	struct mlx4_priv *priv = mlx4_priv(dev);
   4863	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   4864	struct list_head *mpt_list =
   4865		&tracker->slave_list[slave].res_list[RES_MPT];
   4866	struct res_mpt *mpt;
   4867	struct res_mpt *tmp;
   4868	int state;
   4869	u64 in_param;
   4870	int mptn;
   4871	int err;
   4872
   4873	err = move_all_busy(dev, slave, RES_MPT);
   4874	if (err)
   4875		mlx4_warn(dev, "rem_slave_mrs: Could not move all mpts - too busy for slave %d\n",
   4876			  slave);
   4877
   4878	spin_lock_irq(mlx4_tlock(dev));
   4879	list_for_each_entry_safe(mpt, tmp, mpt_list, com.list) {
   4880		spin_unlock_irq(mlx4_tlock(dev));
   4881		if (mpt->com.owner == slave) {
   4882			mptn = mpt->com.res_id;
   4883			state = mpt->com.from_state;
   4884			while (state != 0) {
   4885				switch (state) {
   4886				case RES_MPT_RESERVED:
   4887					__mlx4_mpt_release(dev, mpt->key);
   4888					spin_lock_irq(mlx4_tlock(dev));
   4889					rb_erase(&mpt->com.node,
   4890						 &tracker->res_tree[RES_MPT]);
   4891					list_del(&mpt->com.list);
   4892					spin_unlock_irq(mlx4_tlock(dev));
   4893					mlx4_release_resource(dev, slave,
   4894							      RES_MPT, 1, 0);
   4895					kfree(mpt);
   4896					state = 0;
   4897					break;
   4898
   4899				case RES_MPT_MAPPED:
   4900					__mlx4_mpt_free_icm(dev, mpt->key);
   4901					state = RES_MPT_RESERVED;
   4902					break;
   4903
   4904				case RES_MPT_HW:
   4905					in_param = slave;
   4906					err = mlx4_cmd(dev, in_param, mptn, 0,
   4907						     MLX4_CMD_HW2SW_MPT,
   4908						     MLX4_CMD_TIME_CLASS_A,
   4909						     MLX4_CMD_NATIVE);
   4910					if (err)
   4911						mlx4_dbg(dev, "rem_slave_mrs: failed to move slave %d mpt %d to SW ownership\n",
   4912							 slave, mptn);
   4913					if (mpt->mtt)
   4914						atomic_dec(&mpt->mtt->ref_count);
   4915					state = RES_MPT_MAPPED;
   4916					break;
   4917				default:
   4918					state = 0;
   4919				}
   4920			}
   4921		}
   4922		spin_lock_irq(mlx4_tlock(dev));
   4923	}
   4924	spin_unlock_irq(mlx4_tlock(dev));
   4925}
   4926
   4927static void rem_slave_mtts(struct mlx4_dev *dev, int slave)
   4928{
   4929	struct mlx4_priv *priv = mlx4_priv(dev);
   4930	struct mlx4_resource_tracker *tracker =
   4931		&priv->mfunc.master.res_tracker;
   4932	struct list_head *mtt_list =
   4933		&tracker->slave_list[slave].res_list[RES_MTT];
   4934	struct res_mtt *mtt;
   4935	struct res_mtt *tmp;
   4936	int state;
   4937	int base;
   4938	int err;
   4939
   4940	err = move_all_busy(dev, slave, RES_MTT);
   4941	if (err)
   4942		mlx4_warn(dev, "rem_slave_mtts: Could not move all mtts  - too busy for slave %d\n",
   4943			  slave);
   4944
   4945	spin_lock_irq(mlx4_tlock(dev));
   4946	list_for_each_entry_safe(mtt, tmp, mtt_list, com.list) {
   4947		spin_unlock_irq(mlx4_tlock(dev));
   4948		if (mtt->com.owner == slave) {
   4949			base = mtt->com.res_id;
   4950			state = mtt->com.from_state;
   4951			while (state != 0) {
   4952				switch (state) {
   4953				case RES_MTT_ALLOCATED:
   4954					__mlx4_free_mtt_range(dev, base,
   4955							      mtt->order);
   4956					spin_lock_irq(mlx4_tlock(dev));
   4957					rb_erase(&mtt->com.node,
   4958						 &tracker->res_tree[RES_MTT]);
   4959					list_del(&mtt->com.list);
   4960					spin_unlock_irq(mlx4_tlock(dev));
   4961					mlx4_release_resource(dev, slave, RES_MTT,
   4962							      1 << mtt->order, 0);
   4963					kfree(mtt);
   4964					state = 0;
   4965					break;
   4966
   4967				default:
   4968					state = 0;
   4969				}
   4970			}
   4971		}
   4972		spin_lock_irq(mlx4_tlock(dev));
   4973	}
   4974	spin_unlock_irq(mlx4_tlock(dev));
   4975}
   4976
   4977static int mlx4_do_mirror_rule(struct mlx4_dev *dev, struct res_fs_rule *fs_rule)
   4978{
   4979	struct mlx4_cmd_mailbox *mailbox;
   4980	int err;
   4981	struct res_fs_rule *mirr_rule;
   4982	u64 reg_id;
   4983
   4984	mailbox = mlx4_alloc_cmd_mailbox(dev);
   4985	if (IS_ERR(mailbox))
   4986		return PTR_ERR(mailbox);
   4987
   4988	if (!fs_rule->mirr_mbox) {
   4989		mlx4_err(dev, "rule mirroring mailbox is null\n");
   4990		mlx4_free_cmd_mailbox(dev, mailbox);
   4991		return -EINVAL;
   4992	}
   4993	memcpy(mailbox->buf, fs_rule->mirr_mbox, fs_rule->mirr_mbox_size);
   4994	err = mlx4_cmd_imm(dev, mailbox->dma, &reg_id, fs_rule->mirr_mbox_size >> 2, 0,
   4995			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
   4996			   MLX4_CMD_NATIVE);
   4997	mlx4_free_cmd_mailbox(dev, mailbox);
   4998
   4999	if (err)
   5000		goto err;
   5001
   5002	err = add_res_range(dev, fs_rule->com.owner, reg_id, 1, RES_FS_RULE, fs_rule->qpn);
   5003	if (err)
   5004		goto err_detach;
   5005
   5006	err = get_res(dev, fs_rule->com.owner, reg_id, RES_FS_RULE, &mirr_rule);
   5007	if (err)
   5008		goto err_rem;
   5009
   5010	fs_rule->mirr_rule_id = reg_id;
   5011	mirr_rule->mirr_rule_id = 0;
   5012	mirr_rule->mirr_mbox_size = 0;
   5013	mirr_rule->mirr_mbox = NULL;
   5014	put_res(dev, fs_rule->com.owner, reg_id, RES_FS_RULE);
   5015
   5016	return 0;
   5017err_rem:
   5018	rem_res_range(dev, fs_rule->com.owner, reg_id, 1, RES_FS_RULE, 0);
   5019err_detach:
   5020	mlx4_cmd(dev, reg_id, 0, 0, MLX4_QP_FLOW_STEERING_DETACH,
   5021		 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
   5022err:
   5023	return err;
   5024}
   5025
   5026static int mlx4_mirror_fs_rules(struct mlx4_dev *dev, bool bond)
   5027{
   5028	struct mlx4_priv *priv = mlx4_priv(dev);
   5029	struct mlx4_resource_tracker *tracker =
   5030		&priv->mfunc.master.res_tracker;
   5031	struct rb_root *root = &tracker->res_tree[RES_FS_RULE];
   5032	struct rb_node *p;
   5033	struct res_fs_rule *fs_rule;
   5034	int err = 0;
   5035	LIST_HEAD(mirr_list);
   5036
   5037	for (p = rb_first(root); p; p = rb_next(p)) {
   5038		fs_rule = rb_entry(p, struct res_fs_rule, com.node);
   5039		if ((bond && fs_rule->mirr_mbox_size) ||
   5040		    (!bond && !fs_rule->mirr_mbox_size))
   5041			list_add_tail(&fs_rule->mirr_list, &mirr_list);
   5042	}
   5043
   5044	list_for_each_entry(fs_rule, &mirr_list, mirr_list) {
   5045		if (bond)
   5046			err += mlx4_do_mirror_rule(dev, fs_rule);
   5047		else
   5048			err += mlx4_undo_mirror_rule(dev, fs_rule);
   5049	}
   5050	return err;
   5051}
   5052
   5053int mlx4_bond_fs_rules(struct mlx4_dev *dev)
   5054{
   5055	return mlx4_mirror_fs_rules(dev, true);
   5056}
   5057
   5058int mlx4_unbond_fs_rules(struct mlx4_dev *dev)
   5059{
   5060	return mlx4_mirror_fs_rules(dev, false);
   5061}
   5062
   5063static void rem_slave_fs_rule(struct mlx4_dev *dev, int slave)
   5064{
   5065	struct mlx4_priv *priv = mlx4_priv(dev);
   5066	struct mlx4_resource_tracker *tracker =
   5067		&priv->mfunc.master.res_tracker;
   5068	struct list_head *fs_rule_list =
   5069		&tracker->slave_list[slave].res_list[RES_FS_RULE];
   5070	struct res_fs_rule *fs_rule;
   5071	struct res_fs_rule *tmp;
   5072	int state;
   5073	u64 base;
   5074	int err;
   5075
   5076	err = move_all_busy(dev, slave, RES_FS_RULE);
   5077	if (err)
   5078		mlx4_warn(dev, "rem_slave_fs_rule: Could not move all mtts to busy for slave %d\n",
   5079			  slave);
   5080
   5081	spin_lock_irq(mlx4_tlock(dev));
   5082	list_for_each_entry_safe(fs_rule, tmp, fs_rule_list, com.list) {
   5083		spin_unlock_irq(mlx4_tlock(dev));
   5084		if (fs_rule->com.owner == slave) {
   5085			base = fs_rule->com.res_id;
   5086			state = fs_rule->com.from_state;
   5087			while (state != 0) {
   5088				switch (state) {
   5089				case RES_FS_RULE_ALLOCATED:
   5090					/* detach rule */
   5091					err = mlx4_cmd(dev, base, 0, 0,
   5092						       MLX4_QP_FLOW_STEERING_DETACH,
   5093						       MLX4_CMD_TIME_CLASS_A,
   5094						       MLX4_CMD_NATIVE);
   5095
   5096					spin_lock_irq(mlx4_tlock(dev));
   5097					rb_erase(&fs_rule->com.node,
   5098						 &tracker->res_tree[RES_FS_RULE]);
   5099					list_del(&fs_rule->com.list);
   5100					spin_unlock_irq(mlx4_tlock(dev));
   5101					kfree(fs_rule->mirr_mbox);
   5102					kfree(fs_rule);
   5103					state = 0;
   5104					break;
   5105
   5106				default:
   5107					state = 0;
   5108				}
   5109			}
   5110		}
   5111		spin_lock_irq(mlx4_tlock(dev));
   5112	}
   5113	spin_unlock_irq(mlx4_tlock(dev));
   5114}
   5115
   5116static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
   5117{
   5118	struct mlx4_priv *priv = mlx4_priv(dev);
   5119	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   5120	struct list_head *eq_list =
   5121		&tracker->slave_list[slave].res_list[RES_EQ];
   5122	struct res_eq *eq;
   5123	struct res_eq *tmp;
   5124	int err;
   5125	int state;
   5126	int eqn;
   5127
   5128	err = move_all_busy(dev, slave, RES_EQ);
   5129	if (err)
   5130		mlx4_warn(dev, "rem_slave_eqs: Could not move all eqs - too busy for slave %d\n",
   5131			  slave);
   5132
   5133	spin_lock_irq(mlx4_tlock(dev));
   5134	list_for_each_entry_safe(eq, tmp, eq_list, com.list) {
   5135		spin_unlock_irq(mlx4_tlock(dev));
   5136		if (eq->com.owner == slave) {
   5137			eqn = eq->com.res_id;
   5138			state = eq->com.from_state;
   5139			while (state != 0) {
   5140				switch (state) {
   5141				case RES_EQ_RESERVED:
   5142					spin_lock_irq(mlx4_tlock(dev));
   5143					rb_erase(&eq->com.node,
   5144						 &tracker->res_tree[RES_EQ]);
   5145					list_del(&eq->com.list);
   5146					spin_unlock_irq(mlx4_tlock(dev));
   5147					kfree(eq);
   5148					state = 0;
   5149					break;
   5150
   5151				case RES_EQ_HW:
   5152					err = mlx4_cmd(dev, slave, eqn & 0x3ff,
   5153						       1, MLX4_CMD_HW2SW_EQ,
   5154						       MLX4_CMD_TIME_CLASS_A,
   5155						       MLX4_CMD_NATIVE);
   5156					if (err)
   5157						mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n",
   5158							 slave, eqn & 0x3ff);
   5159					atomic_dec(&eq->mtt->ref_count);
   5160					state = RES_EQ_RESERVED;
   5161					break;
   5162
   5163				default:
   5164					state = 0;
   5165				}
   5166			}
   5167		}
   5168		spin_lock_irq(mlx4_tlock(dev));
   5169	}
   5170	spin_unlock_irq(mlx4_tlock(dev));
   5171}
   5172
   5173static void rem_slave_counters(struct mlx4_dev *dev, int slave)
   5174{
   5175	struct mlx4_priv *priv = mlx4_priv(dev);
   5176	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   5177	struct list_head *counter_list =
   5178		&tracker->slave_list[slave].res_list[RES_COUNTER];
   5179	struct res_counter *counter;
   5180	struct res_counter *tmp;
   5181	int err;
   5182	int *counters_arr = NULL;
   5183	int i, j;
   5184
   5185	err = move_all_busy(dev, slave, RES_COUNTER);
   5186	if (err)
   5187		mlx4_warn(dev, "rem_slave_counters: Could not move all counters - too busy for slave %d\n",
   5188			  slave);
   5189
   5190	counters_arr = kmalloc_array(dev->caps.max_counters,
   5191				     sizeof(*counters_arr), GFP_KERNEL);
   5192	if (!counters_arr)
   5193		return;
   5194
   5195	do {
   5196		i = 0;
   5197		j = 0;
   5198		spin_lock_irq(mlx4_tlock(dev));
   5199		list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
   5200			if (counter->com.owner == slave) {
   5201				counters_arr[i++] = counter->com.res_id;
   5202				rb_erase(&counter->com.node,
   5203					 &tracker->res_tree[RES_COUNTER]);
   5204				list_del(&counter->com.list);
   5205				kfree(counter);
   5206			}
   5207		}
   5208		spin_unlock_irq(mlx4_tlock(dev));
   5209
   5210		while (j < i) {
   5211			__mlx4_counter_free(dev, counters_arr[j++]);
   5212			mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
   5213		}
   5214	} while (i);
   5215
   5216	kfree(counters_arr);
   5217}
   5218
   5219static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave)
   5220{
   5221	struct mlx4_priv *priv = mlx4_priv(dev);
   5222	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
   5223	struct list_head *xrcdn_list =
   5224		&tracker->slave_list[slave].res_list[RES_XRCD];
   5225	struct res_xrcdn *xrcd;
   5226	struct res_xrcdn *tmp;
   5227	int err;
   5228	int xrcdn;
   5229
   5230	err = move_all_busy(dev, slave, RES_XRCD);
   5231	if (err)
   5232		mlx4_warn(dev, "rem_slave_xrcdns: Could not move all xrcdns - too busy for slave %d\n",
   5233			  slave);
   5234
   5235	spin_lock_irq(mlx4_tlock(dev));
   5236	list_for_each_entry_safe(xrcd, tmp, xrcdn_list, com.list) {
   5237		if (xrcd->com.owner == slave) {
   5238			xrcdn = xrcd->com.res_id;
   5239			rb_erase(&xrcd->com.node, &tracker->res_tree[RES_XRCD]);
   5240			list_del(&xrcd->com.list);
   5241			kfree(xrcd);
   5242			__mlx4_xrcd_free(dev, xrcdn);
   5243		}
   5244	}
   5245	spin_unlock_irq(mlx4_tlock(dev));
   5246}
   5247
   5248void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
   5249{
   5250	struct mlx4_priv *priv = mlx4_priv(dev);
   5251	mlx4_reset_roce_gids(dev, slave);
   5252	mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
   5253	rem_slave_vlans(dev, slave);
   5254	rem_slave_macs(dev, slave);
   5255	rem_slave_fs_rule(dev, slave);
   5256	rem_slave_qps(dev, slave);
   5257	rem_slave_srqs(dev, slave);
   5258	rem_slave_cqs(dev, slave);
   5259	rem_slave_mrs(dev, slave);
   5260	rem_slave_eqs(dev, slave);
   5261	rem_slave_mtts(dev, slave);
   5262	rem_slave_counters(dev, slave);
   5263	rem_slave_xrcdns(dev, slave);
   5264	mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
   5265}
   5266
   5267static void update_qos_vpp(struct mlx4_update_qp_context *ctx,
   5268			   struct mlx4_vf_immed_vlan_work *work)
   5269{
   5270	ctx->qp_mask |= cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_QOS_VPP);
   5271	ctx->qp_context.qos_vport = work->qos_vport;
   5272}
   5273
   5274void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
   5275{
   5276	struct mlx4_vf_immed_vlan_work *work =
   5277		container_of(_work, struct mlx4_vf_immed_vlan_work, work);
   5278	struct mlx4_cmd_mailbox *mailbox;
   5279	struct mlx4_update_qp_context *upd_context;
   5280	struct mlx4_dev *dev = &work->priv->dev;
   5281	struct mlx4_resource_tracker *tracker =
   5282		&work->priv->mfunc.master.res_tracker;
   5283	struct list_head *qp_list =
   5284		&tracker->slave_list[work->slave].res_list[RES_QP];
   5285	struct res_qp *qp;
   5286	struct res_qp *tmp;
   5287	u64 qp_path_mask_vlan_ctrl =
   5288		       ((1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED) |
   5289		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P) |
   5290		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED) |
   5291		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED) |
   5292		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P) |
   5293		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED));
   5294
   5295	u64 qp_path_mask = ((1ULL << MLX4_UPD_QP_PATH_MASK_VLAN_INDEX) |
   5296		       (1ULL << MLX4_UPD_QP_PATH_MASK_FVL) |
   5297		       (1ULL << MLX4_UPD_QP_PATH_MASK_CV) |
   5298		       (1ULL << MLX4_UPD_QP_PATH_MASK_SV) |
   5299		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_HIDE_CQE_VLAN) |
   5300		       (1ULL << MLX4_UPD_QP_PATH_MASK_FEUP) |
   5301		       (1ULL << MLX4_UPD_QP_PATH_MASK_FVL_RX) |
   5302		       (1ULL << MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE));
   5303
   5304	int err;
   5305	int port, errors = 0;
   5306	u8 vlan_control;
   5307
   5308	if (mlx4_is_slave(dev)) {
   5309		mlx4_warn(dev, "Trying to update-qp in slave %d\n",
   5310			  work->slave);
   5311		goto out;
   5312	}
   5313
   5314	mailbox = mlx4_alloc_cmd_mailbox(dev);
   5315	if (IS_ERR(mailbox))
   5316		goto out;
   5317	if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_LINK_DISABLE) /* block all */
   5318		vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
   5319			MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
   5320			MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED |
   5321			MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
   5322			MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED |
   5323			MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
   5324	else if (!work->vlan_id)
   5325		vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
   5326			MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
   5327	else if (work->vlan_proto == htons(ETH_P_8021AD))
   5328		vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
   5329			MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
   5330			MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
   5331			MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
   5332	else  /* vst 802.1Q */
   5333		vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
   5334			MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
   5335			MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
   5336
   5337	upd_context = mailbox->buf;
   5338	upd_context->qp_mask = cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_VSD);
   5339
   5340	spin_lock_irq(mlx4_tlock(dev));
   5341	list_for_each_entry_safe(qp, tmp, qp_list, com.list) {
   5342		spin_unlock_irq(mlx4_tlock(dev));
   5343		if (qp->com.owner == work->slave) {
   5344			if (qp->com.from_state != RES_QP_HW ||
   5345			    !qp->sched_queue ||  /* no INIT2RTR trans yet */
   5346			    mlx4_is_qp_reserved(dev, qp->local_qpn) ||
   5347			    qp->qpc_flags & (1 << MLX4_RSS_QPC_FLAG_OFFSET)) {
   5348				spin_lock_irq(mlx4_tlock(dev));
   5349				continue;
   5350			}
   5351			port = (qp->sched_queue >> 6 & 1) + 1;
   5352			if (port != work->port) {
   5353				spin_lock_irq(mlx4_tlock(dev));
   5354				continue;
   5355			}
   5356			if (MLX4_QP_ST_RC == ((qp->qpc_flags >> 16) & 0xff))
   5357				upd_context->primary_addr_path_mask = cpu_to_be64(qp_path_mask);
   5358			else
   5359				upd_context->primary_addr_path_mask =
   5360					cpu_to_be64(qp_path_mask | qp_path_mask_vlan_ctrl);
   5361			if (work->vlan_id == MLX4_VGT) {
   5362				upd_context->qp_context.param3 = qp->param3;
   5363				upd_context->qp_context.pri_path.vlan_control = qp->vlan_control;
   5364				upd_context->qp_context.pri_path.fvl_rx = qp->fvl_rx;
   5365				upd_context->qp_context.pri_path.vlan_index = qp->vlan_index;
   5366				upd_context->qp_context.pri_path.fl = qp->pri_path_fl;
   5367				upd_context->qp_context.pri_path.feup = qp->feup;
   5368				upd_context->qp_context.pri_path.sched_queue =
   5369					qp->sched_queue;
   5370			} else {
   5371				upd_context->qp_context.param3 = qp->param3 & ~cpu_to_be32(MLX4_STRIP_VLAN);
   5372				upd_context->qp_context.pri_path.vlan_control = vlan_control;
   5373				upd_context->qp_context.pri_path.vlan_index = work->vlan_ix;
   5374				upd_context->qp_context.pri_path.fvl_rx =
   5375					qp->fvl_rx | MLX4_FVL_RX_FORCE_ETH_VLAN;
   5376				upd_context->qp_context.pri_path.fl =
   5377					qp->pri_path_fl | MLX4_FL_ETH_HIDE_CQE_VLAN;
   5378				if (work->vlan_proto == htons(ETH_P_8021AD))
   5379					upd_context->qp_context.pri_path.fl |= MLX4_FL_SV;
   5380				else
   5381					upd_context->qp_context.pri_path.fl |= MLX4_FL_CV;
   5382				upd_context->qp_context.pri_path.feup =
   5383					qp->feup | MLX4_FEUP_FORCE_ETH_UP | MLX4_FVL_FORCE_ETH_VLAN;
   5384				upd_context->qp_context.pri_path.sched_queue =
   5385					qp->sched_queue & 0xC7;
   5386				upd_context->qp_context.pri_path.sched_queue |=
   5387					((work->qos & 0x7) << 3);
   5388
   5389				if (dev->caps.flags2 &
   5390				    MLX4_DEV_CAP_FLAG2_QOS_VPP)
   5391					update_qos_vpp(upd_context, work);
   5392			}
   5393
   5394			err = mlx4_cmd(dev, mailbox->dma,
   5395				       qp->local_qpn & 0xffffff,
   5396				       0, MLX4_CMD_UPDATE_QP,
   5397				       MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
   5398			if (err) {
   5399				mlx4_info(dev, "UPDATE_QP failed for slave %d, port %d, qpn %d (%d)\n",
   5400					  work->slave, port, qp->local_qpn, err);
   5401				errors++;
   5402			}
   5403		}
   5404		spin_lock_irq(mlx4_tlock(dev));
   5405	}
   5406	spin_unlock_irq(mlx4_tlock(dev));
   5407	mlx4_free_cmd_mailbox(dev, mailbox);
   5408
   5409	if (errors)
   5410		mlx4_err(dev, "%d UPDATE_QP failures for slave %d, port %d\n",
   5411			 errors, work->slave, work->port);
   5412
   5413	/* unregister previous vlan_id if needed and we had no errors
   5414	 * while updating the QPs
   5415	 */
   5416	if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN && !errors &&
   5417	    NO_INDX != work->orig_vlan_ix)
   5418		__mlx4_unregister_vlan(&work->priv->dev, work->port,
   5419				       work->orig_vlan_id);
   5420out:
   5421	kfree(work);
   5422	return;
   5423}