]> rtime.felk.cvut.cz Git - linux-imx.git/blob - drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
HID: wiimote: fix weight conversion error for values > 17kg
[linux-imx.git] / drivers / net / ethernet / mellanox / mlx4 / resource_tracker.c
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 }