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 
46 #include "mlx4.h"
47 #include "fw.h"
48 
49 #define MLX4_MAC_VALID		(1ull << 63)
50 
51 struct mac_res {
52 	struct list_head list;
53 	u64 mac;
54 	u8 port;
55 };
56 
57 struct res_common {
58 	struct list_head	list;
59 	struct rb_node		node;
60 	u64		        res_id;
61 	int			owner;
62 	int			state;
63 	int			from_state;
64 	int			to_state;
65 	int			removing;
66 };
67 
68 enum {
69 	RES_ANY_BUSY = 1
70 };
71 
72 struct res_gid {
73 	struct list_head	list;
74 	u8			gid[16];
75 	enum mlx4_protocol	prot;
76 	enum mlx4_steer_type	steer;
77 };
78 
79 enum res_qp_states {
80 	RES_QP_BUSY = RES_ANY_BUSY,
81 
82 	/* QP number was allocated */
83 	RES_QP_RESERVED,
84 
85 	/* ICM memory for QP context was mapped */
86 	RES_QP_MAPPED,
87 
88 	/* QP is in hw ownership */
89 	RES_QP_HW
90 };
91 
92 struct res_qp {
93 	struct res_common	com;
94 	struct res_mtt	       *mtt;
95 	struct res_cq	       *rcq;
96 	struct res_cq	       *scq;
97 	struct res_srq	       *srq;
98 	struct list_head	mcg_list;
99 	spinlock_t		mcg_spl;
100 	int			local_qpn;
101 };
102 
103 enum res_mtt_states {
104 	RES_MTT_BUSY = RES_ANY_BUSY,
105 	RES_MTT_ALLOCATED,
106 };
107 
108 static inline const char *mtt_states_str(enum res_mtt_states state)
109 {
110 	switch (state) {
111 	case RES_MTT_BUSY: return "RES_MTT_BUSY";
112 	case RES_MTT_ALLOCATED: return "RES_MTT_ALLOCATED";
113 	default: return "Unknown";
114 	}
115 }
116 
117 struct res_mtt {
118 	struct res_common	com;
119 	int			order;
120 	atomic_t		ref_count;
121 };
122 
123 enum res_mpt_states {
124 	RES_MPT_BUSY = RES_ANY_BUSY,
125 	RES_MPT_RESERVED,
126 	RES_MPT_MAPPED,
127 	RES_MPT_HW,
128 };
129 
130 struct res_mpt {
131 	struct res_common	com;
132 	struct res_mtt	       *mtt;
133 	int			key;
134 };
135 
136 enum res_eq_states {
137 	RES_EQ_BUSY = RES_ANY_BUSY,
138 	RES_EQ_RESERVED,
139 	RES_EQ_HW,
140 };
141 
142 struct res_eq {
143 	struct res_common	com;
144 	struct res_mtt	       *mtt;
145 };
146 
147 enum res_cq_states {
148 	RES_CQ_BUSY = RES_ANY_BUSY,
149 	RES_CQ_ALLOCATED,
150 	RES_CQ_HW,
151 };
152 
153 struct res_cq {
154 	struct res_common	com;
155 	struct res_mtt	       *mtt;
156 	atomic_t		ref_count;
157 };
158 
159 enum res_srq_states {
160 	RES_SRQ_BUSY = RES_ANY_BUSY,
161 	RES_SRQ_ALLOCATED,
162 	RES_SRQ_HW,
163 };
164 
165 struct res_srq {
166 	struct res_common	com;
167 	struct res_mtt	       *mtt;
168 	struct res_cq	       *cq;
169 	atomic_t		ref_count;
170 };
171 
172 enum res_counter_states {
173 	RES_COUNTER_BUSY = RES_ANY_BUSY,
174 	RES_COUNTER_ALLOCATED,
175 };
176 
177 struct res_counter {
178 	struct res_common	com;
179 	int			port;
180 };
181 
182 enum res_xrcdn_states {
183 	RES_XRCD_BUSY = RES_ANY_BUSY,
184 	RES_XRCD_ALLOCATED,
185 };
186 
187 struct res_xrcdn {
188 	struct res_common	com;
189 	int			port;
190 };
191 
192 enum res_fs_rule_states {
193 	RES_FS_RULE_BUSY = RES_ANY_BUSY,
194 	RES_FS_RULE_ALLOCATED,
195 };
196 
197 struct res_fs_rule {
198 	struct res_common	com;
199 };
200 
201 static void *res_tracker_lookup(struct rb_root *root, u64 res_id)
202 {
203 	struct rb_node *node = root->rb_node;
204 
205 	while (node) {
206 		struct res_common *res = container_of(node, struct res_common,
207 						      node);
208 
209 		if (res_id < res->res_id)
210 			node = node->rb_left;
211 		else if (res_id > res->res_id)
212 			node = node->rb_right;
213 		else
214 			return res;
215 	}
216 	return NULL;
217 }
218 
219 static int res_tracker_insert(struct rb_root *root, struct res_common *res)
220 {
221 	struct rb_node **new = &(root->rb_node), *parent = NULL;
222 
223 	/* Figure out where to put new node */
224 	while (*new) {
225 		struct res_common *this = container_of(*new, struct res_common,
226 						       node);
227 
228 		parent = *new;
229 		if (res->res_id < this->res_id)
230 			new = &((*new)->rb_left);
231 		else if (res->res_id > this->res_id)
232 			new = &((*new)->rb_right);
233 		else
234 			return -EEXIST;
235 	}
236 
237 	/* Add new node and rebalance tree. */
238 	rb_link_node(&res->node, parent, new);
239 	rb_insert_color(&res->node, root);
240 
241 	return 0;
242 }
243 
244 /* For Debug uses */
245 static const char *ResourceType(enum mlx4_resource rt)
246 {
247 	switch (rt) {
248 	case RES_QP: return "RES_QP";
249 	case RES_CQ: return "RES_CQ";
250 	case RES_SRQ: return "RES_SRQ";
251 	case RES_MPT: return "RES_MPT";
252 	case RES_MTT: return "RES_MTT";
253 	case RES_MAC: return  "RES_MAC";
254 	case RES_EQ: return "RES_EQ";
255 	case RES_COUNTER: return "RES_COUNTER";
256 	case RES_FS_RULE: return "RES_FS_RULE";
257 	case RES_XRCD: return "RES_XRCD";
258 	default: return "Unknown resource type !!!";
259 	};
260 }
261 
262 int mlx4_init_resource_tracker(struct mlx4_dev *dev)
263 {
264 	struct mlx4_priv *priv = mlx4_priv(dev);
265 	int i;
266 	int t;
267 
268 	priv->mfunc.master.res_tracker.slave_list =
269 		kzalloc(dev->num_slaves * sizeof(struct slave_list),
270 			GFP_KERNEL);
271 	if (!priv->mfunc.master.res_tracker.slave_list)
272 		return -ENOMEM;
273 
274 	for (i = 0 ; i < dev->num_slaves; i++) {
275 		for (t = 0; t < MLX4_NUM_OF_RESOURCE_TYPE; ++t)
276 			INIT_LIST_HEAD(&priv->mfunc.master.res_tracker.
277 				       slave_list[i].res_list[t]);
278 		mutex_init(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
279 	}
280 
281 	mlx4_dbg(dev, "Started init_resource_tracker: %ld slaves\n",
282 		 dev->num_slaves);
283 	for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++)
284 		priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT;
285 
286 	spin_lock_init(&priv->mfunc.master.res_tracker.lock);
287 	return 0 ;
288 }
289 
290 void mlx4_free_resource_tracker(struct mlx4_dev *dev,
291 				enum mlx4_res_tracker_free_type type)
292 {
293 	struct mlx4_priv *priv = mlx4_priv(dev);
294 	int i;
295 
296 	if (priv->mfunc.master.res_tracker.slave_list) {
297 		if (type != RES_TR_FREE_STRUCTS_ONLY)
298 			for (i = 0 ; i < dev->num_slaves; i++)
299 				if (type == RES_TR_FREE_ALL ||
300 				    dev->caps.function != i)
301 					mlx4_delete_all_resources_for_slave(dev, i);
302 
303 		if (type != RES_TR_FREE_SLAVES_ONLY) {
304 			kfree(priv->mfunc.master.res_tracker.slave_list);
305 			priv->mfunc.master.res_tracker.slave_list = NULL;
306 		}
307 	}
308 }
309 
310 static void update_ud_gid(struct mlx4_dev *dev,
311 			  struct mlx4_qp_context *qp_ctx, u8 slave)
312 {
313 	u32 ts = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
314 
315 	if (MLX4_QP_ST_UD == ts)
316 		qp_ctx->pri_path.mgid_index = 0x80 | slave;
317 
318 	mlx4_dbg(dev, "slave %d, new gid index: 0x%x ",
319 		slave, qp_ctx->pri_path.mgid_index);
320 }
321 
322 static int mpt_mask(struct mlx4_dev *dev)
323 {
324 	return dev->caps.num_mpts - 1;
325 }
326 
327 static void *find_res(struct mlx4_dev *dev, int res_id,
328 		      enum mlx4_resource type)
329 {
330 	struct mlx4_priv *priv = mlx4_priv(dev);
331 
332 	return res_tracker_lookup(&priv->mfunc.master.res_tracker.res_tree[type],
333 				  res_id);
334 }
335 
336 static int get_res(struct mlx4_dev *dev, int slave, u64 res_id,
337 		   enum mlx4_resource type,
338 		   void *res)
339 {
340 	struct res_common *r;
341 	int err = 0;
342 
343 	spin_lock_irq(mlx4_tlock(dev));
344 	r = find_res(dev, res_id, type);
345 	if (!r) {
346 		err = -ENONET;
347 		goto exit;
348 	}
349 
350 	if (r->state == RES_ANY_BUSY) {
351 		err = -EBUSY;
352 		goto exit;
353 	}
354 
355 	if (r->owner != slave) {
356 		err = -EPERM;
357 		goto exit;
358 	}
359 
360 	r->from_state = r->state;
361 	r->state = RES_ANY_BUSY;
362 	mlx4_dbg(dev, "res %s id 0x%llx to busy\n",
363 		 ResourceType(type), r->res_id);
364 
365 	if (res)
366 		*((struct res_common **)res) = r;
367 
368 exit:
369 	spin_unlock_irq(mlx4_tlock(dev));
370 	return err;
371 }
372 
373 int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev,
374 				    enum mlx4_resource type,
375 				    u64 res_id, int *slave)
376 {
377 
378 	struct res_common *r;
379 	int err = -ENOENT;
380 	int id = res_id;
381 
382 	if (type == RES_QP)
383 		id &= 0x7fffff;
384 	spin_lock(mlx4_tlock(dev));
385 
386 	r = find_res(dev, id, type);
387 	if (r) {
388 		*slave = r->owner;
389 		err = 0;
390 	}
391 	spin_unlock(mlx4_tlock(dev));
392 
393 	return err;
394 }
395 
396 static void put_res(struct mlx4_dev *dev, int slave, u64 res_id,
397 		    enum mlx4_resource type)
398 {
399 	struct res_common *r;
400 
401 	spin_lock_irq(mlx4_tlock(dev));
402 	r = find_res(dev, res_id, type);
403 	if (r)
404 		r->state = r->from_state;
405 	spin_unlock_irq(mlx4_tlock(dev));
406 }
407 
408 static struct res_common *alloc_qp_tr(int id)
409 {
410 	struct res_qp *ret;
411 
412 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
413 	if (!ret)
414 		return NULL;
415 
416 	ret->com.res_id = id;
417 	ret->com.state = RES_QP_RESERVED;
418 	ret->local_qpn = id;
419 	INIT_LIST_HEAD(&ret->mcg_list);
420 	spin_lock_init(&ret->mcg_spl);
421 
422 	return &ret->com;
423 }
424 
425 static struct res_common *alloc_mtt_tr(int id, int order)
426 {
427 	struct res_mtt *ret;
428 
429 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
430 	if (!ret)
431 		return NULL;
432 
433 	ret->com.res_id = id;
434 	ret->order = order;
435 	ret->com.state = RES_MTT_ALLOCATED;
436 	atomic_set(&ret->ref_count, 0);
437 
438 	return &ret->com;
439 }
440 
441 static struct res_common *alloc_mpt_tr(int id, int key)
442 {
443 	struct res_mpt *ret;
444 
445 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
446 	if (!ret)
447 		return NULL;
448 
449 	ret->com.res_id = id;
450 	ret->com.state = RES_MPT_RESERVED;
451 	ret->key = key;
452 
453 	return &ret->com;
454 }
455 
456 static struct res_common *alloc_eq_tr(int id)
457 {
458 	struct res_eq *ret;
459 
460 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
461 	if (!ret)
462 		return NULL;
463 
464 	ret->com.res_id = id;
465 	ret->com.state = RES_EQ_RESERVED;
466 
467 	return &ret->com;
468 }
469 
470 static struct res_common *alloc_cq_tr(int id)
471 {
472 	struct res_cq *ret;
473 
474 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
475 	if (!ret)
476 		return NULL;
477 
478 	ret->com.res_id = id;
479 	ret->com.state = RES_CQ_ALLOCATED;
480 	atomic_set(&ret->ref_count, 0);
481 
482 	return &ret->com;
483 }
484 
485 static struct res_common *alloc_srq_tr(int id)
486 {
487 	struct res_srq *ret;
488 
489 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
490 	if (!ret)
491 		return NULL;
492 
493 	ret->com.res_id = id;
494 	ret->com.state = RES_SRQ_ALLOCATED;
495 	atomic_set(&ret->ref_count, 0);
496 
497 	return &ret->com;
498 }
499 
500 static struct res_common *alloc_counter_tr(int id)
501 {
502 	struct res_counter *ret;
503 
504 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
505 	if (!ret)
506 		return NULL;
507 
508 	ret->com.res_id = id;
509 	ret->com.state = RES_COUNTER_ALLOCATED;
510 
511 	return &ret->com;
512 }
513 
514 static struct res_common *alloc_xrcdn_tr(int id)
515 {
516 	struct res_xrcdn *ret;
517 
518 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
519 	if (!ret)
520 		return NULL;
521 
522 	ret->com.res_id = id;
523 	ret->com.state = RES_XRCD_ALLOCATED;
524 
525 	return &ret->com;
526 }
527 
528 static struct res_common *alloc_fs_rule_tr(u64 id)
529 {
530 	struct res_fs_rule *ret;
531 
532 	ret = kzalloc(sizeof *ret, GFP_KERNEL);
533 	if (!ret)
534 		return NULL;
535 
536 	ret->com.res_id = id;
537 	ret->com.state = RES_FS_RULE_ALLOCATED;
538 
539 	return &ret->com;
540 }
541 
542 static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
543 				   int extra)
544 {
545 	struct res_common *ret;
546 
547 	switch (type) {
548 	case RES_QP:
549 		ret = alloc_qp_tr(id);
550 		break;
551 	case RES_MPT:
552 		ret = alloc_mpt_tr(id, extra);
553 		break;
554 	case RES_MTT:
555 		ret = alloc_mtt_tr(id, extra);
556 		break;
557 	case RES_EQ:
558 		ret = alloc_eq_tr(id);
559 		break;
560 	case RES_CQ:
561 		ret = alloc_cq_tr(id);
562 		break;
563 	case RES_SRQ:
564 		ret = alloc_srq_tr(id);
565 		break;
566 	case RES_MAC:
567 		printk(KERN_ERR "implementation missing\n");
568 		return NULL;
569 	case RES_COUNTER:
570 		ret = alloc_counter_tr(id);
571 		break;
572 	case RES_XRCD:
573 		ret = alloc_xrcdn_tr(id);
574 		break;
575 	case RES_FS_RULE:
576 		ret = alloc_fs_rule_tr(id);
577 		break;
578 	default:
579 		return NULL;
580 	}
581 	if (ret)
582 		ret->owner = slave;
583 
584 	return ret;
585 }
586 
587 static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
588 			 enum mlx4_resource type, int extra)
589 {
590 	int i;
591 	int err;
592 	struct mlx4_priv *priv = mlx4_priv(dev);
593 	struct res_common **res_arr;
594 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
595 	struct rb_root *root = &tracker->res_tree[type];
596 
597 	res_arr = kzalloc(count * sizeof *res_arr, GFP_KERNEL);
598 	if (!res_arr)
599 		return -ENOMEM;
600 
601 	for (i = 0; i < count; ++i) {
602 		res_arr[i] = alloc_tr(base + i, type, slave, extra);
603 		if (!res_arr[i]) {
604 			for (--i; i >= 0; --i)
605 				kfree(res_arr[i]);
606 
607 			kfree(res_arr);
608 			return -ENOMEM;
609 		}
610 	}
611 
612 	spin_lock_irq(mlx4_tlock(dev));
613 	for (i = 0; i < count; ++i) {
614 		if (find_res(dev, base + i, type)) {
615 			err = -EEXIST;
616 			goto undo;
617 		}
618 		err = res_tracker_insert(root, res_arr[i]);
619 		if (err)
620 			goto undo;
621 		list_add_tail(&res_arr[i]->list,
622 			      &tracker->slave_list[slave].res_list[type]);
623 	}
624 	spin_unlock_irq(mlx4_tlock(dev));
625 	kfree(res_arr);
626 
627 	return 0;
628 
629 undo:
630 	for (--i; i >= base; --i)
631 		rb_erase(&res_arr[i]->node, root);
632 
633 	spin_unlock_irq(mlx4_tlock(dev));
634 
635 	for (i = 0; i < count; ++i)
636 		kfree(res_arr[i]);
637 
638 	kfree(res_arr);
639 
640 	return err;
641 }
642 
643 static int remove_qp_ok(struct res_qp *res)
644 {
645 	if (res->com.state == RES_QP_BUSY)
646 		return -EBUSY;
647 	else if (res->com.state != RES_QP_RESERVED)
648 		return -EPERM;
649 
650 	return 0;
651 }
652 
653 static int remove_mtt_ok(struct res_mtt *res, int order)
654 {
655 	if (res->com.state == RES_MTT_BUSY ||
656 	    atomic_read(&res->ref_count)) {
657 		printk(KERN_DEBUG "%s-%d: state %s, ref_count %d\n",
658 		       __func__, __LINE__,
659 		       mtt_states_str(res->com.state),
660 		       atomic_read(&res->ref_count));
661 		return -EBUSY;
662 	} else if (res->com.state != RES_MTT_ALLOCATED)
663 		return -EPERM;
664 	else if (res->order != order)
665 		return -EINVAL;
666 
667 	return 0;
668 }
669 
670 static int remove_mpt_ok(struct res_mpt *res)
671 {
672 	if (res->com.state == RES_MPT_BUSY)
673 		return -EBUSY;
674 	else if (res->com.state != RES_MPT_RESERVED)
675 		return -EPERM;
676 
677 	return 0;
678 }
679 
680 static int remove_eq_ok(struct res_eq *res)
681 {
682 	if (res->com.state == RES_MPT_BUSY)
683 		return -EBUSY;
684 	else if (res->com.state != RES_MPT_RESERVED)
685 		return -EPERM;
686 
687 	return 0;
688 }
689 
690 static int remove_counter_ok(struct res_counter *res)
691 {
692 	if (res->com.state == RES_COUNTER_BUSY)
693 		return -EBUSY;
694 	else if (res->com.state != RES_COUNTER_ALLOCATED)
695 		return -EPERM;
696 
697 	return 0;
698 }
699 
700 static int remove_xrcdn_ok(struct res_xrcdn *res)
701 {
702 	if (res->com.state == RES_XRCD_BUSY)
703 		return -EBUSY;
704 	else if (res->com.state != RES_XRCD_ALLOCATED)
705 		return -EPERM;
706 
707 	return 0;
708 }
709 
710 static int remove_fs_rule_ok(struct res_fs_rule *res)
711 {
712 	if (res->com.state == RES_FS_RULE_BUSY)
713 		return -EBUSY;
714 	else if (res->com.state != RES_FS_RULE_ALLOCATED)
715 		return -EPERM;
716 
717 	return 0;
718 }
719 
720 static int remove_cq_ok(struct res_cq *res)
721 {
722 	if (res->com.state == RES_CQ_BUSY)
723 		return -EBUSY;
724 	else if (res->com.state != RES_CQ_ALLOCATED)
725 		return -EPERM;
726 
727 	return 0;
728 }
729 
730 static int remove_srq_ok(struct res_srq *res)
731 {
732 	if (res->com.state == RES_SRQ_BUSY)
733 		return -EBUSY;
734 	else if (res->com.state != RES_SRQ_ALLOCATED)
735 		return -EPERM;
736 
737 	return 0;
738 }
739 
740 static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra)
741 {
742 	switch (type) {
743 	case RES_QP:
744 		return remove_qp_ok((struct res_qp *)res);
745 	case RES_CQ:
746 		return remove_cq_ok((struct res_cq *)res);
747 	case RES_SRQ:
748 		return remove_srq_ok((struct res_srq *)res);
749 	case RES_MPT:
750 		return remove_mpt_ok((struct res_mpt *)res);
751 	case RES_MTT:
752 		return remove_mtt_ok((struct res_mtt *)res, extra);
753 	case RES_MAC:
754 		return -ENOSYS;
755 	case RES_EQ:
756 		return remove_eq_ok((struct res_eq *)res);
757 	case RES_COUNTER:
758 		return remove_counter_ok((struct res_counter *)res);
759 	case RES_XRCD:
760 		return remove_xrcdn_ok((struct res_xrcdn *)res);
761 	case RES_FS_RULE:
762 		return remove_fs_rule_ok((struct res_fs_rule *)res);
763 	default:
764 		return -EINVAL;
765 	}
766 }
767 
768 static int rem_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
769 			 enum mlx4_resource type, int extra)
770 {
771 	u64 i;
772 	int err;
773 	struct mlx4_priv *priv = mlx4_priv(dev);
774 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
775 	struct res_common *r;
776 
777 	spin_lock_irq(mlx4_tlock(dev));
778 	for (i = base; i < base + count; ++i) {
779 		r = res_tracker_lookup(&tracker->res_tree[type], i);
780 		if (!r) {
781 			err = -ENOENT;
782 			goto out;
783 		}
784 		if (r->owner != slave) {
785 			err = -EPERM;
786 			goto out;
787 		}
788 		err = remove_ok(r, type, extra);
789 		if (err)
790 			goto out;
791 	}
792 
793 	for (i = base; i < base + count; ++i) {
794 		r = res_tracker_lookup(&tracker->res_tree[type], i);
795 		rb_erase(&r->node, &tracker->res_tree[type]);
796 		list_del(&r->list);
797 		kfree(r);
798 	}
799 	err = 0;
800 
801 out:
802 	spin_unlock_irq(mlx4_tlock(dev));
803 
804 	return err;
805 }
806 
807 static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn,
808 				enum res_qp_states state, struct res_qp **qp,
809 				int alloc)
810 {
811 	struct mlx4_priv *priv = mlx4_priv(dev);
812 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
813 	struct res_qp *r;
814 	int err = 0;
815 
816 	spin_lock_irq(mlx4_tlock(dev));
817 	r = res_tracker_lookup(&tracker->res_tree[RES_QP], qpn);
818 	if (!r)
819 		err = -ENOENT;
820 	else if (r->com.owner != slave)
821 		err = -EPERM;
822 	else {
823 		switch (state) {
824 		case RES_QP_BUSY:
825 			mlx4_dbg(dev, "%s: failed RES_QP, 0x%llx\n",
826 				 __func__, r->com.res_id);
827 			err = -EBUSY;
828 			break;
829 
830 		case RES_QP_RESERVED:
831 			if (r->com.state == RES_QP_MAPPED && !alloc)
832 				break;
833 
834 			mlx4_dbg(dev, "failed RES_QP, 0x%llx\n", r->com.res_id);
835 			err = -EINVAL;
836 			break;
837 
838 		case RES_QP_MAPPED:
839 			if ((r->com.state == RES_QP_RESERVED && alloc) ||
840 			    r->com.state == RES_QP_HW)
841 				break;
842 			else {
843 				mlx4_dbg(dev, "failed RES_QP, 0x%llx\n",
844 					  r->com.res_id);
845 				err = -EINVAL;
846 			}
847 
848 			break;
849 
850 		case RES_QP_HW:
851 			if (r->com.state != RES_QP_MAPPED)
852 				err = -EINVAL;
853 			break;
854 		default:
855 			err = -EINVAL;
856 		}
857 
858 		if (!err) {
859 			r->com.from_state = r->com.state;
860 			r->com.to_state = state;
861 			r->com.state = RES_QP_BUSY;
862 			if (qp)
863 				*qp = r;
864 		}
865 	}
866 
867 	spin_unlock_irq(mlx4_tlock(dev));
868 
869 	return err;
870 }
871 
872 static int mr_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
873 				enum res_mpt_states state, struct res_mpt **mpt)
874 {
875 	struct mlx4_priv *priv = mlx4_priv(dev);
876 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
877 	struct res_mpt *r;
878 	int err = 0;
879 
880 	spin_lock_irq(mlx4_tlock(dev));
881 	r = res_tracker_lookup(&tracker->res_tree[RES_MPT], index);
882 	if (!r)
883 		err = -ENOENT;
884 	else if (r->com.owner != slave)
885 		err = -EPERM;
886 	else {
887 		switch (state) {
888 		case RES_MPT_BUSY:
889 			err = -EINVAL;
890 			break;
891 
892 		case RES_MPT_RESERVED:
893 			if (r->com.state != RES_MPT_MAPPED)
894 				err = -EINVAL;
895 			break;
896 
897 		case RES_MPT_MAPPED:
898 			if (r->com.state != RES_MPT_RESERVED &&
899 			    r->com.state != RES_MPT_HW)
900 				err = -EINVAL;
901 			break;
902 
903 		case RES_MPT_HW:
904 			if (r->com.state != RES_MPT_MAPPED)
905 				err = -EINVAL;
906 			break;
907 		default:
908 			err = -EINVAL;
909 		}
910 
911 		if (!err) {
912 			r->com.from_state = r->com.state;
913 			r->com.to_state = state;
914 			r->com.state = RES_MPT_BUSY;
915 			if (mpt)
916 				*mpt = r;
917 		}
918 	}
919 
920 	spin_unlock_irq(mlx4_tlock(dev));
921 
922 	return err;
923 }
924 
925 static int eq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
926 				enum res_eq_states state, struct res_eq **eq)
927 {
928 	struct mlx4_priv *priv = mlx4_priv(dev);
929 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
930 	struct res_eq *r;
931 	int err = 0;
932 
933 	spin_lock_irq(mlx4_tlock(dev));
934 	r = res_tracker_lookup(&tracker->res_tree[RES_EQ], index);
935 	if (!r)
936 		err = -ENOENT;
937 	else if (r->com.owner != slave)
938 		err = -EPERM;
939 	else {
940 		switch (state) {
941 		case RES_EQ_BUSY:
942 			err = -EINVAL;
943 			break;
944 
945 		case RES_EQ_RESERVED:
946 			if (r->com.state != RES_EQ_HW)
947 				err = -EINVAL;
948 			break;
949 
950 		case RES_EQ_HW:
951 			if (r->com.state != RES_EQ_RESERVED)
952 				err = -EINVAL;
953 			break;
954 
955 		default:
956 			err = -EINVAL;
957 		}
958 
959 		if (!err) {
960 			r->com.from_state = r->com.state;
961 			r->com.to_state = state;
962 			r->com.state = RES_EQ_BUSY;
963 			if (eq)
964 				*eq = r;
965 		}
966 	}
967 
968 	spin_unlock_irq(mlx4_tlock(dev));
969 
970 	return err;
971 }
972 
973 static int cq_res_start_move_to(struct mlx4_dev *dev, int slave, int cqn,
974 				enum res_cq_states state, struct res_cq **cq)
975 {
976 	struct mlx4_priv *priv = mlx4_priv(dev);
977 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
978 	struct res_cq *r;
979 	int err;
980 
981 	spin_lock_irq(mlx4_tlock(dev));
982 	r = res_tracker_lookup(&tracker->res_tree[RES_CQ], cqn);
983 	if (!r)
984 		err = -ENOENT;
985 	else if (r->com.owner != slave)
986 		err = -EPERM;
987 	else {
988 		switch (state) {
989 		case RES_CQ_BUSY:
990 			err = -EBUSY;
991 			break;
992 
993 		case RES_CQ_ALLOCATED:
994 			if (r->com.state != RES_CQ_HW)
995 				err = -EINVAL;
996 			else if (atomic_read(&r->ref_count))
997 				err = -EBUSY;
998 			else
999 				err = 0;
1000 			break;
1001 
1002 		case RES_CQ_HW:
1003 			if (r->com.state != RES_CQ_ALLOCATED)
1004 				err = -EINVAL;
1005 			else
1006 				err = 0;
1007 			break;
1008 
1009 		default:
1010 			err = -EINVAL;
1011 		}
1012 
1013 		if (!err) {
1014 			r->com.from_state = r->com.state;
1015 			r->com.to_state = state;
1016 			r->com.state = RES_CQ_BUSY;
1017 			if (cq)
1018 				*cq = r;
1019 		}
1020 	}
1021 
1022 	spin_unlock_irq(mlx4_tlock(dev));
1023 
1024 	return err;
1025 }
1026 
1027 static int srq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
1028 				 enum res_cq_states state, struct res_srq **srq)
1029 {
1030 	struct mlx4_priv *priv = mlx4_priv(dev);
1031 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1032 	struct res_srq *r;
1033 	int err = 0;
1034 
1035 	spin_lock_irq(mlx4_tlock(dev));
1036 	r = res_tracker_lookup(&tracker->res_tree[RES_SRQ], index);
1037 	if (!r)
1038 		err = -ENOENT;
1039 	else if (r->com.owner != slave)
1040 		err = -EPERM;
1041 	else {
1042 		switch (state) {
1043 		case RES_SRQ_BUSY:
1044 			err = -EINVAL;
1045 			break;
1046 
1047 		case RES_SRQ_ALLOCATED:
1048 			if (r->com.state != RES_SRQ_HW)
1049 				err = -EINVAL;
1050 			else if (atomic_read(&r->ref_count))
1051 				err = -EBUSY;
1052 			break;
1053 
1054 		case RES_SRQ_HW:
1055 			if (r->com.state != RES_SRQ_ALLOCATED)
1056 				err = -EINVAL;
1057 			break;
1058 
1059 		default:
1060 			err = -EINVAL;
1061 		}
1062 
1063 		if (!err) {
1064 			r->com.from_state = r->com.state;
1065 			r->com.to_state = state;
1066 			r->com.state = RES_SRQ_BUSY;
1067 			if (srq)
1068 				*srq = r;
1069 		}
1070 	}
1071 
1072 	spin_unlock_irq(mlx4_tlock(dev));
1073 
1074 	return err;
1075 }
1076 
1077 static void res_abort_move(struct mlx4_dev *dev, int slave,
1078 			   enum mlx4_resource type, int id)
1079 {
1080 	struct mlx4_priv *priv = mlx4_priv(dev);
1081 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1082 	struct res_common *r;
1083 
1084 	spin_lock_irq(mlx4_tlock(dev));
1085 	r = res_tracker_lookup(&tracker->res_tree[type], id);
1086 	if (r && (r->owner == slave))
1087 		r->state = r->from_state;
1088 	spin_unlock_irq(mlx4_tlock(dev));
1089 }
1090 
1091 static void res_end_move(struct mlx4_dev *dev, int slave,
1092 			 enum mlx4_resource type, int id)
1093 {
1094 	struct mlx4_priv *priv = mlx4_priv(dev);
1095 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1096 	struct res_common *r;
1097 
1098 	spin_lock_irq(mlx4_tlock(dev));
1099 	r = res_tracker_lookup(&tracker->res_tree[type], id);
1100 	if (r && (r->owner == slave))
1101 		r->state = r->to_state;
1102 	spin_unlock_irq(mlx4_tlock(dev));
1103 }
1104 
1105 static int valid_reserved(struct mlx4_dev *dev, int slave, int qpn)
1106 {
1107 	return mlx4_is_qp_reserved(dev, qpn);
1108 }
1109 
1110 static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1111 			u64 in_param, u64 *out_param)
1112 {
1113 	int err;
1114 	int count;
1115 	int align;
1116 	int base;
1117 	int qpn;
1118 
1119 	switch (op) {
1120 	case RES_OP_RESERVE:
1121 		count = get_param_l(&in_param);
1122 		align = get_param_h(&in_param);
1123 		err = __mlx4_qp_reserve_range(dev, count, align, &base);
1124 		if (err)
1125 			return err;
1126 
1127 		err = add_res_range(dev, slave, base, count, RES_QP, 0);
1128 		if (err) {
1129 			__mlx4_qp_release_range(dev, base, count);
1130 			return err;
1131 		}
1132 		set_param_l(out_param, base);
1133 		break;
1134 	case RES_OP_MAP_ICM:
1135 		qpn = get_param_l(&in_param) & 0x7fffff;
1136 		if (valid_reserved(dev, slave, qpn)) {
1137 			err = add_res_range(dev, slave, qpn, 1, RES_QP, 0);
1138 			if (err)
1139 				return err;
1140 		}
1141 
1142 		err = qp_res_start_move_to(dev, slave, qpn, RES_QP_MAPPED,
1143 					   NULL, 1);
1144 		if (err)
1145 			return err;
1146 
1147 		if (!valid_reserved(dev, slave, qpn)) {
1148 			err = __mlx4_qp_alloc_icm(dev, qpn);
1149 			if (err) {
1150 				res_abort_move(dev, slave, RES_QP, qpn);
1151 				return err;
1152 			}
1153 		}
1154 
1155 		res_end_move(dev, slave, RES_QP, qpn);
1156 		break;
1157 
1158 	default:
1159 		err = -EINVAL;
1160 		break;
1161 	}
1162 	return err;
1163 }
1164 
1165 static int mtt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1166 			 u64 in_param, u64 *out_param)
1167 {
1168 	int err = -EINVAL;
1169 	int base;
1170 	int order;
1171 
1172 	if (op != RES_OP_RESERVE_AND_MAP)
1173 		return err;
1174 
1175 	order = get_param_l(&in_param);
1176 	base = __mlx4_alloc_mtt_range(dev, order);
1177 	if (base == -1)
1178 		return -ENOMEM;
1179 
1180 	err = add_res_range(dev, slave, base, 1, RES_MTT, order);
1181 	if (err)
1182 		__mlx4_free_mtt_range(dev, base, order);
1183 	else
1184 		set_param_l(out_param, base);
1185 
1186 	return err;
1187 }
1188 
1189 static int mpt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1190 			 u64 in_param, u64 *out_param)
1191 {
1192 	int err = -EINVAL;
1193 	int index;
1194 	int id;
1195 	struct res_mpt *mpt;
1196 
1197 	switch (op) {
1198 	case RES_OP_RESERVE:
1199 		index = __mlx4_mr_reserve(dev);
1200 		if (index == -1)
1201 			break;
1202 		id = index & mpt_mask(dev);
1203 
1204 		err = add_res_range(dev, slave, id, 1, RES_MPT, index);
1205 		if (err) {
1206 			__mlx4_mr_release(dev, index);
1207 			break;
1208 		}
1209 		set_param_l(out_param, index);
1210 		break;
1211 	case RES_OP_MAP_ICM:
1212 		index = get_param_l(&in_param);
1213 		id = index & mpt_mask(dev);
1214 		err = mr_res_start_move_to(dev, slave, id,
1215 					   RES_MPT_MAPPED, &mpt);
1216 		if (err)
1217 			return err;
1218 
1219 		err = __mlx4_mr_alloc_icm(dev, mpt->key);
1220 		if (err) {
1221 			res_abort_move(dev, slave, RES_MPT, id);
1222 			return err;
1223 		}
1224 
1225 		res_end_move(dev, slave, RES_MPT, id);
1226 		break;
1227 	}
1228 	return err;
1229 }
1230 
1231 static int cq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1232 			u64 in_param, u64 *out_param)
1233 {
1234 	int cqn;
1235 	int err;
1236 
1237 	switch (op) {
1238 	case RES_OP_RESERVE_AND_MAP:
1239 		err = __mlx4_cq_alloc_icm(dev, &cqn);
1240 		if (err)
1241 			break;
1242 
1243 		err = add_res_range(dev, slave, cqn, 1, RES_CQ, 0);
1244 		if (err) {
1245 			__mlx4_cq_free_icm(dev, cqn);
1246 			break;
1247 		}
1248 
1249 		set_param_l(out_param, cqn);
1250 		break;
1251 
1252 	default:
1253 		err = -EINVAL;
1254 	}
1255 
1256 	return err;
1257 }
1258 
1259 static int srq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1260 			 u64 in_param, u64 *out_param)
1261 {
1262 	int srqn;
1263 	int err;
1264 
1265 	switch (op) {
1266 	case RES_OP_RESERVE_AND_MAP:
1267 		err = __mlx4_srq_alloc_icm(dev, &srqn);
1268 		if (err)
1269 			break;
1270 
1271 		err = add_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
1272 		if (err) {
1273 			__mlx4_srq_free_icm(dev, srqn);
1274 			break;
1275 		}
1276 
1277 		set_param_l(out_param, srqn);
1278 		break;
1279 
1280 	default:
1281 		err = -EINVAL;
1282 	}
1283 
1284 	return err;
1285 }
1286 
1287 static int mac_add_to_slave(struct mlx4_dev *dev, int slave, u64 mac, int port)
1288 {
1289 	struct mlx4_priv *priv = mlx4_priv(dev);
1290 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1291 	struct mac_res *res;
1292 
1293 	res = kzalloc(sizeof *res, GFP_KERNEL);
1294 	if (!res)
1295 		return -ENOMEM;
1296 	res->mac = mac;
1297 	res->port = (u8) port;
1298 	list_add_tail(&res->list,
1299 		      &tracker->slave_list[slave].res_list[RES_MAC]);
1300 	return 0;
1301 }
1302 
1303 static void mac_del_from_slave(struct mlx4_dev *dev, int slave, u64 mac,
1304 			       int port)
1305 {
1306 	struct mlx4_priv *priv = mlx4_priv(dev);
1307 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1308 	struct list_head *mac_list =
1309 		&tracker->slave_list[slave].res_list[RES_MAC];
1310 	struct mac_res *res, *tmp;
1311 
1312 	list_for_each_entry_safe(res, tmp, mac_list, list) {
1313 		if (res->mac == mac && res->port == (u8) port) {
1314 			list_del(&res->list);
1315 			kfree(res);
1316 			break;
1317 		}
1318 	}
1319 }
1320 
1321 static void rem_slave_macs(struct mlx4_dev *dev, int slave)
1322 {
1323 	struct mlx4_priv *priv = mlx4_priv(dev);
1324 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1325 	struct list_head *mac_list =
1326 		&tracker->slave_list[slave].res_list[RES_MAC];
1327 	struct mac_res *res, *tmp;
1328 
1329 	list_for_each_entry_safe(res, tmp, mac_list, list) {
1330 		list_del(&res->list);
1331 		__mlx4_unregister_mac(dev, res->port, res->mac);
1332 		kfree(res);
1333 	}
1334 }
1335 
1336 static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1337 			 u64 in_param, u64 *out_param)
1338 {
1339 	int err = -EINVAL;
1340 	int port;
1341 	u64 mac;
1342 
1343 	if (op != RES_OP_RESERVE_AND_MAP)
1344 		return err;
1345 
1346 	port = get_param_l(out_param);
1347 	mac = in_param;
1348 
1349 	err = __mlx4_register_mac(dev, port, mac);
1350 	if (err >= 0) {
1351 		set_param_l(out_param, err);
1352 		err = 0;
1353 	}
1354 
1355 	if (!err) {
1356 		err = mac_add_to_slave(dev, slave, mac, port);
1357 		if (err)
1358 			__mlx4_unregister_mac(dev, port, mac);
1359 	}
1360 	return err;
1361 }
1362 
1363 static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1364 			 u64 in_param, u64 *out_param)
1365 {
1366 	return 0;
1367 }
1368 
1369 static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1370 			     u64 in_param, u64 *out_param)
1371 {
1372 	u32 index;
1373 	int err;
1374 
1375 	if (op != RES_OP_RESERVE)
1376 		return -EINVAL;
1377 
1378 	err = __mlx4_counter_alloc(dev, &index);
1379 	if (err)
1380 		return err;
1381 
1382 	err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0);
1383 	if (err)
1384 		__mlx4_counter_free(dev, index);
1385 	else
1386 		set_param_l(out_param, index);
1387 
1388 	return err;
1389 }
1390 
1391 static int xrcdn_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1392 			   u64 in_param, u64 *out_param)
1393 {
1394 	u32 xrcdn;
1395 	int err;
1396 
1397 	if (op != RES_OP_RESERVE)
1398 		return -EINVAL;
1399 
1400 	err = __mlx4_xrcd_alloc(dev, &xrcdn);
1401 	if (err)
1402 		return err;
1403 
1404 	err = add_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
1405 	if (err)
1406 		__mlx4_xrcd_free(dev, xrcdn);
1407 	else
1408 		set_param_l(out_param, xrcdn);
1409 
1410 	return err;
1411 }
1412 
1413 int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
1414 			   struct mlx4_vhcr *vhcr,
1415 			   struct mlx4_cmd_mailbox *inbox,
1416 			   struct mlx4_cmd_mailbox *outbox,
1417 			   struct mlx4_cmd_info *cmd)
1418 {
1419 	int err;
1420 	int alop = vhcr->op_modifier;
1421 
1422 	switch (vhcr->in_modifier) {
1423 	case RES_QP:
1424 		err = qp_alloc_res(dev, slave, vhcr->op_modifier, alop,
1425 				   vhcr->in_param, &vhcr->out_param);
1426 		break;
1427 
1428 	case RES_MTT:
1429 		err = mtt_alloc_res(dev, slave, vhcr->op_modifier, alop,
1430 				    vhcr->in_param, &vhcr->out_param);
1431 		break;
1432 
1433 	case RES_MPT:
1434 		err = mpt_alloc_res(dev, slave, vhcr->op_modifier, alop,
1435 				    vhcr->in_param, &vhcr->out_param);
1436 		break;
1437 
1438 	case RES_CQ:
1439 		err = cq_alloc_res(dev, slave, vhcr->op_modifier, alop,
1440 				   vhcr->in_param, &vhcr->out_param);
1441 		break;
1442 
1443 	case RES_SRQ:
1444 		err = srq_alloc_res(dev, slave, vhcr->op_modifier, alop,
1445 				    vhcr->in_param, &vhcr->out_param);
1446 		break;
1447 
1448 	case RES_MAC:
1449 		err = mac_alloc_res(dev, slave, vhcr->op_modifier, alop,
1450 				    vhcr->in_param, &vhcr->out_param);
1451 		break;
1452 
1453 	case RES_VLAN:
1454 		err = vlan_alloc_res(dev, slave, vhcr->op_modifier, alop,
1455 				    vhcr->in_param, &vhcr->out_param);
1456 		break;
1457 
1458 	case RES_COUNTER:
1459 		err = counter_alloc_res(dev, slave, vhcr->op_modifier, alop,
1460 					vhcr->in_param, &vhcr->out_param);
1461 		break;
1462 
1463 	case RES_XRCD:
1464 		err = xrcdn_alloc_res(dev, slave, vhcr->op_modifier, alop,
1465 				      vhcr->in_param, &vhcr->out_param);
1466 		break;
1467 
1468 	default:
1469 		err = -EINVAL;
1470 		break;
1471 	}
1472 
1473 	return err;
1474 }
1475 
1476 static int qp_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1477 		       u64 in_param)
1478 {
1479 	int err;
1480 	int count;
1481 	int base;
1482 	int qpn;
1483 
1484 	switch (op) {
1485 	case RES_OP_RESERVE:
1486 		base = get_param_l(&in_param) & 0x7fffff;
1487 		count = get_param_h(&in_param);
1488 		err = rem_res_range(dev, slave, base, count, RES_QP, 0);
1489 		if (err)
1490 			break;
1491 		__mlx4_qp_release_range(dev, base, count);
1492 		break;
1493 	case RES_OP_MAP_ICM:
1494 		qpn = get_param_l(&in_param) & 0x7fffff;
1495 		err = qp_res_start_move_to(dev, slave, qpn, RES_QP_RESERVED,
1496 					   NULL, 0);
1497 		if (err)
1498 			return err;
1499 
1500 		if (!valid_reserved(dev, slave, qpn))
1501 			__mlx4_qp_free_icm(dev, qpn);
1502 
1503 		res_end_move(dev, slave, RES_QP, qpn);
1504 
1505 		if (valid_reserved(dev, slave, qpn))
1506 			err = rem_res_range(dev, slave, qpn, 1, RES_QP, 0);
1507 		break;
1508 	default:
1509 		err = -EINVAL;
1510 		break;
1511 	}
1512 	return err;
1513 }
1514 
1515 static int mtt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1516 			u64 in_param, u64 *out_param)
1517 {
1518 	int err = -EINVAL;
1519 	int base;
1520 	int order;
1521 
1522 	if (op != RES_OP_RESERVE_AND_MAP)
1523 		return err;
1524 
1525 	base = get_param_l(&in_param);
1526 	order = get_param_h(&in_param);
1527 	err = rem_res_range(dev, slave, base, 1, RES_MTT, order);
1528 	if (!err)
1529 		__mlx4_free_mtt_range(dev, base, order);
1530 	return err;
1531 }
1532 
1533 static int mpt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1534 			u64 in_param)
1535 {
1536 	int err = -EINVAL;
1537 	int index;
1538 	int id;
1539 	struct res_mpt *mpt;
1540 
1541 	switch (op) {
1542 	case RES_OP_RESERVE:
1543 		index = get_param_l(&in_param);
1544 		id = index & mpt_mask(dev);
1545 		err = get_res(dev, slave, id, RES_MPT, &mpt);
1546 		if (err)
1547 			break;
1548 		index = mpt->key;
1549 		put_res(dev, slave, id, RES_MPT);
1550 
1551 		err = rem_res_range(dev, slave, id, 1, RES_MPT, 0);
1552 		if (err)
1553 			break;
1554 		__mlx4_mr_release(dev, index);
1555 		break;
1556 	case RES_OP_MAP_ICM:
1557 			index = get_param_l(&in_param);
1558 			id = index & mpt_mask(dev);
1559 			err = mr_res_start_move_to(dev, slave, id,
1560 						   RES_MPT_RESERVED, &mpt);
1561 			if (err)
1562 				return err;
1563 
1564 			__mlx4_mr_free_icm(dev, mpt->key);
1565 			res_end_move(dev, slave, RES_MPT, id);
1566 			return err;
1567 		break;
1568 	default:
1569 		err = -EINVAL;
1570 		break;
1571 	}
1572 	return err;
1573 }
1574 
1575 static int cq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1576 		       u64 in_param, u64 *out_param)
1577 {
1578 	int cqn;
1579 	int err;
1580 
1581 	switch (op) {
1582 	case RES_OP_RESERVE_AND_MAP:
1583 		cqn = get_param_l(&in_param);
1584 		err = rem_res_range(dev, slave, cqn, 1, RES_CQ, 0);
1585 		if (err)
1586 			break;
1587 
1588 		__mlx4_cq_free_icm(dev, cqn);
1589 		break;
1590 
1591 	default:
1592 		err = -EINVAL;
1593 		break;
1594 	}
1595 
1596 	return err;
1597 }
1598 
1599 static int srq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1600 			u64 in_param, u64 *out_param)
1601 {
1602 	int srqn;
1603 	int err;
1604 
1605 	switch (op) {
1606 	case RES_OP_RESERVE_AND_MAP:
1607 		srqn = get_param_l(&in_param);
1608 		err = rem_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
1609 		if (err)
1610 			break;
1611 
1612 		__mlx4_srq_free_icm(dev, srqn);
1613 		break;
1614 
1615 	default:
1616 		err = -EINVAL;
1617 		break;
1618 	}
1619 
1620 	return err;
1621 }
1622 
1623 static int mac_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1624 			    u64 in_param, u64 *out_param)
1625 {
1626 	int port;
1627 	int err = 0;
1628 
1629 	switch (op) {
1630 	case RES_OP_RESERVE_AND_MAP:
1631 		port = get_param_l(out_param);
1632 		mac_del_from_slave(dev, slave, in_param, port);
1633 		__mlx4_unregister_mac(dev, port, in_param);
1634 		break;
1635 	default:
1636 		err = -EINVAL;
1637 		break;
1638 	}
1639 
1640 	return err;
1641 
1642 }
1643 
1644 static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1645 			    u64 in_param, u64 *out_param)
1646 {
1647 	return 0;
1648 }
1649 
1650 static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1651 			    u64 in_param, u64 *out_param)
1652 {
1653 	int index;
1654 	int err;
1655 
1656 	if (op != RES_OP_RESERVE)
1657 		return -EINVAL;
1658 
1659 	index = get_param_l(&in_param);
1660 	err = rem_res_range(dev, slave, index, 1, RES_COUNTER, 0);
1661 	if (err)
1662 		return err;
1663 
1664 	__mlx4_counter_free(dev, index);
1665 
1666 	return err;
1667 }
1668 
1669 static int xrcdn_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1670 			  u64 in_param, u64 *out_param)
1671 {
1672 	int xrcdn;
1673 	int err;
1674 
1675 	if (op != RES_OP_RESERVE)
1676 		return -EINVAL;
1677 
1678 	xrcdn = get_param_l(&in_param);
1679 	err = rem_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
1680 	if (err)
1681 		return err;
1682 
1683 	__mlx4_xrcd_free(dev, xrcdn);
1684 
1685 	return err;
1686 }
1687 
1688 int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
1689 			  struct mlx4_vhcr *vhcr,
1690 			  struct mlx4_cmd_mailbox *inbox,
1691 			  struct mlx4_cmd_mailbox *outbox,
1692 			  struct mlx4_cmd_info *cmd)
1693 {
1694 	int err = -EINVAL;
1695 	int alop = vhcr->op_modifier;
1696 
1697 	switch (vhcr->in_modifier) {
1698 	case RES_QP:
1699 		err = qp_free_res(dev, slave, vhcr->op_modifier, alop,
1700 				  vhcr->in_param);
1701 		break;
1702 
1703 	case RES_MTT:
1704 		err = mtt_free_res(dev, slave, vhcr->op_modifier, alop,
1705 				   vhcr->in_param, &vhcr->out_param);
1706 		break;
1707 
1708 	case RES_MPT:
1709 		err = mpt_free_res(dev, slave, vhcr->op_modifier, alop,
1710 				   vhcr->in_param);
1711 		break;
1712 
1713 	case RES_CQ:
1714 		err = cq_free_res(dev, slave, vhcr->op_modifier, alop,
1715 				  vhcr->in_param, &vhcr->out_param);
1716 		break;
1717 
1718 	case RES_SRQ:
1719 		err = srq_free_res(dev, slave, vhcr->op_modifier, alop,
1720 				   vhcr->in_param, &vhcr->out_param);
1721 		break;
1722 
1723 	case RES_MAC:
1724 		err = mac_free_res(dev, slave, vhcr->op_modifier, alop,
1725 				   vhcr->in_param, &vhcr->out_param);
1726 		break;
1727 
1728 	case RES_VLAN:
1729 		err = vlan_free_res(dev, slave, vhcr->op_modifier, alop,
1730 				   vhcr->in_param, &vhcr->out_param);
1731 		break;
1732 
1733 	case RES_COUNTER:
1734 		err = counter_free_res(dev, slave, vhcr->op_modifier, alop,
1735 				       vhcr->in_param, &vhcr->out_param);
1736 		break;
1737 
1738 	case RES_XRCD:
1739 		err = xrcdn_free_res(dev, slave, vhcr->op_modifier, alop,
1740 				     vhcr->in_param, &vhcr->out_param);
1741 
1742 	default:
1743 		break;
1744 	}
1745 	return err;
1746 }
1747 
1748 /* ugly but other choices are uglier */
1749 static int mr_phys_mpt(struct mlx4_mpt_entry *mpt)
1750 {
1751 	return (be32_to_cpu(mpt->flags) >> 9) & 1;
1752 }
1753 
1754 static int mr_get_mtt_addr(struct mlx4_mpt_entry *mpt)
1755 {
1756 	return (int)be64_to_cpu(mpt->mtt_addr) & 0xfffffff8;
1757 }
1758 
1759 static int mr_get_mtt_size(struct mlx4_mpt_entry *mpt)
1760 {
1761 	return be32_to_cpu(mpt->mtt_sz);
1762 }
1763 
1764 static int qp_get_mtt_addr(struct mlx4_qp_context *qpc)
1765 {
1766 	return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8;
1767 }
1768 
1769 static int srq_get_mtt_addr(struct mlx4_srq_context *srqc)
1770 {
1771 	return be32_to_cpu(srqc->mtt_base_addr_l) & 0xfffffff8;
1772 }
1773 
1774 static int qp_get_mtt_size(struct mlx4_qp_context *qpc)
1775 {
1776 	int page_shift = (qpc->log_page_size & 0x3f) + 12;
1777 	int log_sq_size = (qpc->sq_size_stride >> 3) & 0xf;
1778 	int log_sq_sride = qpc->sq_size_stride & 7;
1779 	int log_rq_size = (qpc->rq_size_stride >> 3) & 0xf;
1780 	int log_rq_stride = qpc->rq_size_stride & 7;
1781 	int srq = (be32_to_cpu(qpc->srqn) >> 24) & 1;
1782 	int rss = (be32_to_cpu(qpc->flags) >> 13) & 1;
1783 	int xrc = (be32_to_cpu(qpc->local_qpn) >> 23) & 1;
1784 	int sq_size;
1785 	int rq_size;
1786 	int total_pages;
1787 	int total_mem;
1788 	int page_offset = (be32_to_cpu(qpc->params2) >> 6) & 0x3f;
1789 
1790 	sq_size = 1 << (log_sq_size + log_sq_sride + 4);
1791 	rq_size = (srq|rss|xrc) ? 0 : (1 << (log_rq_size + log_rq_stride + 4));
1792 	total_mem = sq_size + rq_size;
1793 	total_pages =
1794 		roundup_pow_of_two((total_mem + (page_offset << 6)) >>
1795 				   page_shift);
1796 
1797 	return total_pages;
1798 }
1799 
1800 static int check_mtt_range(struct mlx4_dev *dev, int slave, int start,
1801 			   int size, struct res_mtt *mtt)
1802 {
1803 	int res_start = mtt->com.res_id;
1804 	int res_size = (1 << mtt->order);
1805 
1806 	if (start < res_start || start + size > res_start + res_size)
1807 		return -EPERM;
1808 	return 0;
1809 }
1810 
1811 int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev *dev, int slave,
1812 			   struct mlx4_vhcr *vhcr,
1813 			   struct mlx4_cmd_mailbox *inbox,
1814 			   struct mlx4_cmd_mailbox *outbox,
1815 			   struct mlx4_cmd_info *cmd)
1816 {
1817 	int err;
1818 	int index = vhcr->in_modifier;
1819 	struct res_mtt *mtt;
1820 	struct res_mpt *mpt;
1821 	int mtt_base = mr_get_mtt_addr(inbox->buf) / dev->caps.mtt_entry_sz;
1822 	int phys;
1823 	int id;
1824 
1825 	id = index & mpt_mask(dev);
1826 	err = mr_res_start_move_to(dev, slave, id, RES_MPT_HW, &mpt);
1827 	if (err)
1828 		return err;
1829 
1830 	phys = mr_phys_mpt(inbox->buf);
1831 	if (!phys) {
1832 		err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
1833 		if (err)
1834 			goto ex_abort;
1835 
1836 		err = check_mtt_range(dev, slave, mtt_base,
1837 				      mr_get_mtt_size(inbox->buf), mtt);
1838 		if (err)
1839 			goto ex_put;
1840 
1841 		mpt->mtt = mtt;
1842 	}
1843 
1844 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
1845 	if (err)
1846 		goto ex_put;
1847 
1848 	if (!phys) {
1849 		atomic_inc(&mtt->ref_count);
1850 		put_res(dev, slave, mtt->com.res_id, RES_MTT);
1851 	}
1852 
1853 	res_end_move(dev, slave, RES_MPT, id);
1854 	return 0;
1855 
1856 ex_put:
1857 	if (!phys)
1858 		put_res(dev, slave, mtt->com.res_id, RES_MTT);
1859 ex_abort:
1860 	res_abort_move(dev, slave, RES_MPT, id);
1861 
1862 	return err;
1863 }
1864 
1865 int mlx4_HW2SW_MPT_wrapper(struct mlx4_dev *dev, int slave,
1866 			   struct mlx4_vhcr *vhcr,
1867 			   struct mlx4_cmd_mailbox *inbox,
1868 			   struct mlx4_cmd_mailbox *outbox,
1869 			   struct mlx4_cmd_info *cmd)
1870 {
1871 	int err;
1872 	int index = vhcr->in_modifier;
1873 	struct res_mpt *mpt;
1874 	int id;
1875 
1876 	id = index & mpt_mask(dev);
1877 	err = mr_res_start_move_to(dev, slave, id, RES_MPT_MAPPED, &mpt);
1878 	if (err)
1879 		return err;
1880 
1881 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
1882 	if (err)
1883 		goto ex_abort;
1884 
1885 	if (mpt->mtt)
1886 		atomic_dec(&mpt->mtt->ref_count);
1887 
1888 	res_end_move(dev, slave, RES_MPT, id);
1889 	return 0;
1890 
1891 ex_abort:
1892 	res_abort_move(dev, slave, RES_MPT, id);
1893 
1894 	return err;
1895 }
1896 
1897 int mlx4_QUERY_MPT_wrapper(struct mlx4_dev *dev, int slave,
1898 			   struct mlx4_vhcr *vhcr,
1899 			   struct mlx4_cmd_mailbox *inbox,
1900 			   struct mlx4_cmd_mailbox *outbox,
1901 			   struct mlx4_cmd_info *cmd)
1902 {
1903 	int err;
1904 	int index = vhcr->in_modifier;
1905 	struct res_mpt *mpt;
1906 	int id;
1907 
1908 	id = index & mpt_mask(dev);
1909 	err = get_res(dev, slave, id, RES_MPT, &mpt);
1910 	if (err)
1911 		return err;
1912 
1913 	if (mpt->com.from_state != RES_MPT_HW) {
1914 		err = -EBUSY;
1915 		goto out;
1916 	}
1917 
1918 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
1919 
1920 out:
1921 	put_res(dev, slave, id, RES_MPT);
1922 	return err;
1923 }
1924 
1925 static int qp_get_rcqn(struct mlx4_qp_context *qpc)
1926 {
1927 	return be32_to_cpu(qpc->cqn_recv) & 0xffffff;
1928 }
1929 
1930 static int qp_get_scqn(struct mlx4_qp_context *qpc)
1931 {
1932 	return be32_to_cpu(qpc->cqn_send) & 0xffffff;
1933 }
1934 
1935 static u32 qp_get_srqn(struct mlx4_qp_context *qpc)
1936 {
1937 	return be32_to_cpu(qpc->srqn) & 0x1ffffff;
1938 }
1939 
1940 int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
1941 			     struct mlx4_vhcr *vhcr,
1942 			     struct mlx4_cmd_mailbox *inbox,
1943 			     struct mlx4_cmd_mailbox *outbox,
1944 			     struct mlx4_cmd_info *cmd)
1945 {
1946 	int err;
1947 	int qpn = vhcr->in_modifier & 0x7fffff;
1948 	struct res_mtt *mtt;
1949 	struct res_qp *qp;
1950 	struct mlx4_qp_context *qpc = inbox->buf + 8;
1951 	int mtt_base = qp_get_mtt_addr(qpc) / dev->caps.mtt_entry_sz;
1952 	int mtt_size = qp_get_mtt_size(qpc);
1953 	struct res_cq *rcq;
1954 	struct res_cq *scq;
1955 	int rcqn = qp_get_rcqn(qpc);
1956 	int scqn = qp_get_scqn(qpc);
1957 	u32 srqn = qp_get_srqn(qpc) & 0xffffff;
1958 	int use_srq = (qp_get_srqn(qpc) >> 24) & 1;
1959 	struct res_srq *srq;
1960 	int local_qpn = be32_to_cpu(qpc->local_qpn) & 0xffffff;
1961 
1962 	err = qp_res_start_move_to(dev, slave, qpn, RES_QP_HW, &qp, 0);
1963 	if (err)
1964 		return err;
1965 	qp->local_qpn = local_qpn;
1966 
1967 	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
1968 	if (err)
1969 		goto ex_abort;
1970 
1971 	err = check_mtt_range(dev, slave, mtt_base, mtt_size, mtt);
1972 	if (err)
1973 		goto ex_put_mtt;
1974 
1975 	err = get_res(dev, slave, rcqn, RES_CQ, &rcq);
1976 	if (err)
1977 		goto ex_put_mtt;
1978 
1979 	if (scqn != rcqn) {
1980 		err = get_res(dev, slave, scqn, RES_CQ, &scq);
1981 		if (err)
1982 			goto ex_put_rcq;
1983 	} else
1984 		scq = rcq;
1985 
1986 	if (use_srq) {
1987 		err = get_res(dev, slave, srqn, RES_SRQ, &srq);
1988 		if (err)
1989 			goto ex_put_scq;
1990 	}
1991 
1992 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
1993 	if (err)
1994 		goto ex_put_srq;
1995 	atomic_inc(&mtt->ref_count);
1996 	qp->mtt = mtt;
1997 	atomic_inc(&rcq->ref_count);
1998 	qp->rcq = rcq;
1999 	atomic_inc(&scq->ref_count);
2000 	qp->scq = scq;
2001 
2002 	if (scqn != rcqn)
2003 		put_res(dev, slave, scqn, RES_CQ);
2004 
2005 	if (use_srq) {
2006 		atomic_inc(&srq->ref_count);
2007 		put_res(dev, slave, srqn, RES_SRQ);
2008 		qp->srq = srq;
2009 	}
2010 	put_res(dev, slave, rcqn, RES_CQ);
2011 	put_res(dev, slave, mtt_base, RES_MTT);
2012 	res_end_move(dev, slave, RES_QP, qpn);
2013 
2014 	return 0;
2015 
2016 ex_put_srq:
2017 	if (use_srq)
2018 		put_res(dev, slave, srqn, RES_SRQ);
2019 ex_put_scq:
2020 	if (scqn != rcqn)
2021 		put_res(dev, slave, scqn, RES_CQ);
2022 ex_put_rcq:
2023 	put_res(dev, slave, rcqn, RES_CQ);
2024 ex_put_mtt:
2025 	put_res(dev, slave, mtt_base, RES_MTT);
2026 ex_abort:
2027 	res_abort_move(dev, slave, RES_QP, qpn);
2028 
2029 	return err;
2030 }
2031 
2032 static int eq_get_mtt_addr(struct mlx4_eq_context *eqc)
2033 {
2034 	return be32_to_cpu(eqc->mtt_base_addr_l) & 0xfffffff8;
2035 }
2036 
2037 static int eq_get_mtt_size(struct mlx4_eq_context *eqc)
2038 {
2039 	int log_eq_size = eqc->log_eq_size & 0x1f;
2040 	int page_shift = (eqc->log_page_size & 0x3f) + 12;
2041 
2042 	if (log_eq_size + 5 < page_shift)
2043 		return 1;
2044 
2045 	return 1 << (log_eq_size + 5 - page_shift);
2046 }
2047 
2048 static int cq_get_mtt_addr(struct mlx4_cq_context *cqc)
2049 {
2050 	return be32_to_cpu(cqc->mtt_base_addr_l) & 0xfffffff8;
2051 }
2052 
2053 static int cq_get_mtt_size(struct mlx4_cq_context *cqc)
2054 {
2055 	int log_cq_size = (be32_to_cpu(cqc->logsize_usrpage) >> 24) & 0x1f;
2056 	int page_shift = (cqc->log_page_size & 0x3f) + 12;
2057 
2058 	if (log_cq_size + 5 < page_shift)
2059 		return 1;
2060 
2061 	return 1 << (log_cq_size + 5 - page_shift);
2062 }
2063 
2064 int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave,
2065 			  struct mlx4_vhcr *vhcr,
2066 			  struct mlx4_cmd_mailbox *inbox,
2067 			  struct mlx4_cmd_mailbox *outbox,
2068 			  struct mlx4_cmd_info *cmd)
2069 {
2070 	int err;
2071 	int eqn = vhcr->in_modifier;
2072 	int res_id = (slave << 8) | eqn;
2073 	struct mlx4_eq_context *eqc = inbox->buf;
2074 	int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz;
2075 	int mtt_size = eq_get_mtt_size(eqc);
2076 	struct res_eq *eq;
2077 	struct res_mtt *mtt;
2078 
2079 	err = add_res_range(dev, slave, res_id, 1, RES_EQ, 0);
2080 	if (err)
2081 		return err;
2082 	err = eq_res_start_move_to(dev, slave, res_id, RES_EQ_HW, &eq);
2083 	if (err)
2084 		goto out_add;
2085 
2086 	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
2087 	if (err)
2088 		goto out_move;
2089 
2090 	err = check_mtt_range(dev, slave, mtt_base, mtt_size, mtt);
2091 	if (err)
2092 		goto out_put;
2093 
2094 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2095 	if (err)
2096 		goto out_put;
2097 
2098 	atomic_inc(&mtt->ref_count);
2099 	eq->mtt = mtt;
2100 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2101 	res_end_move(dev, slave, RES_EQ, res_id);
2102 	return 0;
2103 
2104 out_put:
2105 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2106 out_move:
2107 	res_abort_move(dev, slave, RES_EQ, res_id);
2108 out_add:
2109 	rem_res_range(dev, slave, res_id, 1, RES_EQ, 0);
2110 	return err;
2111 }
2112 
2113 static int get_containing_mtt(struct mlx4_dev *dev, int slave, int start,
2114 			      int len, struct res_mtt **res)
2115 {
2116 	struct mlx4_priv *priv = mlx4_priv(dev);
2117 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2118 	struct res_mtt *mtt;
2119 	int err = -EINVAL;
2120 
2121 	spin_lock_irq(mlx4_tlock(dev));
2122 	list_for_each_entry(mtt, &tracker->slave_list[slave].res_list[RES_MTT],
2123 			    com.list) {
2124 		if (!check_mtt_range(dev, slave, start, len, mtt)) {
2125 			*res = mtt;
2126 			mtt->com.from_state = mtt->com.state;
2127 			mtt->com.state = RES_MTT_BUSY;
2128 			err = 0;
2129 			break;
2130 		}
2131 	}
2132 	spin_unlock_irq(mlx4_tlock(dev));
2133 
2134 	return err;
2135 }
2136 
2137 int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave,
2138 			   struct mlx4_vhcr *vhcr,
2139 			   struct mlx4_cmd_mailbox *inbox,
2140 			   struct mlx4_cmd_mailbox *outbox,
2141 			   struct mlx4_cmd_info *cmd)
2142 {
2143 	struct mlx4_mtt mtt;
2144 	__be64 *page_list = inbox->buf;
2145 	u64 *pg_list = (u64 *)page_list;
2146 	int i;
2147 	struct res_mtt *rmtt = NULL;
2148 	int start = be64_to_cpu(page_list[0]);
2149 	int npages = vhcr->in_modifier;
2150 	int err;
2151 
2152 	err = get_containing_mtt(dev, slave, start, npages, &rmtt);
2153 	if (err)
2154 		return err;
2155 
2156 	/* Call the SW implementation of write_mtt:
2157 	 * - Prepare a dummy mtt struct
2158 	 * - Translate inbox contents to simple addresses in host endianess */
2159 	mtt.offset = 0;  /* TBD this is broken but I don't handle it since
2160 			    we don't really use it */
2161 	mtt.order = 0;
2162 	mtt.page_shift = 0;
2163 	for (i = 0; i < npages; ++i)
2164 		pg_list[i + 2] = (be64_to_cpu(page_list[i + 2]) & ~1ULL);
2165 
2166 	err = __mlx4_write_mtt(dev, &mtt, be64_to_cpu(page_list[0]), npages,
2167 			       ((u64 *)page_list + 2));
2168 
2169 	if (rmtt)
2170 		put_res(dev, slave, rmtt->com.res_id, RES_MTT);
2171 
2172 	return err;
2173 }
2174 
2175 int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave,
2176 			  struct mlx4_vhcr *vhcr,
2177 			  struct mlx4_cmd_mailbox *inbox,
2178 			  struct mlx4_cmd_mailbox *outbox,
2179 			  struct mlx4_cmd_info *cmd)
2180 {
2181 	int eqn = vhcr->in_modifier;
2182 	int res_id = eqn | (slave << 8);
2183 	struct res_eq *eq;
2184 	int err;
2185 
2186 	err = eq_res_start_move_to(dev, slave, res_id, RES_EQ_RESERVED, &eq);
2187 	if (err)
2188 		return err;
2189 
2190 	err = get_res(dev, slave, eq->mtt->com.res_id, RES_MTT, NULL);
2191 	if (err)
2192 		goto ex_abort;
2193 
2194 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2195 	if (err)
2196 		goto ex_put;
2197 
2198 	atomic_dec(&eq->mtt->ref_count);
2199 	put_res(dev, slave, eq->mtt->com.res_id, RES_MTT);
2200 	res_end_move(dev, slave, RES_EQ, res_id);
2201 	rem_res_range(dev, slave, res_id, 1, RES_EQ, 0);
2202 
2203 	return 0;
2204 
2205 ex_put:
2206 	put_res(dev, slave, eq->mtt->com.res_id, RES_MTT);
2207 ex_abort:
2208 	res_abort_move(dev, slave, RES_EQ, res_id);
2209 
2210 	return err;
2211 }
2212 
2213 int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
2214 {
2215 	struct mlx4_priv *priv = mlx4_priv(dev);
2216 	struct mlx4_slave_event_eq_info *event_eq;
2217 	struct mlx4_cmd_mailbox *mailbox;
2218 	u32 in_modifier = 0;
2219 	int err;
2220 	int res_id;
2221 	struct res_eq *req;
2222 
2223 	if (!priv->mfunc.master.slave_state)
2224 		return -EINVAL;
2225 
2226 	event_eq = &priv->mfunc.master.slave_state[slave].event_eq[eqe->type];
2227 
2228 	/* Create the event only if the slave is registered */
2229 	if (event_eq->eqn < 0)
2230 		return 0;
2231 
2232 	mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]);
2233 	res_id = (slave << 8) | event_eq->eqn;
2234 	err = get_res(dev, slave, res_id, RES_EQ, &req);
2235 	if (err)
2236 		goto unlock;
2237 
2238 	if (req->com.from_state != RES_EQ_HW) {
2239 		err = -EINVAL;
2240 		goto put;
2241 	}
2242 
2243 	mailbox = mlx4_alloc_cmd_mailbox(dev);
2244 	if (IS_ERR(mailbox)) {
2245 		err = PTR_ERR(mailbox);
2246 		goto put;
2247 	}
2248 
2249 	if (eqe->type == MLX4_EVENT_TYPE_CMD) {
2250 		++event_eq->token;
2251 		eqe->event.cmd.token = cpu_to_be16(event_eq->token);
2252 	}
2253 
2254 	memcpy(mailbox->buf, (u8 *) eqe, 28);
2255 
2256 	in_modifier = (slave & 0xff) | ((event_eq->eqn & 0xff) << 16);
2257 
2258 	err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0,
2259 		       MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B,
2260 		       MLX4_CMD_NATIVE);
2261 
2262 	put_res(dev, slave, res_id, RES_EQ);
2263 	mutex_unlock(&priv->mfunc.master.gen_eqe_mutex[slave]);
2264 	mlx4_free_cmd_mailbox(dev, mailbox);
2265 	return err;
2266 
2267 put:
2268 	put_res(dev, slave, res_id, RES_EQ);
2269 
2270 unlock:
2271 	mutex_unlock(&priv->mfunc.master.gen_eqe_mutex[slave]);
2272 	return err;
2273 }
2274 
2275 int mlx4_QUERY_EQ_wrapper(struct mlx4_dev *dev, int slave,
2276 			  struct mlx4_vhcr *vhcr,
2277 			  struct mlx4_cmd_mailbox *inbox,
2278 			  struct mlx4_cmd_mailbox *outbox,
2279 			  struct mlx4_cmd_info *cmd)
2280 {
2281 	int eqn = vhcr->in_modifier;
2282 	int res_id = eqn | (slave << 8);
2283 	struct res_eq *eq;
2284 	int err;
2285 
2286 	err = get_res(dev, slave, res_id, RES_EQ, &eq);
2287 	if (err)
2288 		return err;
2289 
2290 	if (eq->com.from_state != RES_EQ_HW) {
2291 		err = -EINVAL;
2292 		goto ex_put;
2293 	}
2294 
2295 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2296 
2297 ex_put:
2298 	put_res(dev, slave, res_id, RES_EQ);
2299 	return err;
2300 }
2301 
2302 int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev *dev, int slave,
2303 			  struct mlx4_vhcr *vhcr,
2304 			  struct mlx4_cmd_mailbox *inbox,
2305 			  struct mlx4_cmd_mailbox *outbox,
2306 			  struct mlx4_cmd_info *cmd)
2307 {
2308 	int err;
2309 	int cqn = vhcr->in_modifier;
2310 	struct mlx4_cq_context *cqc = inbox->buf;
2311 	int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
2312 	struct res_cq *cq;
2313 	struct res_mtt *mtt;
2314 
2315 	err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_HW, &cq);
2316 	if (err)
2317 		return err;
2318 	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
2319 	if (err)
2320 		goto out_move;
2321 	err = check_mtt_range(dev, slave, mtt_base, cq_get_mtt_size(cqc), mtt);
2322 	if (err)
2323 		goto out_put;
2324 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2325 	if (err)
2326 		goto out_put;
2327 	atomic_inc(&mtt->ref_count);
2328 	cq->mtt = mtt;
2329 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2330 	res_end_move(dev, slave, RES_CQ, cqn);
2331 	return 0;
2332 
2333 out_put:
2334 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2335 out_move:
2336 	res_abort_move(dev, slave, RES_CQ, cqn);
2337 	return err;
2338 }
2339 
2340 int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev *dev, int slave,
2341 			  struct mlx4_vhcr *vhcr,
2342 			  struct mlx4_cmd_mailbox *inbox,
2343 			  struct mlx4_cmd_mailbox *outbox,
2344 			  struct mlx4_cmd_info *cmd)
2345 {
2346 	int err;
2347 	int cqn = vhcr->in_modifier;
2348 	struct res_cq *cq;
2349 
2350 	err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_ALLOCATED, &cq);
2351 	if (err)
2352 		return err;
2353 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2354 	if (err)
2355 		goto out_move;
2356 	atomic_dec(&cq->mtt->ref_count);
2357 	res_end_move(dev, slave, RES_CQ, cqn);
2358 	return 0;
2359 
2360 out_move:
2361 	res_abort_move(dev, slave, RES_CQ, cqn);
2362 	return err;
2363 }
2364 
2365 int mlx4_QUERY_CQ_wrapper(struct mlx4_dev *dev, int slave,
2366 			  struct mlx4_vhcr *vhcr,
2367 			  struct mlx4_cmd_mailbox *inbox,
2368 			  struct mlx4_cmd_mailbox *outbox,
2369 			  struct mlx4_cmd_info *cmd)
2370 {
2371 	int cqn = vhcr->in_modifier;
2372 	struct res_cq *cq;
2373 	int err;
2374 
2375 	err = get_res(dev, slave, cqn, RES_CQ, &cq);
2376 	if (err)
2377 		return err;
2378 
2379 	if (cq->com.from_state != RES_CQ_HW)
2380 		goto ex_put;
2381 
2382 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2383 ex_put:
2384 	put_res(dev, slave, cqn, RES_CQ);
2385 
2386 	return err;
2387 }
2388 
2389 static int handle_resize(struct mlx4_dev *dev, int slave,
2390 			 struct mlx4_vhcr *vhcr,
2391 			 struct mlx4_cmd_mailbox *inbox,
2392 			 struct mlx4_cmd_mailbox *outbox,
2393 			 struct mlx4_cmd_info *cmd,
2394 			 struct res_cq *cq)
2395 {
2396 	int err;
2397 	struct res_mtt *orig_mtt;
2398 	struct res_mtt *mtt;
2399 	struct mlx4_cq_context *cqc = inbox->buf;
2400 	int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
2401 
2402 	err = get_res(dev, slave, cq->mtt->com.res_id, RES_MTT, &orig_mtt);
2403 	if (err)
2404 		return err;
2405 
2406 	if (orig_mtt != cq->mtt) {
2407 		err = -EINVAL;
2408 		goto ex_put;
2409 	}
2410 
2411 	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
2412 	if (err)
2413 		goto ex_put;
2414 
2415 	err = check_mtt_range(dev, slave, mtt_base, cq_get_mtt_size(cqc), mtt);
2416 	if (err)
2417 		goto ex_put1;
2418 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2419 	if (err)
2420 		goto ex_put1;
2421 	atomic_dec(&orig_mtt->ref_count);
2422 	put_res(dev, slave, orig_mtt->com.res_id, RES_MTT);
2423 	atomic_inc(&mtt->ref_count);
2424 	cq->mtt = mtt;
2425 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2426 	return 0;
2427 
2428 ex_put1:
2429 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2430 ex_put:
2431 	put_res(dev, slave, orig_mtt->com.res_id, RES_MTT);
2432 
2433 	return err;
2434 
2435 }
2436 
2437 int mlx4_MODIFY_CQ_wrapper(struct mlx4_dev *dev, int slave,
2438 			   struct mlx4_vhcr *vhcr,
2439 			   struct mlx4_cmd_mailbox *inbox,
2440 			   struct mlx4_cmd_mailbox *outbox,
2441 			   struct mlx4_cmd_info *cmd)
2442 {
2443 	int cqn = vhcr->in_modifier;
2444 	struct res_cq *cq;
2445 	int err;
2446 
2447 	err = get_res(dev, slave, cqn, RES_CQ, &cq);
2448 	if (err)
2449 		return err;
2450 
2451 	if (cq->com.from_state != RES_CQ_HW)
2452 		goto ex_put;
2453 
2454 	if (vhcr->op_modifier == 0) {
2455 		err = handle_resize(dev, slave, vhcr, inbox, outbox, cmd, cq);
2456 		goto ex_put;
2457 	}
2458 
2459 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2460 ex_put:
2461 	put_res(dev, slave, cqn, RES_CQ);
2462 
2463 	return err;
2464 }
2465 
2466 static int srq_get_mtt_size(struct mlx4_srq_context *srqc)
2467 {
2468 	int log_srq_size = (be32_to_cpu(srqc->state_logsize_srqn) >> 24) & 0xf;
2469 	int log_rq_stride = srqc->logstride & 7;
2470 	int page_shift = (srqc->log_page_size & 0x3f) + 12;
2471 
2472 	if (log_srq_size + log_rq_stride + 4 < page_shift)
2473 		return 1;
2474 
2475 	return 1 << (log_srq_size + log_rq_stride + 4 - page_shift);
2476 }
2477 
2478 int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
2479 			   struct mlx4_vhcr *vhcr,
2480 			   struct mlx4_cmd_mailbox *inbox,
2481 			   struct mlx4_cmd_mailbox *outbox,
2482 			   struct mlx4_cmd_info *cmd)
2483 {
2484 	int err;
2485 	int srqn = vhcr->in_modifier;
2486 	struct res_mtt *mtt;
2487 	struct res_srq *srq;
2488 	struct mlx4_srq_context *srqc = inbox->buf;
2489 	int mtt_base = srq_get_mtt_addr(srqc) / dev->caps.mtt_entry_sz;
2490 
2491 	if (srqn != (be32_to_cpu(srqc->state_logsize_srqn) & 0xffffff))
2492 		return -EINVAL;
2493 
2494 	err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_HW, &srq);
2495 	if (err)
2496 		return err;
2497 	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
2498 	if (err)
2499 		goto ex_abort;
2500 	err = check_mtt_range(dev, slave, mtt_base, srq_get_mtt_size(srqc),
2501 			      mtt);
2502 	if (err)
2503 		goto ex_put_mtt;
2504 
2505 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2506 	if (err)
2507 		goto ex_put_mtt;
2508 
2509 	atomic_inc(&mtt->ref_count);
2510 	srq->mtt = mtt;
2511 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2512 	res_end_move(dev, slave, RES_SRQ, srqn);
2513 	return 0;
2514 
2515 ex_put_mtt:
2516 	put_res(dev, slave, mtt->com.res_id, RES_MTT);
2517 ex_abort:
2518 	res_abort_move(dev, slave, RES_SRQ, srqn);
2519 
2520 	return err;
2521 }
2522 
2523 int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
2524 			   struct mlx4_vhcr *vhcr,
2525 			   struct mlx4_cmd_mailbox *inbox,
2526 			   struct mlx4_cmd_mailbox *outbox,
2527 			   struct mlx4_cmd_info *cmd)
2528 {
2529 	int err;
2530 	int srqn = vhcr->in_modifier;
2531 	struct res_srq *srq;
2532 
2533 	err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_ALLOCATED, &srq);
2534 	if (err)
2535 		return err;
2536 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2537 	if (err)
2538 		goto ex_abort;
2539 	atomic_dec(&srq->mtt->ref_count);
2540 	if (srq->cq)
2541 		atomic_dec(&srq->cq->ref_count);
2542 	res_end_move(dev, slave, RES_SRQ, srqn);
2543 
2544 	return 0;
2545 
2546 ex_abort:
2547 	res_abort_move(dev, slave, RES_SRQ, srqn);
2548 
2549 	return err;
2550 }
2551 
2552 int mlx4_QUERY_SRQ_wrapper(struct mlx4_dev *dev, int slave,
2553 			   struct mlx4_vhcr *vhcr,
2554 			   struct mlx4_cmd_mailbox *inbox,
2555 			   struct mlx4_cmd_mailbox *outbox,
2556 			   struct mlx4_cmd_info *cmd)
2557 {
2558 	int err;
2559 	int srqn = vhcr->in_modifier;
2560 	struct res_srq *srq;
2561 
2562 	err = get_res(dev, slave, srqn, RES_SRQ, &srq);
2563 	if (err)
2564 		return err;
2565 	if (srq->com.from_state != RES_SRQ_HW) {
2566 		err = -EBUSY;
2567 		goto out;
2568 	}
2569 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2570 out:
2571 	put_res(dev, slave, srqn, RES_SRQ);
2572 	return err;
2573 }
2574 
2575 int mlx4_ARM_SRQ_wrapper(struct mlx4_dev *dev, int slave,
2576 			 struct mlx4_vhcr *vhcr,
2577 			 struct mlx4_cmd_mailbox *inbox,
2578 			 struct mlx4_cmd_mailbox *outbox,
2579 			 struct mlx4_cmd_info *cmd)
2580 {
2581 	int err;
2582 	int srqn = vhcr->in_modifier;
2583 	struct res_srq *srq;
2584 
2585 	err = get_res(dev, slave, srqn, RES_SRQ, &srq);
2586 	if (err)
2587 		return err;
2588 
2589 	if (srq->com.from_state != RES_SRQ_HW) {
2590 		err = -EBUSY;
2591 		goto out;
2592 	}
2593 
2594 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2595 out:
2596 	put_res(dev, slave, srqn, RES_SRQ);
2597 	return err;
2598 }
2599 
2600 int mlx4_GEN_QP_wrapper(struct mlx4_dev *dev, int slave,
2601 			struct mlx4_vhcr *vhcr,
2602 			struct mlx4_cmd_mailbox *inbox,
2603 			struct mlx4_cmd_mailbox *outbox,
2604 			struct mlx4_cmd_info *cmd)
2605 {
2606 	int err;
2607 	int qpn = vhcr->in_modifier & 0x7fffff;
2608 	struct res_qp *qp;
2609 
2610 	err = get_res(dev, slave, qpn, RES_QP, &qp);
2611 	if (err)
2612 		return err;
2613 	if (qp->com.from_state != RES_QP_HW) {
2614 		err = -EBUSY;
2615 		goto out;
2616 	}
2617 
2618 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2619 out:
2620 	put_res(dev, slave, qpn, RES_QP);
2621 	return err;
2622 }
2623 
2624 int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
2625 			     struct mlx4_vhcr *vhcr,
2626 			     struct mlx4_cmd_mailbox *inbox,
2627 			     struct mlx4_cmd_mailbox *outbox,
2628 			     struct mlx4_cmd_info *cmd)
2629 {
2630 	struct mlx4_qp_context *qpc = inbox->buf + 8;
2631 
2632 	update_ud_gid(dev, qpc, (u8)slave);
2633 
2634 	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2635 }
2636 
2637 int mlx4_2RST_QP_wrapper(struct mlx4_dev *dev, int slave,
2638 			 struct mlx4_vhcr *vhcr,
2639 			 struct mlx4_cmd_mailbox *inbox,
2640 			 struct mlx4_cmd_mailbox *outbox,
2641 			 struct mlx4_cmd_info *cmd)
2642 {
2643 	int err;
2644 	int qpn = vhcr->in_modifier & 0x7fffff;
2645 	struct res_qp *qp;
2646 
2647 	err = qp_res_start_move_to(dev, slave, qpn, RES_QP_MAPPED, &qp, 0);
2648 	if (err)
2649 		return err;
2650 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2651 	if (err)
2652 		goto ex_abort;
2653 
2654 	atomic_dec(&qp->mtt->ref_count);
2655 	atomic_dec(&qp->rcq->ref_count);
2656 	atomic_dec(&qp->scq->ref_count);
2657 	if (qp->srq)
2658 		atomic_dec(&qp->srq->ref_count);
2659 	res_end_move(dev, slave, RES_QP, qpn);
2660 	return 0;
2661 
2662 ex_abort:
2663 	res_abort_move(dev, slave, RES_QP, qpn);
2664 
2665 	return err;
2666 }
2667 
2668 static struct res_gid *find_gid(struct mlx4_dev *dev, int slave,
2669 				struct res_qp *rqp, u8 *gid)
2670 {
2671 	struct res_gid *res;
2672 
2673 	list_for_each_entry(res, &rqp->mcg_list, list) {
2674 		if (!memcmp(res->gid, gid, 16))
2675 			return res;
2676 	}
2677 	return NULL;
2678 }
2679 
2680 static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2681 		       u8 *gid, enum mlx4_protocol prot,
2682 		       enum mlx4_steer_type steer)
2683 {
2684 	struct res_gid *res;
2685 	int err;
2686 
2687 	res = kzalloc(sizeof *res, GFP_KERNEL);
2688 	if (!res)
2689 		return -ENOMEM;
2690 
2691 	spin_lock_irq(&rqp->mcg_spl);
2692 	if (find_gid(dev, slave, rqp, gid)) {
2693 		kfree(res);
2694 		err = -EEXIST;
2695 	} else {
2696 		memcpy(res->gid, gid, 16);
2697 		res->prot = prot;
2698 		res->steer = steer;
2699 		list_add_tail(&res->list, &rqp->mcg_list);
2700 		err = 0;
2701 	}
2702 	spin_unlock_irq(&rqp->mcg_spl);
2703 
2704 	return err;
2705 }
2706 
2707 static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2708 		       u8 *gid, enum mlx4_protocol prot,
2709 		       enum mlx4_steer_type steer)
2710 {
2711 	struct res_gid *res;
2712 	int err;
2713 
2714 	spin_lock_irq(&rqp->mcg_spl);
2715 	res = find_gid(dev, slave, rqp, gid);
2716 	if (!res || res->prot != prot || res->steer != steer)
2717 		err = -EINVAL;
2718 	else {
2719 		list_del(&res->list);
2720 		kfree(res);
2721 		err = 0;
2722 	}
2723 	spin_unlock_irq(&rqp->mcg_spl);
2724 
2725 	return err;
2726 }
2727 
2728 int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
2729 			       struct mlx4_vhcr *vhcr,
2730 			       struct mlx4_cmd_mailbox *inbox,
2731 			       struct mlx4_cmd_mailbox *outbox,
2732 			       struct mlx4_cmd_info *cmd)
2733 {
2734 	struct mlx4_qp qp; /* dummy for calling attach/detach */
2735 	u8 *gid = inbox->buf;
2736 	enum mlx4_protocol prot = (vhcr->in_modifier >> 28) & 0x7;
2737 	int err;
2738 	int qpn;
2739 	struct res_qp *rqp;
2740 	int attach = vhcr->op_modifier;
2741 	int block_loopback = vhcr->in_modifier >> 31;
2742 	u8 steer_type_mask = 2;
2743 	enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
2744 
2745 	qpn = vhcr->in_modifier & 0xffffff;
2746 	err = get_res(dev, slave, qpn, RES_QP, &rqp);
2747 	if (err)
2748 		return err;
2749 
2750 	qp.qpn = qpn;
2751 	if (attach) {
2752 		err = add_mcg_res(dev, slave, rqp, gid, prot, type);
2753 		if (err)
2754 			goto ex_put;
2755 
2756 		err = mlx4_qp_attach_common(dev, &qp, gid,
2757 					    block_loopback, prot, type);
2758 		if (err)
2759 			goto ex_rem;
2760 	} else {
2761 		err = rem_mcg_res(dev, slave, rqp, gid, prot, type);
2762 		if (err)
2763 			goto ex_put;
2764 		err = mlx4_qp_detach_common(dev, &qp, gid, prot, type);
2765 	}
2766 
2767 	put_res(dev, slave, qpn, RES_QP);
2768 	return 0;
2769 
2770 ex_rem:
2771 	/* ignore error return below, already in error */
2772 	(void) rem_mcg_res(dev, slave, rqp, gid, prot, type);
2773 ex_put:
2774 	put_res(dev, slave, qpn, RES_QP);
2775 
2776 	return err;
2777 }
2778 
2779 int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
2780 					 struct mlx4_vhcr *vhcr,
2781 					 struct mlx4_cmd_mailbox *inbox,
2782 					 struct mlx4_cmd_mailbox *outbox,
2783 					 struct mlx4_cmd_info *cmd)
2784 {
2785 	int err;
2786 
2787 	if (dev->caps.steering_mode !=
2788 	    MLX4_STEERING_MODE_DEVICE_MANAGED)
2789 		return -EOPNOTSUPP;
2790 
2791 	err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,
2792 			   vhcr->in_modifier, 0,
2793 			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
2794 			   MLX4_CMD_NATIVE);
2795 	if (err)
2796 		return err;
2797 
2798 	err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0);
2799 	if (err) {
2800 		mlx4_err(dev, "Fail to add flow steering resources.\n ");
2801 		/* detach rule*/
2802 		mlx4_cmd(dev, vhcr->out_param, 0, 0,
2803 			 MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
2804 			 MLX4_CMD_NATIVE);
2805 	}
2806 	return err;
2807 }
2808 
2809 int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
2810 					 struct mlx4_vhcr *vhcr,
2811 					 struct mlx4_cmd_mailbox *inbox,
2812 					 struct mlx4_cmd_mailbox *outbox,
2813 					 struct mlx4_cmd_info *cmd)
2814 {
2815 	int err;
2816 
2817 	if (dev->caps.steering_mode !=
2818 	    MLX4_STEERING_MODE_DEVICE_MANAGED)
2819 		return -EOPNOTSUPP;
2820 
2821 	err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0);
2822 	if (err) {
2823 		mlx4_err(dev, "Fail to remove flow steering resources.\n ");
2824 		return err;
2825 	}
2826 
2827 	err = mlx4_cmd(dev, vhcr->in_param, 0, 0,
2828 		       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
2829 		       MLX4_CMD_NATIVE);
2830 	return err;
2831 }
2832 
2833 enum {
2834 	BUSY_MAX_RETRIES = 10
2835 };
2836 
2837 int mlx4_QUERY_IF_STAT_wrapper(struct mlx4_dev *dev, int slave,
2838 			       struct mlx4_vhcr *vhcr,
2839 			       struct mlx4_cmd_mailbox *inbox,
2840 			       struct mlx4_cmd_mailbox *outbox,
2841 			       struct mlx4_cmd_info *cmd)
2842 {
2843 	int err;
2844 	int index = vhcr->in_modifier & 0xffff;
2845 
2846 	err = get_res(dev, slave, index, RES_COUNTER, NULL);
2847 	if (err)
2848 		return err;
2849 
2850 	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2851 	put_res(dev, slave, index, RES_COUNTER);
2852 	return err;
2853 }
2854 
2855 static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
2856 {
2857 	struct res_gid *rgid;
2858 	struct res_gid *tmp;
2859 	struct mlx4_qp qp; /* dummy for calling attach/detach */
2860 
2861 	list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) {
2862 		qp.qpn = rqp->local_qpn;
2863 		(void) mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot,
2864 					     rgid->steer);
2865 		list_del(&rgid->list);
2866 		kfree(rgid);
2867 	}
2868 }
2869 
2870 static int _move_all_busy(struct mlx4_dev *dev, int slave,
2871 			  enum mlx4_resource type, int print)
2872 {
2873 	struct mlx4_priv *priv = mlx4_priv(dev);
2874 	struct mlx4_resource_tracker *tracker =
2875 		&priv->mfunc.master.res_tracker;
2876 	struct list_head *rlist = &tracker->slave_list[slave].res_list[type];
2877 	struct res_common *r;
2878 	struct res_common *tmp;
2879 	int busy;
2880 
2881 	busy = 0;
2882 	spin_lock_irq(mlx4_tlock(dev));
2883 	list_for_each_entry_safe(r, tmp, rlist, list) {
2884 		if (r->owner == slave) {
2885 			if (!r->removing) {
2886 				if (r->state == RES_ANY_BUSY) {
2887 					if (print)
2888 						mlx4_dbg(dev,
2889 							 "%s id 0x%llx is busy\n",
2890 							  ResourceType(type),
2891 							  r->res_id);
2892 					++busy;
2893 				} else {
2894 					r->from_state = r->state;
2895 					r->state = RES_ANY_BUSY;
2896 					r->removing = 1;
2897 				}
2898 			}
2899 		}
2900 	}
2901 	spin_unlock_irq(mlx4_tlock(dev));
2902 
2903 	return busy;
2904 }
2905 
2906 static int move_all_busy(struct mlx4_dev *dev, int slave,
2907 			 enum mlx4_resource type)
2908 {
2909 	unsigned long begin;
2910 	int busy;
2911 
2912 	begin = jiffies;
2913 	do {
2914 		busy = _move_all_busy(dev, slave, type, 0);
2915 		if (time_after(jiffies, begin + 5 * HZ))
2916 			break;
2917 		if (busy)
2918 			cond_resched();
2919 	} while (busy);
2920 
2921 	if (busy)
2922 		busy = _move_all_busy(dev, slave, type, 1);
2923 
2924 	return busy;
2925 }
2926 static void rem_slave_qps(struct mlx4_dev *dev, int slave)
2927 {
2928 	struct mlx4_priv *priv = mlx4_priv(dev);
2929 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2930 	struct list_head *qp_list =
2931 		&tracker->slave_list[slave].res_list[RES_QP];
2932 	struct res_qp *qp;
2933 	struct res_qp *tmp;
2934 	int state;
2935 	u64 in_param;
2936 	int qpn;
2937 	int err;
2938 
2939 	err = move_all_busy(dev, slave, RES_QP);
2940 	if (err)
2941 		mlx4_warn(dev, "rem_slave_qps: Could not move all qps to busy"
2942 			  "for slave %d\n", slave);
2943 
2944 	spin_lock_irq(mlx4_tlock(dev));
2945 	list_for_each_entry_safe(qp, tmp, qp_list, com.list) {
2946 		spin_unlock_irq(mlx4_tlock(dev));
2947 		if (qp->com.owner == slave) {
2948 			qpn = qp->com.res_id;
2949 			detach_qp(dev, slave, qp);
2950 			state = qp->com.from_state;
2951 			while (state != 0) {
2952 				switch (state) {
2953 				case RES_QP_RESERVED:
2954 					spin_lock_irq(mlx4_tlock(dev));
2955 					rb_erase(&qp->com.node,
2956 						 &tracker->res_tree[RES_QP]);
2957 					list_del(&qp->com.list);
2958 					spin_unlock_irq(mlx4_tlock(dev));
2959 					kfree(qp);
2960 					state = 0;
2961 					break;
2962 				case RES_QP_MAPPED:
2963 					if (!valid_reserved(dev, slave, qpn))
2964 						__mlx4_qp_free_icm(dev, qpn);
2965 					state = RES_QP_RESERVED;
2966 					break;
2967 				case RES_QP_HW:
2968 					in_param = slave;
2969 					err = mlx4_cmd(dev, in_param,
2970 						       qp->local_qpn, 2,
2971 						       MLX4_CMD_2RST_QP,
2972 						       MLX4_CMD_TIME_CLASS_A,
2973 						       MLX4_CMD_NATIVE);
2974 					if (err)
2975 						mlx4_dbg(dev, "rem_slave_qps: failed"
2976 							 " to move slave %d qpn %d to"
2977 							 " reset\n", slave,
2978 							 qp->local_qpn);
2979 					atomic_dec(&qp->rcq->ref_count);
2980 					atomic_dec(&qp->scq->ref_count);
2981 					atomic_dec(&qp->mtt->ref_count);
2982 					if (qp->srq)
2983 						atomic_dec(&qp->srq->ref_count);
2984 					state = RES_QP_MAPPED;
2985 					break;
2986 				default:
2987 					state = 0;
2988 				}
2989 			}
2990 		}
2991 		spin_lock_irq(mlx4_tlock(dev));
2992 	}
2993 	spin_unlock_irq(mlx4_tlock(dev));
2994 }
2995 
2996 static void rem_slave_srqs(struct mlx4_dev *dev, int slave)
2997 {
2998 	struct mlx4_priv *priv = mlx4_priv(dev);
2999 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
3000 	struct list_head *srq_list =
3001 		&tracker->slave_list[slave].res_list[RES_SRQ];
3002 	struct res_srq *srq;
3003 	struct res_srq *tmp;
3004 	int state;
3005 	u64 in_param;
3006 	LIST_HEAD(tlist);
3007 	int srqn;
3008 	int err;
3009 
3010 	err = move_all_busy(dev, slave, RES_SRQ);
3011 	if (err)
3012 		mlx4_warn(dev, "rem_slave_srqs: Could not move all srqs to "
3013 			  "busy for slave %d\n", slave);
3014 
3015 	spin_lock_irq(mlx4_tlock(dev));
3016 	list_for_each_entry_safe(srq, tmp, srq_list, com.list) {
3017 		spin_unlock_irq(mlx4_tlock(dev));
3018 		if (srq->com.owner == slave) {
3019 			srqn = srq->com.res_id;
3020 			state = srq->com.from_state;
3021 			while (state != 0) {
3022 				switch (state) {
3023 				case RES_SRQ_ALLOCATED:
3024 					__mlx4_srq_free_icm(dev, srqn);
3025 					spin_lock_irq(mlx4_tlock(dev));
3026 					rb_erase(&srq->com.node,
3027 						 &tracker->res_tree[RES_SRQ]);
3028 					list_del(&srq->com.list);
3029 					spin_unlock_irq(mlx4_tlock(dev));
3030 					kfree(srq);
3031 					state = 0;
3032 					break;
3033 
3034 				case RES_SRQ_HW:
3035 					in_param = slave;
3036 					err = mlx4_cmd(dev, in_param, srqn, 1,
3037 						       MLX4_CMD_HW2SW_SRQ,
3038 						       MLX4_CMD_TIME_CLASS_A,
3039 						       MLX4_CMD_NATIVE);
3040 					if (err)
3041 						mlx4_dbg(dev, "rem_slave_srqs: failed"
3042 							 " to move slave %d srq %d to"
3043 							 " SW ownership\n",
3044 							 slave, srqn);
3045 
3046 					atomic_dec(&srq->mtt->ref_count);
3047 					if (srq->cq)
3048 						atomic_dec(&srq->cq->ref_count);
3049 					state = RES_SRQ_ALLOCATED;
3050 					break;
3051 
3052 				default:
3053 					state = 0;
3054 				}
3055 			}
3056 		}
3057 		spin_lock_irq(mlx4_tlock(dev));
3058 	}
3059 	spin_unlock_irq(mlx4_tlock(dev));
3060 }
3061 
3062 static void rem_slave_cqs(struct mlx4_dev *dev, int slave)
3063 {
3064 	struct mlx4_priv *priv = mlx4_priv(dev);
3065 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
3066 	struct list_head *cq_list =
3067 		&tracker->slave_list[slave].res_list[RES_CQ];
3068 	struct res_cq *cq;
3069 	struct res_cq *tmp;
3070 	int state;
3071 	u64 in_param;
3072 	LIST_HEAD(tlist);
3073 	int cqn;
3074 	int err;
3075 
3076 	err = move_all_busy(dev, slave, RES_CQ);
3077 	if (err)
3078 		mlx4_warn(dev, "rem_slave_cqs: Could not move all cqs to "
3079 			  "busy for slave %d\n", slave);
3080 
3081 	spin_lock_irq(mlx4_tlock(dev));
3082 	list_for_each_entry_safe(cq, tmp, cq_list, com.list) {
3083 		spin_unlock_irq(mlx4_tlock(dev));
3084 		if (cq->com.owner == slave && !atomic_read(&cq->ref_count)) {
3085 			cqn = cq->com.res_id;
3086 			state = cq->com.from_state;
3087 			while (state != 0) {
3088 				switch (state) {
3089 				case RES_CQ_ALLOCATED:
3090 					__mlx4_cq_free_icm(dev, cqn);
3091 					spin_lock_irq(mlx4_tlock(dev));
3092 					rb_erase(&cq->com.node,
3093 						 &tracker->res_tree[RES_CQ]);
3094 					list_del(&cq->com.list);
3095 					spin_unlock_irq(mlx4_tlock(dev));
3096 					kfree(cq);
3097 					state = 0;
3098 					break;
3099 
3100 				case RES_CQ_HW:
3101 					in_param = slave;
3102 					err = mlx4_cmd(dev, in_param, cqn, 1,
3103 						       MLX4_CMD_HW2SW_CQ,
3104 						       MLX4_CMD_TIME_CLASS_A,
3105 						       MLX4_CMD_NATIVE);
3106 					if (err)
3107 						mlx4_dbg(dev, "rem_slave_cqs: failed"
3108 							 " to move slave %d cq %d to"
3109 							 " SW ownership\n",
3110 							 slave, cqn);
3111 					atomic_dec(&cq->mtt->ref_count);
3112 					state = RES_CQ_ALLOCATED;
3113 					break;
3114 
3115 				default:
3116 					state = 0;
3117 				}
3118 			}
3119 		}
3120 		spin_lock_irq(mlx4_tlock(dev));
3121 	}
3122 	spin_unlock_irq(mlx4_tlock(dev));
3123 }
3124 
3125 static void rem_slave_mrs(struct mlx4_dev *dev, int slave)
3126 {
3127 	struct mlx4_priv *priv = mlx4_priv(dev);
3128 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
3129 	struct list_head *mpt_list =
3130 		&tracker->slave_list[slave].res_list[RES_MPT];
3131 	struct res_mpt *mpt;
3132 	struct res_mpt *tmp;
3133 	int state;
3134 	u64 in_param;
3135 	LIST_HEAD(tlist);
3136 	int mptn;
3137 	int err;
3138 
3139 	err = move_all_busy(dev, slave, RES_MPT);
3140 	if (err)
3141 		mlx4_warn(dev, "rem_slave_mrs: Could not move all mpts to "
3142 			  "busy for slave %d\n", slave);
3143 
3144 	spin_lock_irq(mlx4_tlock(dev));
3145 	list_for_each_entry_safe(mpt, tmp, mpt_list, com.list) {
3146 		spin_unlock_irq(mlx4_tlock(dev));
3147 		if (mpt->com.owner == slave) {
3148 			mptn = mpt->com.res_id;
3149 			state = mpt->com.from_state;
3150 			while (state != 0) {
3151 				switch (state) {
3152 				case RES_MPT_RESERVED:
3153 					__mlx4_mr_release(dev, mpt->key);
3154 					spin_lock_irq(mlx4_tlock(dev));
3155 					rb_erase(&mpt->com.node,
3156 						 &tracker->res_tree[RES_MPT]);
3157 					list_del(&mpt->com.list);
3158 					spin_unlock_irq(mlx4_tlock(dev));
3159 					kfree(mpt);
3160 					state = 0;
3161 					break;
3162 
3163 				case RES_MPT_MAPPED:
3164 					__mlx4_mr_free_icm(dev, mpt->key);
3165 					state = RES_MPT_RESERVED;
3166 					break;
3167 
3168 				case RES_MPT_HW:
3169 					in_param = slave;
3170 					err = mlx4_cmd(dev, in_param, mptn, 0,
3171 						     MLX4_CMD_HW2SW_MPT,
3172 						     MLX4_CMD_TIME_CLASS_A,
3173 						     MLX4_CMD_NATIVE);
3174 					if (err)
3175 						mlx4_dbg(dev, "rem_slave_mrs: failed"
3176 							 " to move slave %d mpt %d to"
3177 							 " SW ownership\n",
3178 							 slave, mptn);
3179 					if (mpt->mtt)
3180 						atomic_dec(&mpt->mtt->ref_count);
3181 					state = RES_MPT_MAPPED;
3182 					break;
3183 				default:
3184 					state = 0;
3185 				}
3186 			}
3187 		}
3188 		spin_lock_irq(mlx4_tlock(dev));
3189 	}
3190 	spin_unlock_irq(mlx4_tlock(dev));
3191 }
3192 
3193 static void rem_slave_mtts(struct mlx4_dev *dev, int slave)
3194 {
3195 	struct mlx4_priv *priv = mlx4_priv(dev);
3196 	struct mlx4_resource_tracker *tracker =
3197 		&priv->mfunc.master.res_tracker;
3198 	struct list_head *mtt_list =
3199 		&tracker->slave_list[slave].res_list[RES_MTT];
3200 	struct res_mtt *mtt;
3201 	struct res_mtt *tmp;
3202 	int state;
3203 	LIST_HEAD(tlist);
3204 	int base;
3205 	int err;
3206 
3207 	err = move_all_busy(dev, slave, RES_MTT);
3208 	if (err)
3209 		mlx4_warn(dev, "rem_slave_mtts: Could not move all mtts to "
3210 			  "busy for slave %d\n", slave);
3211 
3212 	spin_lock_irq(mlx4_tlock(dev));
3213 	list_for_each_entry_safe(mtt, tmp, mtt_list, com.list) {
3214 		spin_unlock_irq(mlx4_tlock(dev));
3215 		if (mtt->com.owner == slave) {
3216 			base = mtt->com.res_id;
3217 			state = mtt->com.from_state;
3218 			while (state != 0) {
3219 				switch (state) {
3220 				case RES_MTT_ALLOCATED:
3221 					__mlx4_free_mtt_range(dev, base,
3222 							      mtt->order);
3223 					spin_lock_irq(mlx4_tlock(dev));
3224 					rb_erase(&mtt->com.node,
3225 						 &tracker->res_tree[RES_MTT]);
3226 					list_del(&mtt->com.list);
3227 					spin_unlock_irq(mlx4_tlock(dev));
3228 					kfree(mtt);
3229 					state = 0;
3230 					break;
3231 
3232 				default:
3233 					state = 0;
3234 				}
3235 			}
3236 		}
3237 		spin_lock_irq(mlx4_tlock(dev));
3238 	}
3239 	spin_unlock_irq(mlx4_tlock(dev));
3240 }
3241 
3242 static void rem_slave_fs_rule(struct mlx4_dev *dev, int slave)
3243 {
3244 	struct mlx4_priv *priv = mlx4_priv(dev);
3245 	struct mlx4_resource_tracker *tracker =
3246 		&priv->mfunc.master.res_tracker;
3247 	struct list_head *fs_rule_list =
3248 		&tracker->slave_list[slave].res_list[RES_FS_RULE];
3249 	struct res_fs_rule *fs_rule;
3250 	struct res_fs_rule *tmp;
3251 	int state;
3252 	u64 base;
3253 	int err;
3254 
3255 	err = move_all_busy(dev, slave, RES_FS_RULE);
3256 	if (err)
3257 		mlx4_warn(dev, "rem_slave_fs_rule: Could not move all mtts to busy for slave %d\n",
3258 			  slave);
3259 
3260 	spin_lock_irq(mlx4_tlock(dev));
3261 	list_for_each_entry_safe(fs_rule, tmp, fs_rule_list, com.list) {
3262 		spin_unlock_irq(mlx4_tlock(dev));
3263 		if (fs_rule->com.owner == slave) {
3264 			base = fs_rule->com.res_id;
3265 			state = fs_rule->com.from_state;
3266 			while (state != 0) {
3267 				switch (state) {
3268 				case RES_FS_RULE_ALLOCATED:
3269 					/* detach rule */
3270 					err = mlx4_cmd(dev, base, 0, 0,
3271 						       MLX4_QP_FLOW_STEERING_DETACH,
3272 						       MLX4_CMD_TIME_CLASS_A,
3273 						       MLX4_CMD_NATIVE);
3274 
3275 					spin_lock_irq(mlx4_tlock(dev));
3276 					rb_erase(&fs_rule->com.node,
3277 						 &tracker->res_tree[RES_FS_RULE]);
3278 					list_del(&fs_rule->com.list);
3279 					spin_unlock_irq(mlx4_tlock(dev));
3280 					kfree(fs_rule);
3281 					state = 0;
3282 					break;
3283 
3284 				default:
3285 					state = 0;
3286 				}
3287 			}
3288 		}
3289 		spin_lock_irq(mlx4_tlock(dev));
3290 	}
3291 	spin_unlock_irq(mlx4_tlock(dev));
3292 }
3293 
3294 static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
3295 {
3296 	struct mlx4_priv *priv = mlx4_priv(dev);
3297 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
3298 	struct list_head *eq_list =
3299 		&tracker->slave_list[slave].res_list[RES_EQ];
3300 	struct res_eq *eq;
3301 	struct res_eq *tmp;
3302 	int err;
3303 	int state;
3304 	LIST_HEAD(tlist);
3305 	int eqn;
3306 	struct mlx4_cmd_mailbox *mailbox;
3307 
3308 	err = move_all_busy(dev, slave, RES_EQ);
3309 	if (err)
3310 		mlx4_warn(dev, "rem_slave_eqs: Could not move all eqs to "
3311 			  "busy for slave %d\n", slave);
3312 
3313 	spin_lock_irq(mlx4_tlock(dev));
3314 	list_for_each_entry_safe(eq, tmp, eq_list, com.list) {
3315 		spin_unlock_irq(mlx4_tlock(dev));
3316 		if (eq->com.owner == slave) {
3317 			eqn = eq->com.res_id;
3318 			state = eq->com.from_state;
3319 			while (state != 0) {
3320 				switch (state) {
3321 				case RES_EQ_RESERVED:
3322 					spin_lock_irq(mlx4_tlock(dev));
3323 					rb_erase(&eq->com.node,
3324 						 &tracker->res_tree[RES_EQ]);
3325 					list_del(&eq->com.list);
3326 					spin_unlock_irq(mlx4_tlock(dev));
3327 					kfree(eq);
3328 					state = 0;
3329 					break;
3330 
3331 				case RES_EQ_HW:
3332 					mailbox = mlx4_alloc_cmd_mailbox(dev);
3333 					if (IS_ERR(mailbox)) {
3334 						cond_resched();
3335 						continue;
3336 					}
3337 					err = mlx4_cmd_box(dev, slave, 0,
3338 							   eqn & 0xff, 0,
3339 							   MLX4_CMD_HW2SW_EQ,
3340 							   MLX4_CMD_TIME_CLASS_A,
3341 							   MLX4_CMD_NATIVE);
3342 					if (err)
3343 						mlx4_dbg(dev, "rem_slave_eqs: failed"
3344 							 " to move slave %d eqs %d to"
3345 							 " SW ownership\n", slave, eqn);
3346 					mlx4_free_cmd_mailbox(dev, mailbox);
3347 					atomic_dec(&eq->mtt->ref_count);
3348 					state = RES_EQ_RESERVED;
3349 					break;
3350 
3351 				default:
3352 					state = 0;
3353 				}
3354 			}
3355 		}
3356 		spin_lock_irq(mlx4_tlock(dev));
3357 	}
3358 	spin_unlock_irq(mlx4_tlock(dev));
3359 }
3360 
3361 static void rem_slave_counters(struct mlx4_dev *dev, int slave)
3362 {
3363 	struct mlx4_priv *priv = mlx4_priv(dev);
3364 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
3365 	struct list_head *counter_list =
3366 		&tracker->slave_list[slave].res_list[RES_COUNTER];
3367 	struct res_counter *counter;
3368 	struct res_counter *tmp;
3369 	int err;
3370 	int index;
3371 
3372 	err = move_all_busy(dev, slave, RES_COUNTER);
3373 	if (err)
3374 		mlx4_warn(dev, "rem_slave_counters: Could not move all counters to "
3375 			  "busy for slave %d\n", slave);
3376 
3377 	spin_lock_irq(mlx4_tlock(dev));
3378 	list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
3379 		if (counter->com.owner == slave) {
3380 			index = counter->com.res_id;
3381 			rb_erase(&counter->com.node,
3382 				 &tracker->res_tree[RES_COUNTER]);
3383 			list_del(&counter->com.list);
3384 			kfree(counter);
3385 			__mlx4_counter_free(dev, index);
3386 		}
3387 	}
3388 	spin_unlock_irq(mlx4_tlock(dev));
3389 }
3390 
3391 static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave)
3392 {
3393 	struct mlx4_priv *priv = mlx4_priv(dev);
3394 	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
3395 	struct list_head *xrcdn_list =
3396 		&tracker->slave_list[slave].res_list[RES_XRCD];
3397 	struct res_xrcdn *xrcd;
3398 	struct res_xrcdn *tmp;
3399 	int err;
3400 	int xrcdn;
3401 
3402 	err = move_all_busy(dev, slave, RES_XRCD);
3403 	if (err)
3404 		mlx4_warn(dev, "rem_slave_xrcdns: Could not move all xrcdns to "
3405 			  "busy for slave %d\n", slave);
3406 
3407 	spin_lock_irq(mlx4_tlock(dev));
3408 	list_for_each_entry_safe(xrcd, tmp, xrcdn_list, com.list) {
3409 		if (xrcd->com.owner == slave) {
3410 			xrcdn = xrcd->com.res_id;
3411 			rb_erase(&xrcd->com.node, &tracker->res_tree[RES_XRCD]);
3412 			list_del(&xrcd->com.list);
3413 			kfree(xrcd);
3414 			__mlx4_xrcd_free(dev, xrcdn);
3415 		}
3416 	}
3417 	spin_unlock_irq(mlx4_tlock(dev));
3418 }
3419 
3420 void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
3421 {
3422 	struct mlx4_priv *priv = mlx4_priv(dev);
3423 
3424 	mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
3425 	/*VLAN*/
3426 	rem_slave_macs(dev, slave);
3427 	rem_slave_qps(dev, slave);
3428 	rem_slave_srqs(dev, slave);
3429 	rem_slave_cqs(dev, slave);
3430 	rem_slave_mrs(dev, slave);
3431 	rem_slave_eqs(dev, slave);
3432 	rem_slave_mtts(dev, slave);
3433 	rem_slave_counters(dev, slave);
3434 	rem_slave_xrcdns(dev, slave);
3435 	rem_slave_fs_rule(dev, slave);
3436 	mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
3437 }
3438