2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies.
5 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
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:
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
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.
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
36 #include <linux/sched.h>
37 #include <linux/pci.h>
38 #include <linux/errno.h>
39 #include <linux/kernel.h>
41 #include <linux/slab.h>
42 #include <linux/mlx4/cmd.h>
43 #include <linux/mlx4/qp.h>
44 #include <linux/if_ether.h>
45 #include <linux/etherdevice.h>
50 #define MLX4_MAC_VALID (1ull << 63)
53 struct list_head list
;
61 struct list_head list
;
69 struct list_head list
;
84 struct list_head list
;
86 enum mlx4_protocol prot
;
87 enum mlx4_steer_type steer
;
92 RES_QP_BUSY
= RES_ANY_BUSY
,
94 /* QP number was allocated */
97 /* ICM memory for QP context was mapped */
100 /* QP is in hw ownership */
105 struct res_common com
;
110 struct list_head mcg_list
;
115 /* saved qp params before VST enforcement in order to restore on VGT */
125 enum res_mtt_states
{
126 RES_MTT_BUSY
= RES_ANY_BUSY
,
130 static inline const char *mtt_states_str(enum res_mtt_states state
)
133 case RES_MTT_BUSY
: return "RES_MTT_BUSY";
134 case RES_MTT_ALLOCATED
: return "RES_MTT_ALLOCATED";
135 default: return "Unknown";
140 struct res_common com
;
145 enum res_mpt_states
{
146 RES_MPT_BUSY
= RES_ANY_BUSY
,
153 struct res_common com
;
159 RES_EQ_BUSY
= RES_ANY_BUSY
,
165 struct res_common com
;
170 RES_CQ_BUSY
= RES_ANY_BUSY
,
176 struct res_common com
;
181 enum res_srq_states
{
182 RES_SRQ_BUSY
= RES_ANY_BUSY
,
188 struct res_common com
;
194 enum res_counter_states
{
195 RES_COUNTER_BUSY
= RES_ANY_BUSY
,
196 RES_COUNTER_ALLOCATED
,
200 struct res_common com
;
204 enum res_xrcdn_states
{
205 RES_XRCD_BUSY
= RES_ANY_BUSY
,
210 struct res_common com
;
214 enum res_fs_rule_states
{
215 RES_FS_RULE_BUSY
= RES_ANY_BUSY
,
216 RES_FS_RULE_ALLOCATED
,
220 struct res_common com
;
224 static int mlx4_is_eth(struct mlx4_dev
*dev
, int port
)
226 return dev
->caps
.port_mask
[port
] == MLX4_PORT_TYPE_IB
? 0 : 1;
229 static void *res_tracker_lookup(struct rb_root
*root
, u64 res_id
)
231 struct rb_node
*node
= root
->rb_node
;
234 struct res_common
*res
= container_of(node
, struct res_common
,
237 if (res_id
< res
->res_id
)
238 node
= node
->rb_left
;
239 else if (res_id
> res
->res_id
)
240 node
= node
->rb_right
;
247 static int res_tracker_insert(struct rb_root
*root
, struct res_common
*res
)
249 struct rb_node
**new = &(root
->rb_node
), *parent
= NULL
;
251 /* Figure out where to put new node */
253 struct res_common
*this = container_of(*new, struct res_common
,
257 if (res
->res_id
< this->res_id
)
258 new = &((*new)->rb_left
);
259 else if (res
->res_id
> this->res_id
)
260 new = &((*new)->rb_right
);
265 /* Add new node and rebalance tree. */
266 rb_link_node(&res
->node
, parent
, new);
267 rb_insert_color(&res
->node
, root
);
282 static const char *resource_str(enum mlx4_resource rt
)
285 case RES_QP
: return "RES_QP";
286 case RES_CQ
: return "RES_CQ";
287 case RES_SRQ
: return "RES_SRQ";
288 case RES_MPT
: return "RES_MPT";
289 case RES_MTT
: return "RES_MTT";
290 case RES_MAC
: return "RES_MAC";
291 case RES_VLAN
: return "RES_VLAN";
292 case RES_EQ
: return "RES_EQ";
293 case RES_COUNTER
: return "RES_COUNTER";
294 case RES_FS_RULE
: return "RES_FS_RULE";
295 case RES_XRCD
: return "RES_XRCD";
296 default: return "Unknown resource type !!!";
300 static void rem_slave_vlans(struct mlx4_dev
*dev
, int slave
);
301 static inline int mlx4_grant_resource(struct mlx4_dev
*dev
, int slave
,
302 enum mlx4_resource res_type
, int count
,
305 struct mlx4_priv
*priv
= mlx4_priv(dev
);
306 struct resource_allocator
*res_alloc
=
307 &priv
->mfunc
.master
.res_tracker
.res_alloc
[res_type
];
309 int allocated
, free
, reserved
, guaranteed
, from_free
;
312 if (slave
> dev
->num_vfs
)
315 spin_lock(&res_alloc
->alloc_lock
);
316 allocated
= (port
> 0) ?
317 res_alloc
->allocated
[(port
- 1) * (dev
->num_vfs
+ 1) + slave
] :
318 res_alloc
->allocated
[slave
];
319 free
= (port
> 0) ? res_alloc
->res_port_free
[port
- 1] :
321 reserved
= (port
> 0) ? res_alloc
->res_port_rsvd
[port
- 1] :
322 res_alloc
->res_reserved
;
323 guaranteed
= res_alloc
->guaranteed
[slave
];
325 if (allocated
+ count
> res_alloc
->quota
[slave
]) {
326 mlx4_warn(dev
, "VF %d port %d res %s: quota exceeded, count %d alloc %d quota %d\n",
327 slave
, port
, resource_str(res_type
), count
,
328 allocated
, res_alloc
->quota
[slave
]);
332 if (allocated
+ count
<= guaranteed
) {
336 /* portion may need to be obtained from free area */
337 if (guaranteed
- allocated
> 0)
338 from_free
= count
- (guaranteed
- allocated
);
342 from_rsvd
= count
- from_free
;
344 if (free
- from_free
>= reserved
)
347 mlx4_warn(dev
, "VF %d port %d res %s: free pool empty, free %d from_free %d rsvd %d\n",
348 slave
, port
, resource_str(res_type
), free
,
349 from_free
, reserved
);
353 /* grant the request */
355 res_alloc
->allocated
[(port
- 1) * (dev
->num_vfs
+ 1) + slave
] += count
;
356 res_alloc
->res_port_free
[port
- 1] -= count
;
357 res_alloc
->res_port_rsvd
[port
- 1] -= from_rsvd
;
359 res_alloc
->allocated
[slave
] += count
;
360 res_alloc
->res_free
-= count
;
361 res_alloc
->res_reserved
-= from_rsvd
;
366 spin_unlock(&res_alloc
->alloc_lock
);
370 static inline void mlx4_release_resource(struct mlx4_dev
*dev
, int slave
,
371 enum mlx4_resource res_type
, int count
,
374 struct mlx4_priv
*priv
= mlx4_priv(dev
);
375 struct resource_allocator
*res_alloc
=
376 &priv
->mfunc
.master
.res_tracker
.res_alloc
[res_type
];
377 int allocated
, guaranteed
, from_rsvd
;
379 if (slave
> dev
->num_vfs
)
382 spin_lock(&res_alloc
->alloc_lock
);
384 allocated
= (port
> 0) ?
385 res_alloc
->allocated
[(port
- 1) * (dev
->num_vfs
+ 1) + slave
] :
386 res_alloc
->allocated
[slave
];
387 guaranteed
= res_alloc
->guaranteed
[slave
];
389 if (allocated
- count
>= guaranteed
) {
392 /* portion may need to be returned to reserved area */
393 if (allocated
- guaranteed
> 0)
394 from_rsvd
= count
- (allocated
- guaranteed
);
400 res_alloc
->allocated
[(port
- 1) * (dev
->num_vfs
+ 1) + slave
] -= count
;
401 res_alloc
->res_port_free
[port
- 1] += count
;
402 res_alloc
->res_port_rsvd
[port
- 1] += from_rsvd
;
404 res_alloc
->allocated
[slave
] -= count
;
405 res_alloc
->res_free
+= count
;
406 res_alloc
->res_reserved
+= from_rsvd
;
409 spin_unlock(&res_alloc
->alloc_lock
);
413 static inline void initialize_res_quotas(struct mlx4_dev
*dev
,
414 struct resource_allocator
*res_alloc
,
415 enum mlx4_resource res_type
,
416 int vf
, int num_instances
)
418 res_alloc
->guaranteed
[vf
] = num_instances
/ (2 * (dev
->num_vfs
+ 1));
419 res_alloc
->quota
[vf
] = (num_instances
/ 2) + res_alloc
->guaranteed
[vf
];
420 if (vf
== mlx4_master_func_num(dev
)) {
421 res_alloc
->res_free
= num_instances
;
422 if (res_type
== RES_MTT
) {
423 /* reserved mtts will be taken out of the PF allocation */
424 res_alloc
->res_free
+= dev
->caps
.reserved_mtts
;
425 res_alloc
->guaranteed
[vf
] += dev
->caps
.reserved_mtts
;
426 res_alloc
->quota
[vf
] += dev
->caps
.reserved_mtts
;
431 void mlx4_init_quotas(struct mlx4_dev
*dev
)
433 struct mlx4_priv
*priv
= mlx4_priv(dev
);
436 /* quotas for VFs are initialized in mlx4_slave_cap */
437 if (mlx4_is_slave(dev
))
440 if (!mlx4_is_mfunc(dev
)) {
441 dev
->quotas
.qp
= dev
->caps
.num_qps
- dev
->caps
.reserved_qps
-
442 mlx4_num_reserved_sqps(dev
);
443 dev
->quotas
.cq
= dev
->caps
.num_cqs
- dev
->caps
.reserved_cqs
;
444 dev
->quotas
.srq
= dev
->caps
.num_srqs
- dev
->caps
.reserved_srqs
;
445 dev
->quotas
.mtt
= dev
->caps
.num_mtts
- dev
->caps
.reserved_mtts
;
446 dev
->quotas
.mpt
= dev
->caps
.num_mpts
- dev
->caps
.reserved_mrws
;
450 pf
= mlx4_master_func_num(dev
);
452 priv
->mfunc
.master
.res_tracker
.res_alloc
[RES_QP
].quota
[pf
];
454 priv
->mfunc
.master
.res_tracker
.res_alloc
[RES_CQ
].quota
[pf
];
456 priv
->mfunc
.master
.res_tracker
.res_alloc
[RES_SRQ
].quota
[pf
];
458 priv
->mfunc
.master
.res_tracker
.res_alloc
[RES_MTT
].quota
[pf
];
460 priv
->mfunc
.master
.res_tracker
.res_alloc
[RES_MPT
].quota
[pf
];
462 int mlx4_init_resource_tracker(struct mlx4_dev
*dev
)
464 struct mlx4_priv
*priv
= mlx4_priv(dev
);
468 priv
->mfunc
.master
.res_tracker
.slave_list
=
469 kzalloc(dev
->num_slaves
* sizeof(struct slave_list
),
471 if (!priv
->mfunc
.master
.res_tracker
.slave_list
)
474 for (i
= 0 ; i
< dev
->num_slaves
; i
++) {
475 for (t
= 0; t
< MLX4_NUM_OF_RESOURCE_TYPE
; ++t
)
476 INIT_LIST_HEAD(&priv
->mfunc
.master
.res_tracker
.
477 slave_list
[i
].res_list
[t
]);
478 mutex_init(&priv
->mfunc
.master
.res_tracker
.slave_list
[i
].mutex
);
481 mlx4_dbg(dev
, "Started init_resource_tracker: %ld slaves\n",
483 for (i
= 0 ; i
< MLX4_NUM_OF_RESOURCE_TYPE
; i
++)
484 priv
->mfunc
.master
.res_tracker
.res_tree
[i
] = RB_ROOT
;
486 for (i
= 0; i
< MLX4_NUM_OF_RESOURCE_TYPE
; i
++) {
487 struct resource_allocator
*res_alloc
=
488 &priv
->mfunc
.master
.res_tracker
.res_alloc
[i
];
489 res_alloc
->quota
= kmalloc((dev
->num_vfs
+ 1) * sizeof(int), GFP_KERNEL
);
490 res_alloc
->guaranteed
= kmalloc((dev
->num_vfs
+ 1) * sizeof(int), GFP_KERNEL
);
491 if (i
== RES_MAC
|| i
== RES_VLAN
)
492 res_alloc
->allocated
= kzalloc(MLX4_MAX_PORTS
*
493 (dev
->num_vfs
+ 1) * sizeof(int),
496 res_alloc
->allocated
= kzalloc((dev
->num_vfs
+ 1) * sizeof(int), GFP_KERNEL
);
498 if (!res_alloc
->quota
|| !res_alloc
->guaranteed
||
499 !res_alloc
->allocated
)
502 spin_lock_init(&res_alloc
->alloc_lock
);
503 for (t
= 0; t
< dev
->num_vfs
+ 1; t
++) {
504 struct mlx4_active_ports actv_ports
=
505 mlx4_get_active_ports(dev
, t
);
508 initialize_res_quotas(dev
, res_alloc
, RES_QP
,
509 t
, dev
->caps
.num_qps
-
510 dev
->caps
.reserved_qps
-
511 mlx4_num_reserved_sqps(dev
));
514 initialize_res_quotas(dev
, res_alloc
, RES_CQ
,
515 t
, dev
->caps
.num_cqs
-
516 dev
->caps
.reserved_cqs
);
519 initialize_res_quotas(dev
, res_alloc
, RES_SRQ
,
520 t
, dev
->caps
.num_srqs
-
521 dev
->caps
.reserved_srqs
);
524 initialize_res_quotas(dev
, res_alloc
, RES_MPT
,
525 t
, dev
->caps
.num_mpts
-
526 dev
->caps
.reserved_mrws
);
529 initialize_res_quotas(dev
, res_alloc
, RES_MTT
,
530 t
, dev
->caps
.num_mtts
-
531 dev
->caps
.reserved_mtts
);
534 if (t
== mlx4_master_func_num(dev
)) {
535 int max_vfs_pport
= 0;
536 /* Calculate the max vfs per port for */
538 for (j
= 0; j
< dev
->caps
.num_ports
;
540 struct mlx4_slaves_pport slaves_pport
=
541 mlx4_phys_to_slaves_pport(dev
, j
+ 1);
542 unsigned current_slaves
=
543 bitmap_weight(slaves_pport
.slaves
,
544 dev
->caps
.num_ports
) - 1;
545 if (max_vfs_pport
< current_slaves
)
549 res_alloc
->quota
[t
] =
552 res_alloc
->guaranteed
[t
] = 2;
553 for (j
= 0; j
< MLX4_MAX_PORTS
; j
++)
554 res_alloc
->res_port_free
[j
] =
557 res_alloc
->quota
[t
] = MLX4_MAX_MAC_NUM
;
558 res_alloc
->guaranteed
[t
] = 2;
562 if (t
== mlx4_master_func_num(dev
)) {
563 res_alloc
->quota
[t
] = MLX4_MAX_VLAN_NUM
;
564 res_alloc
->guaranteed
[t
] = MLX4_MAX_VLAN_NUM
/ 2;
565 for (j
= 0; j
< MLX4_MAX_PORTS
; j
++)
566 res_alloc
->res_port_free
[j
] =
569 res_alloc
->quota
[t
] = MLX4_MAX_VLAN_NUM
/ 2;
570 res_alloc
->guaranteed
[t
] = 0;
574 res_alloc
->quota
[t
] = dev
->caps
.max_counters
;
575 res_alloc
->guaranteed
[t
] = 0;
576 if (t
== mlx4_master_func_num(dev
))
577 res_alloc
->res_free
= res_alloc
->quota
[t
];
582 if (i
== RES_MAC
|| i
== RES_VLAN
) {
583 for (j
= 0; j
< dev
->caps
.num_ports
; j
++)
584 if (test_bit(j
, actv_ports
.ports
))
585 res_alloc
->res_port_rsvd
[j
] +=
586 res_alloc
->guaranteed
[t
];
588 res_alloc
->res_reserved
+= res_alloc
->guaranteed
[t
];
592 spin_lock_init(&priv
->mfunc
.master
.res_tracker
.lock
);
596 for (i
= 0; i
< MLX4_NUM_OF_RESOURCE_TYPE
; i
++) {
597 kfree(priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].allocated
);
598 priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].allocated
= NULL
;
599 kfree(priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].guaranteed
);
600 priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].guaranteed
= NULL
;
601 kfree(priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].quota
);
602 priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].quota
= NULL
;
607 void mlx4_free_resource_tracker(struct mlx4_dev
*dev
,
608 enum mlx4_res_tracker_free_type type
)
610 struct mlx4_priv
*priv
= mlx4_priv(dev
);
613 if (priv
->mfunc
.master
.res_tracker
.slave_list
) {
614 if (type
!= RES_TR_FREE_STRUCTS_ONLY
) {
615 for (i
= 0; i
< dev
->num_slaves
; i
++) {
616 if (type
== RES_TR_FREE_ALL
||
617 dev
->caps
.function
!= i
)
618 mlx4_delete_all_resources_for_slave(dev
, i
);
620 /* free master's vlans */
621 i
= dev
->caps
.function
;
622 mlx4_reset_roce_gids(dev
, i
);
623 mutex_lock(&priv
->mfunc
.master
.res_tracker
.slave_list
[i
].mutex
);
624 rem_slave_vlans(dev
, i
);
625 mutex_unlock(&priv
->mfunc
.master
.res_tracker
.slave_list
[i
].mutex
);
628 if (type
!= RES_TR_FREE_SLAVES_ONLY
) {
629 for (i
= 0; i
< MLX4_NUM_OF_RESOURCE_TYPE
; i
++) {
630 kfree(priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].allocated
);
631 priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].allocated
= NULL
;
632 kfree(priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].guaranteed
);
633 priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].guaranteed
= NULL
;
634 kfree(priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].quota
);
635 priv
->mfunc
.master
.res_tracker
.res_alloc
[i
].quota
= NULL
;
637 kfree(priv
->mfunc
.master
.res_tracker
.slave_list
);
638 priv
->mfunc
.master
.res_tracker
.slave_list
= NULL
;
643 static void update_pkey_index(struct mlx4_dev
*dev
, int slave
,
644 struct mlx4_cmd_mailbox
*inbox
)
646 u8 sched
= *(u8
*)(inbox
->buf
+ 64);
647 u8 orig_index
= *(u8
*)(inbox
->buf
+ 35);
649 struct mlx4_priv
*priv
= mlx4_priv(dev
);
652 port
= (sched
>> 6 & 1) + 1;
654 new_index
= priv
->virt2phys_pkey
[slave
][port
- 1][orig_index
];
655 *(u8
*)(inbox
->buf
+ 35) = new_index
;
658 static void update_gid(struct mlx4_dev
*dev
, struct mlx4_cmd_mailbox
*inbox
,
661 struct mlx4_qp_context
*qp_ctx
= inbox
->buf
+ 8;
662 enum mlx4_qp_optpar optpar
= be32_to_cpu(*(__be32
*) inbox
->buf
);
663 u32 ts
= (be32_to_cpu(qp_ctx
->flags
) >> 16) & 0xff;
666 if (MLX4_QP_ST_UD
== ts
) {
667 port
= (qp_ctx
->pri_path
.sched_queue
>> 6 & 1) + 1;
668 if (mlx4_is_eth(dev
, port
))
669 qp_ctx
->pri_path
.mgid_index
=
670 mlx4_get_base_gid_ix(dev
, slave
, port
) | 0x80;
672 qp_ctx
->pri_path
.mgid_index
= slave
| 0x80;
674 } else if (MLX4_QP_ST_RC
== ts
|| MLX4_QP_ST_XRC
== ts
|| MLX4_QP_ST_UC
== ts
) {
675 if (optpar
& MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH
) {
676 port
= (qp_ctx
->pri_path
.sched_queue
>> 6 & 1) + 1;
677 if (mlx4_is_eth(dev
, port
)) {
678 qp_ctx
->pri_path
.mgid_index
+=
679 mlx4_get_base_gid_ix(dev
, slave
, port
);
680 qp_ctx
->pri_path
.mgid_index
&= 0x7f;
682 qp_ctx
->pri_path
.mgid_index
= slave
& 0x7F;
685 if (optpar
& MLX4_QP_OPTPAR_ALT_ADDR_PATH
) {
686 port
= (qp_ctx
->alt_path
.sched_queue
>> 6 & 1) + 1;
687 if (mlx4_is_eth(dev
, port
)) {
688 qp_ctx
->alt_path
.mgid_index
+=
689 mlx4_get_base_gid_ix(dev
, slave
, port
);
690 qp_ctx
->alt_path
.mgid_index
&= 0x7f;
692 qp_ctx
->alt_path
.mgid_index
= slave
& 0x7F;
698 static int update_vport_qp_param(struct mlx4_dev
*dev
,
699 struct mlx4_cmd_mailbox
*inbox
,
702 struct mlx4_qp_context
*qpc
= inbox
->buf
+ 8;
703 struct mlx4_vport_oper_state
*vp_oper
;
704 struct mlx4_priv
*priv
;
708 port
= (qpc
->pri_path
.sched_queue
& 0x40) ? 2 : 1;
709 priv
= mlx4_priv(dev
);
710 vp_oper
= &priv
->mfunc
.master
.vf_oper
[slave
].vport
[port
];
711 qp_type
= (be32_to_cpu(qpc
->flags
) >> 16) & 0xff;
713 if (MLX4_VGT
!= vp_oper
->state
.default_vlan
) {
714 /* the reserved QPs (special, proxy, tunnel)
715 * do not operate over vlans
717 if (mlx4_is_qp_reserved(dev
, qpn
))
720 /* force strip vlan by clear vsd, MLX QP refers to Raw Ethernet */
721 if (qp_type
== MLX4_QP_ST_UD
||
722 (qp_type
== MLX4_QP_ST_MLX
&& mlx4_is_eth(dev
, port
))) {
723 if (dev
->caps
.bmme_flags
& MLX4_BMME_FLAG_VSD_INIT2RTR
) {
724 *(__be32
*)inbox
->buf
=
725 cpu_to_be32(be32_to_cpu(*(__be32
*)inbox
->buf
) |
726 MLX4_QP_OPTPAR_VLAN_STRIPPING
);
727 qpc
->param3
&= ~cpu_to_be32(MLX4_STRIP_VLAN
);
729 struct mlx4_update_qp_params params
= {.flags
= 0};
731 mlx4_update_qp(dev
, qpn
, MLX4_UPDATE_QP_VSD
, ¶ms
);
735 if (vp_oper
->state
.link_state
== IFLA_VF_LINK_STATE_DISABLE
&&
736 dev
->caps
.flags2
& MLX4_DEV_CAP_FLAG2_UPDATE_QP
) {
737 qpc
->pri_path
.vlan_control
=
738 MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED
|
739 MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED
|
740 MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED
|
741 MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED
|
742 MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED
|
743 MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED
;
744 } else if (0 != vp_oper
->state
.default_vlan
) {
745 qpc
->pri_path
.vlan_control
=
746 MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED
|
747 MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED
|
748 MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED
;
749 } else { /* priority tagged */
750 qpc
->pri_path
.vlan_control
=
751 MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED
|
752 MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED
;
755 qpc
->pri_path
.fvl_rx
|= MLX4_FVL_RX_FORCE_ETH_VLAN
;
756 qpc
->pri_path
.vlan_index
= vp_oper
->vlan_idx
;
757 qpc
->pri_path
.fl
|= MLX4_FL_CV
| MLX4_FL_ETH_HIDE_CQE_VLAN
;
758 qpc
->pri_path
.feup
|= MLX4_FEUP_FORCE_ETH_UP
| MLX4_FVL_FORCE_ETH_VLAN
;
759 qpc
->pri_path
.sched_queue
&= 0xC7;
760 qpc
->pri_path
.sched_queue
|= (vp_oper
->state
.default_qos
) << 3;
762 if (vp_oper
->state
.spoofchk
) {
763 qpc
->pri_path
.feup
|= MLX4_FSM_FORCE_ETH_SRC_MAC
;
764 qpc
->pri_path
.grh_mylmc
= (0x80 & qpc
->pri_path
.grh_mylmc
) + vp_oper
->mac_idx
;
769 static int mpt_mask(struct mlx4_dev
*dev
)
771 return dev
->caps
.num_mpts
- 1;
774 static void *find_res(struct mlx4_dev
*dev
, u64 res_id
,
775 enum mlx4_resource type
)
777 struct mlx4_priv
*priv
= mlx4_priv(dev
);
779 return res_tracker_lookup(&priv
->mfunc
.master
.res_tracker
.res_tree
[type
],
783 static int get_res(struct mlx4_dev
*dev
, int slave
, u64 res_id
,
784 enum mlx4_resource type
,
787 struct res_common
*r
;
790 spin_lock_irq(mlx4_tlock(dev
));
791 r
= find_res(dev
, res_id
, type
);
797 if (r
->state
== RES_ANY_BUSY
) {
802 if (r
->owner
!= slave
) {
807 r
->from_state
= r
->state
;
808 r
->state
= RES_ANY_BUSY
;
811 *((struct res_common
**)res
) = r
;
814 spin_unlock_irq(mlx4_tlock(dev
));
818 int mlx4_get_slave_from_resource_id(struct mlx4_dev
*dev
,
819 enum mlx4_resource type
,
820 u64 res_id
, int *slave
)
823 struct res_common
*r
;
829 spin_lock(mlx4_tlock(dev
));
831 r
= find_res(dev
, id
, type
);
836 spin_unlock(mlx4_tlock(dev
));
841 static void put_res(struct mlx4_dev
*dev
, int slave
, u64 res_id
,
842 enum mlx4_resource type
)
844 struct res_common
*r
;
846 spin_lock_irq(mlx4_tlock(dev
));
847 r
= find_res(dev
, res_id
, type
);
849 r
->state
= r
->from_state
;
850 spin_unlock_irq(mlx4_tlock(dev
));
853 static struct res_common
*alloc_qp_tr(int id
)
857 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
861 ret
->com
.res_id
= id
;
862 ret
->com
.state
= RES_QP_RESERVED
;
864 INIT_LIST_HEAD(&ret
->mcg_list
);
865 spin_lock_init(&ret
->mcg_spl
);
866 atomic_set(&ret
->ref_count
, 0);
871 static struct res_common
*alloc_mtt_tr(int id
, int order
)
875 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
879 ret
->com
.res_id
= id
;
881 ret
->com
.state
= RES_MTT_ALLOCATED
;
882 atomic_set(&ret
->ref_count
, 0);
887 static struct res_common
*alloc_mpt_tr(int id
, int key
)
891 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
895 ret
->com
.res_id
= id
;
896 ret
->com
.state
= RES_MPT_RESERVED
;
902 static struct res_common
*alloc_eq_tr(int id
)
906 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
910 ret
->com
.res_id
= id
;
911 ret
->com
.state
= RES_EQ_RESERVED
;
916 static struct res_common
*alloc_cq_tr(int id
)
920 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
924 ret
->com
.res_id
= id
;
925 ret
->com
.state
= RES_CQ_ALLOCATED
;
926 atomic_set(&ret
->ref_count
, 0);
931 static struct res_common
*alloc_srq_tr(int id
)
935 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
939 ret
->com
.res_id
= id
;
940 ret
->com
.state
= RES_SRQ_ALLOCATED
;
941 atomic_set(&ret
->ref_count
, 0);
946 static struct res_common
*alloc_counter_tr(int id
)
948 struct res_counter
*ret
;
950 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
954 ret
->com
.res_id
= id
;
955 ret
->com
.state
= RES_COUNTER_ALLOCATED
;
960 static struct res_common
*alloc_xrcdn_tr(int id
)
962 struct res_xrcdn
*ret
;
964 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
968 ret
->com
.res_id
= id
;
969 ret
->com
.state
= RES_XRCD_ALLOCATED
;
974 static struct res_common
*alloc_fs_rule_tr(u64 id
, int qpn
)
976 struct res_fs_rule
*ret
;
978 ret
= kzalloc(sizeof *ret
, GFP_KERNEL
);
982 ret
->com
.res_id
= id
;
983 ret
->com
.state
= RES_FS_RULE_ALLOCATED
;
988 static struct res_common
*alloc_tr(u64 id
, enum mlx4_resource type
, int slave
,
991 struct res_common
*ret
;
995 ret
= alloc_qp_tr(id
);
998 ret
= alloc_mpt_tr(id
, extra
);
1001 ret
= alloc_mtt_tr(id
, extra
);
1004 ret
= alloc_eq_tr(id
);
1007 ret
= alloc_cq_tr(id
);
1010 ret
= alloc_srq_tr(id
);
1013 pr_err("implementation missing\n");
1016 ret
= alloc_counter_tr(id
);
1019 ret
= alloc_xrcdn_tr(id
);
1022 ret
= alloc_fs_rule_tr(id
, extra
);
1033 static int add_res_range(struct mlx4_dev
*dev
, int slave
, u64 base
, int count
,
1034 enum mlx4_resource type
, int extra
)
1038 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1039 struct res_common
**res_arr
;
1040 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1041 struct rb_root
*root
= &tracker
->res_tree
[type
];
1043 res_arr
= kzalloc(count
* sizeof *res_arr
, GFP_KERNEL
);
1047 for (i
= 0; i
< count
; ++i
) {
1048 res_arr
[i
] = alloc_tr(base
+ i
, type
, slave
, extra
);
1050 for (--i
; i
>= 0; --i
)
1058 spin_lock_irq(mlx4_tlock(dev
));
1059 for (i
= 0; i
< count
; ++i
) {
1060 if (find_res(dev
, base
+ i
, type
)) {
1064 err
= res_tracker_insert(root
, res_arr
[i
]);
1067 list_add_tail(&res_arr
[i
]->list
,
1068 &tracker
->slave_list
[slave
].res_list
[type
]);
1070 spin_unlock_irq(mlx4_tlock(dev
));
1076 for (--i
; i
>= base
; --i
)
1077 rb_erase(&res_arr
[i
]->node
, root
);
1079 spin_unlock_irq(mlx4_tlock(dev
));
1081 for (i
= 0; i
< count
; ++i
)
1089 static int remove_qp_ok(struct res_qp
*res
)
1091 if (res
->com
.state
== RES_QP_BUSY
|| atomic_read(&res
->ref_count
) ||
1092 !list_empty(&res
->mcg_list
)) {
1093 pr_err("resource tracker: fail to remove qp, state %d, ref_count %d\n",
1094 res
->com
.state
, atomic_read(&res
->ref_count
));
1096 } else if (res
->com
.state
!= RES_QP_RESERVED
) {
1103 static int remove_mtt_ok(struct res_mtt
*res
, int order
)
1105 if (res
->com
.state
== RES_MTT_BUSY
||
1106 atomic_read(&res
->ref_count
)) {
1107 pr_devel("%s-%d: state %s, ref_count %d\n",
1109 mtt_states_str(res
->com
.state
),
1110 atomic_read(&res
->ref_count
));
1112 } else if (res
->com
.state
!= RES_MTT_ALLOCATED
)
1114 else if (res
->order
!= order
)
1120 static int remove_mpt_ok(struct res_mpt
*res
)
1122 if (res
->com
.state
== RES_MPT_BUSY
)
1124 else if (res
->com
.state
!= RES_MPT_RESERVED
)
1130 static int remove_eq_ok(struct res_eq
*res
)
1132 if (res
->com
.state
== RES_MPT_BUSY
)
1134 else if (res
->com
.state
!= RES_MPT_RESERVED
)
1140 static int remove_counter_ok(struct res_counter
*res
)
1142 if (res
->com
.state
== RES_COUNTER_BUSY
)
1144 else if (res
->com
.state
!= RES_COUNTER_ALLOCATED
)
1150 static int remove_xrcdn_ok(struct res_xrcdn
*res
)
1152 if (res
->com
.state
== RES_XRCD_BUSY
)
1154 else if (res
->com
.state
!= RES_XRCD_ALLOCATED
)
1160 static int remove_fs_rule_ok(struct res_fs_rule
*res
)
1162 if (res
->com
.state
== RES_FS_RULE_BUSY
)
1164 else if (res
->com
.state
!= RES_FS_RULE_ALLOCATED
)
1170 static int remove_cq_ok(struct res_cq
*res
)
1172 if (res
->com
.state
== RES_CQ_BUSY
)
1174 else if (res
->com
.state
!= RES_CQ_ALLOCATED
)
1180 static int remove_srq_ok(struct res_srq
*res
)
1182 if (res
->com
.state
== RES_SRQ_BUSY
)
1184 else if (res
->com
.state
!= RES_SRQ_ALLOCATED
)
1190 static int remove_ok(struct res_common
*res
, enum mlx4_resource type
, int extra
)
1194 return remove_qp_ok((struct res_qp
*)res
);
1196 return remove_cq_ok((struct res_cq
*)res
);
1198 return remove_srq_ok((struct res_srq
*)res
);
1200 return remove_mpt_ok((struct res_mpt
*)res
);
1202 return remove_mtt_ok((struct res_mtt
*)res
, extra
);
1206 return remove_eq_ok((struct res_eq
*)res
);
1208 return remove_counter_ok((struct res_counter
*)res
);
1210 return remove_xrcdn_ok((struct res_xrcdn
*)res
);
1212 return remove_fs_rule_ok((struct res_fs_rule
*)res
);
1218 static int rem_res_range(struct mlx4_dev
*dev
, int slave
, u64 base
, int count
,
1219 enum mlx4_resource type
, int extra
)
1223 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1224 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1225 struct res_common
*r
;
1227 spin_lock_irq(mlx4_tlock(dev
));
1228 for (i
= base
; i
< base
+ count
; ++i
) {
1229 r
= res_tracker_lookup(&tracker
->res_tree
[type
], i
);
1234 if (r
->owner
!= slave
) {
1238 err
= remove_ok(r
, type
, extra
);
1243 for (i
= base
; i
< base
+ count
; ++i
) {
1244 r
= res_tracker_lookup(&tracker
->res_tree
[type
], i
);
1245 rb_erase(&r
->node
, &tracker
->res_tree
[type
]);
1252 spin_unlock_irq(mlx4_tlock(dev
));
1257 static int qp_res_start_move_to(struct mlx4_dev
*dev
, int slave
, int qpn
,
1258 enum res_qp_states state
, struct res_qp
**qp
,
1261 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1262 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1266 spin_lock_irq(mlx4_tlock(dev
));
1267 r
= res_tracker_lookup(&tracker
->res_tree
[RES_QP
], qpn
);
1270 else if (r
->com
.owner
!= slave
)
1275 mlx4_dbg(dev
, "%s: failed RES_QP, 0x%llx\n",
1276 __func__
, r
->com
.res_id
);
1280 case RES_QP_RESERVED
:
1281 if (r
->com
.state
== RES_QP_MAPPED
&& !alloc
)
1284 mlx4_dbg(dev
, "failed RES_QP, 0x%llx\n", r
->com
.res_id
);
1289 if ((r
->com
.state
== RES_QP_RESERVED
&& alloc
) ||
1290 r
->com
.state
== RES_QP_HW
)
1293 mlx4_dbg(dev
, "failed RES_QP, 0x%llx\n",
1301 if (r
->com
.state
!= RES_QP_MAPPED
)
1309 r
->com
.from_state
= r
->com
.state
;
1310 r
->com
.to_state
= state
;
1311 r
->com
.state
= RES_QP_BUSY
;
1317 spin_unlock_irq(mlx4_tlock(dev
));
1322 static int mr_res_start_move_to(struct mlx4_dev
*dev
, int slave
, int index
,
1323 enum res_mpt_states state
, struct res_mpt
**mpt
)
1325 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1326 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1330 spin_lock_irq(mlx4_tlock(dev
));
1331 r
= res_tracker_lookup(&tracker
->res_tree
[RES_MPT
], index
);
1334 else if (r
->com
.owner
!= slave
)
1342 case RES_MPT_RESERVED
:
1343 if (r
->com
.state
!= RES_MPT_MAPPED
)
1347 case RES_MPT_MAPPED
:
1348 if (r
->com
.state
!= RES_MPT_RESERVED
&&
1349 r
->com
.state
!= RES_MPT_HW
)
1354 if (r
->com
.state
!= RES_MPT_MAPPED
)
1362 r
->com
.from_state
= r
->com
.state
;
1363 r
->com
.to_state
= state
;
1364 r
->com
.state
= RES_MPT_BUSY
;
1370 spin_unlock_irq(mlx4_tlock(dev
));
1375 static int eq_res_start_move_to(struct mlx4_dev
*dev
, int slave
, int index
,
1376 enum res_eq_states state
, struct res_eq
**eq
)
1378 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1379 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1383 spin_lock_irq(mlx4_tlock(dev
));
1384 r
= res_tracker_lookup(&tracker
->res_tree
[RES_EQ
], index
);
1387 else if (r
->com
.owner
!= slave
)
1395 case RES_EQ_RESERVED
:
1396 if (r
->com
.state
!= RES_EQ_HW
)
1401 if (r
->com
.state
!= RES_EQ_RESERVED
)
1410 r
->com
.from_state
= r
->com
.state
;
1411 r
->com
.to_state
= state
;
1412 r
->com
.state
= RES_EQ_BUSY
;
1418 spin_unlock_irq(mlx4_tlock(dev
));
1423 static int cq_res_start_move_to(struct mlx4_dev
*dev
, int slave
, int cqn
,
1424 enum res_cq_states state
, struct res_cq
**cq
)
1426 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1427 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1431 spin_lock_irq(mlx4_tlock(dev
));
1432 r
= res_tracker_lookup(&tracker
->res_tree
[RES_CQ
], cqn
);
1435 } else if (r
->com
.owner
!= slave
) {
1437 } else if (state
== RES_CQ_ALLOCATED
) {
1438 if (r
->com
.state
!= RES_CQ_HW
)
1440 else if (atomic_read(&r
->ref_count
))
1444 } else if (state
!= RES_CQ_HW
|| r
->com
.state
!= RES_CQ_ALLOCATED
) {
1451 r
->com
.from_state
= r
->com
.state
;
1452 r
->com
.to_state
= state
;
1453 r
->com
.state
= RES_CQ_BUSY
;
1458 spin_unlock_irq(mlx4_tlock(dev
));
1463 static int srq_res_start_move_to(struct mlx4_dev
*dev
, int slave
, int index
,
1464 enum res_srq_states state
, struct res_srq
**srq
)
1466 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1467 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1471 spin_lock_irq(mlx4_tlock(dev
));
1472 r
= res_tracker_lookup(&tracker
->res_tree
[RES_SRQ
], index
);
1475 } else if (r
->com
.owner
!= slave
) {
1477 } else if (state
== RES_SRQ_ALLOCATED
) {
1478 if (r
->com
.state
!= RES_SRQ_HW
)
1480 else if (atomic_read(&r
->ref_count
))
1482 } else if (state
!= RES_SRQ_HW
|| r
->com
.state
!= RES_SRQ_ALLOCATED
) {
1487 r
->com
.from_state
= r
->com
.state
;
1488 r
->com
.to_state
= state
;
1489 r
->com
.state
= RES_SRQ_BUSY
;
1494 spin_unlock_irq(mlx4_tlock(dev
));
1499 static void res_abort_move(struct mlx4_dev
*dev
, int slave
,
1500 enum mlx4_resource type
, int id
)
1502 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1503 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1504 struct res_common
*r
;
1506 spin_lock_irq(mlx4_tlock(dev
));
1507 r
= res_tracker_lookup(&tracker
->res_tree
[type
], id
);
1508 if (r
&& (r
->owner
== slave
))
1509 r
->state
= r
->from_state
;
1510 spin_unlock_irq(mlx4_tlock(dev
));
1513 static void res_end_move(struct mlx4_dev
*dev
, int slave
,
1514 enum mlx4_resource type
, int id
)
1516 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1517 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1518 struct res_common
*r
;
1520 spin_lock_irq(mlx4_tlock(dev
));
1521 r
= res_tracker_lookup(&tracker
->res_tree
[type
], id
);
1522 if (r
&& (r
->owner
== slave
))
1523 r
->state
= r
->to_state
;
1524 spin_unlock_irq(mlx4_tlock(dev
));
1527 static int valid_reserved(struct mlx4_dev
*dev
, int slave
, int qpn
)
1529 return mlx4_is_qp_reserved(dev
, qpn
) &&
1530 (mlx4_is_master(dev
) || mlx4_is_guest_proxy(dev
, slave
, qpn
));
1533 static int fw_reserved(struct mlx4_dev
*dev
, int qpn
)
1535 return qpn
< dev
->caps
.reserved_qps_cnt
[MLX4_QP_REGION_FW
];
1538 static int qp_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1539 u64 in_param
, u64
*out_param
)
1549 case RES_OP_RESERVE
:
1550 count
= get_param_l(&in_param
) & 0xffffff;
1551 /* Turn off all unsupported QP allocation flags that the
1552 * slave tries to set.
1554 flags
= (get_param_l(&in_param
) >> 24) & dev
->caps
.alloc_res_qp_mask
;
1555 align
= get_param_h(&in_param
);
1556 err
= mlx4_grant_resource(dev
, slave
, RES_QP
, count
, 0);
1560 err
= __mlx4_qp_reserve_range(dev
, count
, align
, &base
, flags
);
1562 mlx4_release_resource(dev
, slave
, RES_QP
, count
, 0);
1566 err
= add_res_range(dev
, slave
, base
, count
, RES_QP
, 0);
1568 mlx4_release_resource(dev
, slave
, RES_QP
, count
, 0);
1569 __mlx4_qp_release_range(dev
, base
, count
);
1572 set_param_l(out_param
, base
);
1574 case RES_OP_MAP_ICM
:
1575 qpn
= get_param_l(&in_param
) & 0x7fffff;
1576 if (valid_reserved(dev
, slave
, qpn
)) {
1577 err
= add_res_range(dev
, slave
, qpn
, 1, RES_QP
, 0);
1582 err
= qp_res_start_move_to(dev
, slave
, qpn
, RES_QP_MAPPED
,
1587 if (!fw_reserved(dev
, qpn
)) {
1588 err
= __mlx4_qp_alloc_icm(dev
, qpn
, GFP_KERNEL
);
1590 res_abort_move(dev
, slave
, RES_QP
, qpn
);
1595 res_end_move(dev
, slave
, RES_QP
, qpn
);
1605 static int mtt_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1606 u64 in_param
, u64
*out_param
)
1612 if (op
!= RES_OP_RESERVE_AND_MAP
)
1615 order
= get_param_l(&in_param
);
1617 err
= mlx4_grant_resource(dev
, slave
, RES_MTT
, 1 << order
, 0);
1621 base
= __mlx4_alloc_mtt_range(dev
, order
);
1623 mlx4_release_resource(dev
, slave
, RES_MTT
, 1 << order
, 0);
1627 err
= add_res_range(dev
, slave
, base
, 1, RES_MTT
, order
);
1629 mlx4_release_resource(dev
, slave
, RES_MTT
, 1 << order
, 0);
1630 __mlx4_free_mtt_range(dev
, base
, order
);
1632 set_param_l(out_param
, base
);
1638 static int mpt_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1639 u64 in_param
, u64
*out_param
)
1644 struct res_mpt
*mpt
;
1647 case RES_OP_RESERVE
:
1648 err
= mlx4_grant_resource(dev
, slave
, RES_MPT
, 1, 0);
1652 index
= __mlx4_mpt_reserve(dev
);
1654 mlx4_release_resource(dev
, slave
, RES_MPT
, 1, 0);
1657 id
= index
& mpt_mask(dev
);
1659 err
= add_res_range(dev
, slave
, id
, 1, RES_MPT
, index
);
1661 mlx4_release_resource(dev
, slave
, RES_MPT
, 1, 0);
1662 __mlx4_mpt_release(dev
, index
);
1665 set_param_l(out_param
, index
);
1667 case RES_OP_MAP_ICM
:
1668 index
= get_param_l(&in_param
);
1669 id
= index
& mpt_mask(dev
);
1670 err
= mr_res_start_move_to(dev
, slave
, id
,
1671 RES_MPT_MAPPED
, &mpt
);
1675 err
= __mlx4_mpt_alloc_icm(dev
, mpt
->key
, GFP_KERNEL
);
1677 res_abort_move(dev
, slave
, RES_MPT
, id
);
1681 res_end_move(dev
, slave
, RES_MPT
, id
);
1687 static int cq_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1688 u64 in_param
, u64
*out_param
)
1694 case RES_OP_RESERVE_AND_MAP
:
1695 err
= mlx4_grant_resource(dev
, slave
, RES_CQ
, 1, 0);
1699 err
= __mlx4_cq_alloc_icm(dev
, &cqn
);
1701 mlx4_release_resource(dev
, slave
, RES_CQ
, 1, 0);
1705 err
= add_res_range(dev
, slave
, cqn
, 1, RES_CQ
, 0);
1707 mlx4_release_resource(dev
, slave
, RES_CQ
, 1, 0);
1708 __mlx4_cq_free_icm(dev
, cqn
);
1712 set_param_l(out_param
, cqn
);
1722 static int srq_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1723 u64 in_param
, u64
*out_param
)
1729 case RES_OP_RESERVE_AND_MAP
:
1730 err
= mlx4_grant_resource(dev
, slave
, RES_SRQ
, 1, 0);
1734 err
= __mlx4_srq_alloc_icm(dev
, &srqn
);
1736 mlx4_release_resource(dev
, slave
, RES_SRQ
, 1, 0);
1740 err
= add_res_range(dev
, slave
, srqn
, 1, RES_SRQ
, 0);
1742 mlx4_release_resource(dev
, slave
, RES_SRQ
, 1, 0);
1743 __mlx4_srq_free_icm(dev
, srqn
);
1747 set_param_l(out_param
, srqn
);
1757 static int mac_find_smac_ix_in_slave(struct mlx4_dev
*dev
, int slave
, int port
,
1758 u8 smac_index
, u64
*mac
)
1760 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1761 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1762 struct list_head
*mac_list
=
1763 &tracker
->slave_list
[slave
].res_list
[RES_MAC
];
1764 struct mac_res
*res
, *tmp
;
1766 list_for_each_entry_safe(res
, tmp
, mac_list
, list
) {
1767 if (res
->smac_index
== smac_index
&& res
->port
== (u8
) port
) {
1775 static int mac_add_to_slave(struct mlx4_dev
*dev
, int slave
, u64 mac
, int port
, u8 smac_index
)
1777 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1778 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1779 struct list_head
*mac_list
=
1780 &tracker
->slave_list
[slave
].res_list
[RES_MAC
];
1781 struct mac_res
*res
, *tmp
;
1783 list_for_each_entry_safe(res
, tmp
, mac_list
, list
) {
1784 if (res
->mac
== mac
&& res
->port
== (u8
) port
) {
1785 /* mac found. update ref count */
1791 if (mlx4_grant_resource(dev
, slave
, RES_MAC
, 1, port
))
1793 res
= kzalloc(sizeof *res
, GFP_KERNEL
);
1795 mlx4_release_resource(dev
, slave
, RES_MAC
, 1, port
);
1799 res
->port
= (u8
) port
;
1800 res
->smac_index
= smac_index
;
1802 list_add_tail(&res
->list
,
1803 &tracker
->slave_list
[slave
].res_list
[RES_MAC
]);
1807 static void mac_del_from_slave(struct mlx4_dev
*dev
, int slave
, u64 mac
,
1810 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1811 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1812 struct list_head
*mac_list
=
1813 &tracker
->slave_list
[slave
].res_list
[RES_MAC
];
1814 struct mac_res
*res
, *tmp
;
1816 list_for_each_entry_safe(res
, tmp
, mac_list
, list
) {
1817 if (res
->mac
== mac
&& res
->port
== (u8
) port
) {
1818 if (!--res
->ref_count
) {
1819 list_del(&res
->list
);
1820 mlx4_release_resource(dev
, slave
, RES_MAC
, 1, port
);
1828 static void rem_slave_macs(struct mlx4_dev
*dev
, int slave
)
1830 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1831 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1832 struct list_head
*mac_list
=
1833 &tracker
->slave_list
[slave
].res_list
[RES_MAC
];
1834 struct mac_res
*res
, *tmp
;
1837 list_for_each_entry_safe(res
, tmp
, mac_list
, list
) {
1838 list_del(&res
->list
);
1839 /* dereference the mac the num times the slave referenced it */
1840 for (i
= 0; i
< res
->ref_count
; i
++)
1841 __mlx4_unregister_mac(dev
, res
->port
, res
->mac
);
1842 mlx4_release_resource(dev
, slave
, RES_MAC
, 1, res
->port
);
1847 static int mac_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1848 u64 in_param
, u64
*out_param
, int in_port
)
1855 if (op
!= RES_OP_RESERVE_AND_MAP
)
1858 port
= !in_port
? get_param_l(out_param
) : in_port
;
1859 port
= mlx4_slave_convert_port(
1866 err
= __mlx4_register_mac(dev
, port
, mac
);
1869 set_param_l(out_param
, err
);
1874 err
= mac_add_to_slave(dev
, slave
, mac
, port
, smac_index
);
1876 __mlx4_unregister_mac(dev
, port
, mac
);
1881 static int vlan_add_to_slave(struct mlx4_dev
*dev
, int slave
, u16 vlan
,
1882 int port
, int vlan_index
)
1884 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1885 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1886 struct list_head
*vlan_list
=
1887 &tracker
->slave_list
[slave
].res_list
[RES_VLAN
];
1888 struct vlan_res
*res
, *tmp
;
1890 list_for_each_entry_safe(res
, tmp
, vlan_list
, list
) {
1891 if (res
->vlan
== vlan
&& res
->port
== (u8
) port
) {
1892 /* vlan found. update ref count */
1898 if (mlx4_grant_resource(dev
, slave
, RES_VLAN
, 1, port
))
1900 res
= kzalloc(sizeof(*res
), GFP_KERNEL
);
1902 mlx4_release_resource(dev
, slave
, RES_VLAN
, 1, port
);
1906 res
->port
= (u8
) port
;
1907 res
->vlan_index
= vlan_index
;
1909 list_add_tail(&res
->list
,
1910 &tracker
->slave_list
[slave
].res_list
[RES_VLAN
]);
1915 static void vlan_del_from_slave(struct mlx4_dev
*dev
, int slave
, u16 vlan
,
1918 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1919 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1920 struct list_head
*vlan_list
=
1921 &tracker
->slave_list
[slave
].res_list
[RES_VLAN
];
1922 struct vlan_res
*res
, *tmp
;
1924 list_for_each_entry_safe(res
, tmp
, vlan_list
, list
) {
1925 if (res
->vlan
== vlan
&& res
->port
== (u8
) port
) {
1926 if (!--res
->ref_count
) {
1927 list_del(&res
->list
);
1928 mlx4_release_resource(dev
, slave
, RES_VLAN
,
1937 static void rem_slave_vlans(struct mlx4_dev
*dev
, int slave
)
1939 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1940 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
1941 struct list_head
*vlan_list
=
1942 &tracker
->slave_list
[slave
].res_list
[RES_VLAN
];
1943 struct vlan_res
*res
, *tmp
;
1946 list_for_each_entry_safe(res
, tmp
, vlan_list
, list
) {
1947 list_del(&res
->list
);
1948 /* dereference the vlan the num times the slave referenced it */
1949 for (i
= 0; i
< res
->ref_count
; i
++)
1950 __mlx4_unregister_vlan(dev
, res
->port
, res
->vlan
);
1951 mlx4_release_resource(dev
, slave
, RES_VLAN
, 1, res
->port
);
1956 static int vlan_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1957 u64 in_param
, u64
*out_param
, int in_port
)
1959 struct mlx4_priv
*priv
= mlx4_priv(dev
);
1960 struct mlx4_slave_state
*slave_state
= priv
->mfunc
.master
.slave_state
;
1966 port
= !in_port
? get_param_l(out_param
) : in_port
;
1968 if (!port
|| op
!= RES_OP_RESERVE_AND_MAP
)
1971 port
= mlx4_slave_convert_port(
1976 /* upstream kernels had NOP for reg/unreg vlan. Continue this. */
1977 if (!in_port
&& port
> 0 && port
<= dev
->caps
.num_ports
) {
1978 slave_state
[slave
].old_vlan_api
= true;
1982 vlan
= (u16
) in_param
;
1984 err
= __mlx4_register_vlan(dev
, port
, vlan
, &vlan_index
);
1986 set_param_l(out_param
, (u32
) vlan_index
);
1987 err
= vlan_add_to_slave(dev
, slave
, vlan
, port
, vlan_index
);
1989 __mlx4_unregister_vlan(dev
, port
, vlan
);
1994 static int counter_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
1995 u64 in_param
, u64
*out_param
)
2000 if (op
!= RES_OP_RESERVE
)
2003 err
= mlx4_grant_resource(dev
, slave
, RES_COUNTER
, 1, 0);
2007 err
= __mlx4_counter_alloc(dev
, &index
);
2009 mlx4_release_resource(dev
, slave
, RES_COUNTER
, 1, 0);
2013 err
= add_res_range(dev
, slave
, index
, 1, RES_COUNTER
, 0);
2015 __mlx4_counter_free(dev
, index
);
2016 mlx4_release_resource(dev
, slave
, RES_COUNTER
, 1, 0);
2018 set_param_l(out_param
, index
);
2024 static int xrcdn_alloc_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2025 u64 in_param
, u64
*out_param
)
2030 if (op
!= RES_OP_RESERVE
)
2033 err
= __mlx4_xrcd_alloc(dev
, &xrcdn
);
2037 err
= add_res_range(dev
, slave
, xrcdn
, 1, RES_XRCD
, 0);
2039 __mlx4_xrcd_free(dev
, xrcdn
);
2041 set_param_l(out_param
, xrcdn
);
2046 int mlx4_ALLOC_RES_wrapper(struct mlx4_dev
*dev
, int slave
,
2047 struct mlx4_vhcr
*vhcr
,
2048 struct mlx4_cmd_mailbox
*inbox
,
2049 struct mlx4_cmd_mailbox
*outbox
,
2050 struct mlx4_cmd_info
*cmd
)
2053 int alop
= vhcr
->op_modifier
;
2055 switch (vhcr
->in_modifier
& 0xFF) {
2057 err
= qp_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2058 vhcr
->in_param
, &vhcr
->out_param
);
2062 err
= mtt_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2063 vhcr
->in_param
, &vhcr
->out_param
);
2067 err
= mpt_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2068 vhcr
->in_param
, &vhcr
->out_param
);
2072 err
= cq_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2073 vhcr
->in_param
, &vhcr
->out_param
);
2077 err
= srq_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2078 vhcr
->in_param
, &vhcr
->out_param
);
2082 err
= mac_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2083 vhcr
->in_param
, &vhcr
->out_param
,
2084 (vhcr
->in_modifier
>> 8) & 0xFF);
2088 err
= vlan_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2089 vhcr
->in_param
, &vhcr
->out_param
,
2090 (vhcr
->in_modifier
>> 8) & 0xFF);
2094 err
= counter_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2095 vhcr
->in_param
, &vhcr
->out_param
);
2099 err
= xrcdn_alloc_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2100 vhcr
->in_param
, &vhcr
->out_param
);
2111 static int qp_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2120 case RES_OP_RESERVE
:
2121 base
= get_param_l(&in_param
) & 0x7fffff;
2122 count
= get_param_h(&in_param
);
2123 err
= rem_res_range(dev
, slave
, base
, count
, RES_QP
, 0);
2126 mlx4_release_resource(dev
, slave
, RES_QP
, count
, 0);
2127 __mlx4_qp_release_range(dev
, base
, count
);
2129 case RES_OP_MAP_ICM
:
2130 qpn
= get_param_l(&in_param
) & 0x7fffff;
2131 err
= qp_res_start_move_to(dev
, slave
, qpn
, RES_QP_RESERVED
,
2136 if (!fw_reserved(dev
, qpn
))
2137 __mlx4_qp_free_icm(dev
, qpn
);
2139 res_end_move(dev
, slave
, RES_QP
, qpn
);
2141 if (valid_reserved(dev
, slave
, qpn
))
2142 err
= rem_res_range(dev
, slave
, qpn
, 1, RES_QP
, 0);
2151 static int mtt_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2152 u64 in_param
, u64
*out_param
)
2158 if (op
!= RES_OP_RESERVE_AND_MAP
)
2161 base
= get_param_l(&in_param
);
2162 order
= get_param_h(&in_param
);
2163 err
= rem_res_range(dev
, slave
, base
, 1, RES_MTT
, order
);
2165 mlx4_release_resource(dev
, slave
, RES_MTT
, 1 << order
, 0);
2166 __mlx4_free_mtt_range(dev
, base
, order
);
2171 static int mpt_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2177 struct res_mpt
*mpt
;
2180 case RES_OP_RESERVE
:
2181 index
= get_param_l(&in_param
);
2182 id
= index
& mpt_mask(dev
);
2183 err
= get_res(dev
, slave
, id
, RES_MPT
, &mpt
);
2187 put_res(dev
, slave
, id
, RES_MPT
);
2189 err
= rem_res_range(dev
, slave
, id
, 1, RES_MPT
, 0);
2192 mlx4_release_resource(dev
, slave
, RES_MPT
, 1, 0);
2193 __mlx4_mpt_release(dev
, index
);
2195 case RES_OP_MAP_ICM
:
2196 index
= get_param_l(&in_param
);
2197 id
= index
& mpt_mask(dev
);
2198 err
= mr_res_start_move_to(dev
, slave
, id
,
2199 RES_MPT_RESERVED
, &mpt
);
2203 __mlx4_mpt_free_icm(dev
, mpt
->key
);
2204 res_end_move(dev
, slave
, RES_MPT
, id
);
2214 static int cq_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2215 u64 in_param
, u64
*out_param
)
2221 case RES_OP_RESERVE_AND_MAP
:
2222 cqn
= get_param_l(&in_param
);
2223 err
= rem_res_range(dev
, slave
, cqn
, 1, RES_CQ
, 0);
2227 mlx4_release_resource(dev
, slave
, RES_CQ
, 1, 0);
2228 __mlx4_cq_free_icm(dev
, cqn
);
2239 static int srq_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2240 u64 in_param
, u64
*out_param
)
2246 case RES_OP_RESERVE_AND_MAP
:
2247 srqn
= get_param_l(&in_param
);
2248 err
= rem_res_range(dev
, slave
, srqn
, 1, RES_SRQ
, 0);
2252 mlx4_release_resource(dev
, slave
, RES_SRQ
, 1, 0);
2253 __mlx4_srq_free_icm(dev
, srqn
);
2264 static int mac_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2265 u64 in_param
, u64
*out_param
, int in_port
)
2271 case RES_OP_RESERVE_AND_MAP
:
2272 port
= !in_port
? get_param_l(out_param
) : in_port
;
2273 port
= mlx4_slave_convert_port(
2278 mac_del_from_slave(dev
, slave
, in_param
, port
);
2279 __mlx4_unregister_mac(dev
, port
, in_param
);
2290 static int vlan_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2291 u64 in_param
, u64
*out_param
, int port
)
2293 struct mlx4_priv
*priv
= mlx4_priv(dev
);
2294 struct mlx4_slave_state
*slave_state
= priv
->mfunc
.master
.slave_state
;
2297 port
= mlx4_slave_convert_port(
2303 case RES_OP_RESERVE_AND_MAP
:
2304 if (slave_state
[slave
].old_vlan_api
)
2308 vlan_del_from_slave(dev
, slave
, in_param
, port
);
2309 __mlx4_unregister_vlan(dev
, port
, in_param
);
2319 static int counter_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2320 u64 in_param
, u64
*out_param
)
2325 if (op
!= RES_OP_RESERVE
)
2328 index
= get_param_l(&in_param
);
2329 err
= rem_res_range(dev
, slave
, index
, 1, RES_COUNTER
, 0);
2333 __mlx4_counter_free(dev
, index
);
2334 mlx4_release_resource(dev
, slave
, RES_COUNTER
, 1, 0);
2339 static int xrcdn_free_res(struct mlx4_dev
*dev
, int slave
, int op
, int cmd
,
2340 u64 in_param
, u64
*out_param
)
2345 if (op
!= RES_OP_RESERVE
)
2348 xrcdn
= get_param_l(&in_param
);
2349 err
= rem_res_range(dev
, slave
, xrcdn
, 1, RES_XRCD
, 0);
2353 __mlx4_xrcd_free(dev
, xrcdn
);
2358 int mlx4_FREE_RES_wrapper(struct mlx4_dev
*dev
, int slave
,
2359 struct mlx4_vhcr
*vhcr
,
2360 struct mlx4_cmd_mailbox
*inbox
,
2361 struct mlx4_cmd_mailbox
*outbox
,
2362 struct mlx4_cmd_info
*cmd
)
2365 int alop
= vhcr
->op_modifier
;
2367 switch (vhcr
->in_modifier
& 0xFF) {
2369 err
= qp_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2374 err
= mtt_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2375 vhcr
->in_param
, &vhcr
->out_param
);
2379 err
= mpt_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2384 err
= cq_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2385 vhcr
->in_param
, &vhcr
->out_param
);
2389 err
= srq_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2390 vhcr
->in_param
, &vhcr
->out_param
);
2394 err
= mac_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2395 vhcr
->in_param
, &vhcr
->out_param
,
2396 (vhcr
->in_modifier
>> 8) & 0xFF);
2400 err
= vlan_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2401 vhcr
->in_param
, &vhcr
->out_param
,
2402 (vhcr
->in_modifier
>> 8) & 0xFF);
2406 err
= counter_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2407 vhcr
->in_param
, &vhcr
->out_param
);
2411 err
= xrcdn_free_res(dev
, slave
, vhcr
->op_modifier
, alop
,
2412 vhcr
->in_param
, &vhcr
->out_param
);
2420 /* ugly but other choices are uglier */
2421 static int mr_phys_mpt(struct mlx4_mpt_entry
*mpt
)
2423 return (be32_to_cpu(mpt
->flags
) >> 9) & 1;
2426 static int mr_get_mtt_addr(struct mlx4_mpt_entry
*mpt
)
2428 return (int)be64_to_cpu(mpt
->mtt_addr
) & 0xfffffff8;
2431 static int mr_get_mtt_size(struct mlx4_mpt_entry
*mpt
)
2433 return be32_to_cpu(mpt
->mtt_sz
);
2436 static u32
mr_get_pd(struct mlx4_mpt_entry
*mpt
)
2438 return be32_to_cpu(mpt
->pd_flags
) & 0x00ffffff;
2441 static int mr_is_fmr(struct mlx4_mpt_entry
*mpt
)
2443 return be32_to_cpu(mpt
->pd_flags
) & MLX4_MPT_PD_FLAG_FAST_REG
;
2446 static int mr_is_bind_enabled(struct mlx4_mpt_entry
*mpt
)
2448 return be32_to_cpu(mpt
->flags
) & MLX4_MPT_FLAG_BIND_ENABLE
;
2451 static int mr_is_region(struct mlx4_mpt_entry
*mpt
)
2453 return be32_to_cpu(mpt
->flags
) & MLX4_MPT_FLAG_REGION
;
2456 static int qp_get_mtt_addr(struct mlx4_qp_context
*qpc
)
2458 return be32_to_cpu(qpc
->mtt_base_addr_l
) & 0xfffffff8;
2461 static int srq_get_mtt_addr(struct mlx4_srq_context
*srqc
)
2463 return be32_to_cpu(srqc
->mtt_base_addr_l
) & 0xfffffff8;
2466 static int qp_get_mtt_size(struct mlx4_qp_context
*qpc
)
2468 int page_shift
= (qpc
->log_page_size
& 0x3f) + 12;
2469 int log_sq_size
= (qpc
->sq_size_stride
>> 3) & 0xf;
2470 int log_sq_sride
= qpc
->sq_size_stride
& 7;
2471 int log_rq_size
= (qpc
->rq_size_stride
>> 3) & 0xf;
2472 int log_rq_stride
= qpc
->rq_size_stride
& 7;
2473 int srq
= (be32_to_cpu(qpc
->srqn
) >> 24) & 1;
2474 int rss
= (be32_to_cpu(qpc
->flags
) >> 13) & 1;
2475 u32 ts
= (be32_to_cpu(qpc
->flags
) >> 16) & 0xff;
2476 int xrc
= (ts
== MLX4_QP_ST_XRC
) ? 1 : 0;
2481 int page_offset
= (be32_to_cpu(qpc
->params2
) >> 6) & 0x3f;
2483 sq_size
= 1 << (log_sq_size
+ log_sq_sride
+ 4);
2484 rq_size
= (srq
|rss
|xrc
) ? 0 : (1 << (log_rq_size
+ log_rq_stride
+ 4));
2485 total_mem
= sq_size
+ rq_size
;
2487 roundup_pow_of_two((total_mem
+ (page_offset
<< 6)) >>
2493 static int check_mtt_range(struct mlx4_dev
*dev
, int slave
, int start
,
2494 int size
, struct res_mtt
*mtt
)
2496 int res_start
= mtt
->com
.res_id
;
2497 int res_size
= (1 << mtt
->order
);
2499 if (start
< res_start
|| start
+ size
> res_start
+ res_size
)
2504 int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev
*dev
, int slave
,
2505 struct mlx4_vhcr
*vhcr
,
2506 struct mlx4_cmd_mailbox
*inbox
,
2507 struct mlx4_cmd_mailbox
*outbox
,
2508 struct mlx4_cmd_info
*cmd
)
2511 int index
= vhcr
->in_modifier
;
2512 struct res_mtt
*mtt
;
2513 struct res_mpt
*mpt
;
2514 int mtt_base
= mr_get_mtt_addr(inbox
->buf
) / dev
->caps
.mtt_entry_sz
;
2520 id
= index
& mpt_mask(dev
);
2521 err
= mr_res_start_move_to(dev
, slave
, id
, RES_MPT_HW
, &mpt
);
2525 /* Disable memory windows for VFs. */
2526 if (!mr_is_region(inbox
->buf
)) {
2531 /* Make sure that the PD bits related to the slave id are zeros. */
2532 pd
= mr_get_pd(inbox
->buf
);
2533 pd_slave
= (pd
>> 17) & 0x7f;
2534 if (pd_slave
!= 0 && pd_slave
!= slave
) {
2539 if (mr_is_fmr(inbox
->buf
)) {
2540 /* FMR and Bind Enable are forbidden in slave devices. */
2541 if (mr_is_bind_enabled(inbox
->buf
)) {
2545 /* FMR and Memory Windows are also forbidden. */
2546 if (!mr_is_region(inbox
->buf
)) {
2552 phys
= mr_phys_mpt(inbox
->buf
);
2554 err
= get_res(dev
, slave
, mtt_base
, RES_MTT
, &mtt
);
2558 err
= check_mtt_range(dev
, slave
, mtt_base
,
2559 mr_get_mtt_size(inbox
->buf
), mtt
);
2566 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
2571 atomic_inc(&mtt
->ref_count
);
2572 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
2575 res_end_move(dev
, slave
, RES_MPT
, id
);
2580 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
2582 res_abort_move(dev
, slave
, RES_MPT
, id
);
2587 int mlx4_HW2SW_MPT_wrapper(struct mlx4_dev
*dev
, int slave
,
2588 struct mlx4_vhcr
*vhcr
,
2589 struct mlx4_cmd_mailbox
*inbox
,
2590 struct mlx4_cmd_mailbox
*outbox
,
2591 struct mlx4_cmd_info
*cmd
)
2594 int index
= vhcr
->in_modifier
;
2595 struct res_mpt
*mpt
;
2598 id
= index
& mpt_mask(dev
);
2599 err
= mr_res_start_move_to(dev
, slave
, id
, RES_MPT_MAPPED
, &mpt
);
2603 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
2608 atomic_dec(&mpt
->mtt
->ref_count
);
2610 res_end_move(dev
, slave
, RES_MPT
, id
);
2614 res_abort_move(dev
, slave
, RES_MPT
, id
);
2619 int mlx4_QUERY_MPT_wrapper(struct mlx4_dev
*dev
, int slave
,
2620 struct mlx4_vhcr
*vhcr
,
2621 struct mlx4_cmd_mailbox
*inbox
,
2622 struct mlx4_cmd_mailbox
*outbox
,
2623 struct mlx4_cmd_info
*cmd
)
2626 int index
= vhcr
->in_modifier
;
2627 struct res_mpt
*mpt
;
2630 id
= index
& mpt_mask(dev
);
2631 err
= get_res(dev
, slave
, id
, RES_MPT
, &mpt
);
2635 if (mpt
->com
.from_state
== RES_MPT_MAPPED
) {
2636 /* In order to allow rereg in SRIOV, we need to alter the MPT entry. To do
2637 * that, the VF must read the MPT. But since the MPT entry memory is not
2638 * in the VF's virtual memory space, it must use QUERY_MPT to obtain the
2639 * entry contents. To guarantee that the MPT cannot be changed, the driver
2640 * must perform HW2SW_MPT before this query and return the MPT entry to HW
2641 * ownership fofollowing the change. The change here allows the VF to
2642 * perform QUERY_MPT also when the entry is in SW ownership.
2644 struct mlx4_mpt_entry
*mpt_entry
= mlx4_table_find(
2645 &mlx4_priv(dev
)->mr_table
.dmpt_table
,
2648 if (NULL
== mpt_entry
|| NULL
== outbox
->buf
) {
2653 memcpy(outbox
->buf
, mpt_entry
, sizeof(*mpt_entry
));
2656 } else if (mpt
->com
.from_state
== RES_MPT_HW
) {
2657 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
2665 put_res(dev
, slave
, id
, RES_MPT
);
2669 static int qp_get_rcqn(struct mlx4_qp_context
*qpc
)
2671 return be32_to_cpu(qpc
->cqn_recv
) & 0xffffff;
2674 static int qp_get_scqn(struct mlx4_qp_context
*qpc
)
2676 return be32_to_cpu(qpc
->cqn_send
) & 0xffffff;
2679 static u32
qp_get_srqn(struct mlx4_qp_context
*qpc
)
2681 return be32_to_cpu(qpc
->srqn
) & 0x1ffffff;
2684 static void adjust_proxy_tun_qkey(struct mlx4_dev
*dev
, struct mlx4_vhcr
*vhcr
,
2685 struct mlx4_qp_context
*context
)
2687 u32 qpn
= vhcr
->in_modifier
& 0xffffff;
2690 if (mlx4_get_parav_qkey(dev
, qpn
, &qkey
))
2693 /* adjust qkey in qp context */
2694 context
->qkey
= cpu_to_be32(qkey
);
2697 int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
2698 struct mlx4_vhcr
*vhcr
,
2699 struct mlx4_cmd_mailbox
*inbox
,
2700 struct mlx4_cmd_mailbox
*outbox
,
2701 struct mlx4_cmd_info
*cmd
)
2704 int qpn
= vhcr
->in_modifier
& 0x7fffff;
2705 struct res_mtt
*mtt
;
2707 struct mlx4_qp_context
*qpc
= inbox
->buf
+ 8;
2708 int mtt_base
= qp_get_mtt_addr(qpc
) / dev
->caps
.mtt_entry_sz
;
2709 int mtt_size
= qp_get_mtt_size(qpc
);
2712 int rcqn
= qp_get_rcqn(qpc
);
2713 int scqn
= qp_get_scqn(qpc
);
2714 u32 srqn
= qp_get_srqn(qpc
) & 0xffffff;
2715 int use_srq
= (qp_get_srqn(qpc
) >> 24) & 1;
2716 struct res_srq
*srq
;
2717 int local_qpn
= be32_to_cpu(qpc
->local_qpn
) & 0xffffff;
2719 err
= qp_res_start_move_to(dev
, slave
, qpn
, RES_QP_HW
, &qp
, 0);
2722 qp
->local_qpn
= local_qpn
;
2723 qp
->sched_queue
= 0;
2725 qp
->vlan_control
= 0;
2727 qp
->pri_path_fl
= 0;
2730 qp
->qpc_flags
= be32_to_cpu(qpc
->flags
);
2732 err
= get_res(dev
, slave
, mtt_base
, RES_MTT
, &mtt
);
2736 err
= check_mtt_range(dev
, slave
, mtt_base
, mtt_size
, mtt
);
2740 err
= get_res(dev
, slave
, rcqn
, RES_CQ
, &rcq
);
2745 err
= get_res(dev
, slave
, scqn
, RES_CQ
, &scq
);
2752 err
= get_res(dev
, slave
, srqn
, RES_SRQ
, &srq
);
2757 adjust_proxy_tun_qkey(dev
, vhcr
, qpc
);
2758 update_pkey_index(dev
, slave
, inbox
);
2759 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
2762 atomic_inc(&mtt
->ref_count
);
2764 atomic_inc(&rcq
->ref_count
);
2766 atomic_inc(&scq
->ref_count
);
2770 put_res(dev
, slave
, scqn
, RES_CQ
);
2773 atomic_inc(&srq
->ref_count
);
2774 put_res(dev
, slave
, srqn
, RES_SRQ
);
2777 put_res(dev
, slave
, rcqn
, RES_CQ
);
2778 put_res(dev
, slave
, mtt_base
, RES_MTT
);
2779 res_end_move(dev
, slave
, RES_QP
, qpn
);
2785 put_res(dev
, slave
, srqn
, RES_SRQ
);
2788 put_res(dev
, slave
, scqn
, RES_CQ
);
2790 put_res(dev
, slave
, rcqn
, RES_CQ
);
2792 put_res(dev
, slave
, mtt_base
, RES_MTT
);
2794 res_abort_move(dev
, slave
, RES_QP
, qpn
);
2799 static int eq_get_mtt_addr(struct mlx4_eq_context
*eqc
)
2801 return be32_to_cpu(eqc
->mtt_base_addr_l
) & 0xfffffff8;
2804 static int eq_get_mtt_size(struct mlx4_eq_context
*eqc
)
2806 int log_eq_size
= eqc
->log_eq_size
& 0x1f;
2807 int page_shift
= (eqc
->log_page_size
& 0x3f) + 12;
2809 if (log_eq_size
+ 5 < page_shift
)
2812 return 1 << (log_eq_size
+ 5 - page_shift
);
2815 static int cq_get_mtt_addr(struct mlx4_cq_context
*cqc
)
2817 return be32_to_cpu(cqc
->mtt_base_addr_l
) & 0xfffffff8;
2820 static int cq_get_mtt_size(struct mlx4_cq_context
*cqc
)
2822 int log_cq_size
= (be32_to_cpu(cqc
->logsize_usrpage
) >> 24) & 0x1f;
2823 int page_shift
= (cqc
->log_page_size
& 0x3f) + 12;
2825 if (log_cq_size
+ 5 < page_shift
)
2828 return 1 << (log_cq_size
+ 5 - page_shift
);
2831 int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev
*dev
, int slave
,
2832 struct mlx4_vhcr
*vhcr
,
2833 struct mlx4_cmd_mailbox
*inbox
,
2834 struct mlx4_cmd_mailbox
*outbox
,
2835 struct mlx4_cmd_info
*cmd
)
2838 int eqn
= vhcr
->in_modifier
;
2839 int res_id
= (slave
<< 8) | eqn
;
2840 struct mlx4_eq_context
*eqc
= inbox
->buf
;
2841 int mtt_base
= eq_get_mtt_addr(eqc
) / dev
->caps
.mtt_entry_sz
;
2842 int mtt_size
= eq_get_mtt_size(eqc
);
2844 struct res_mtt
*mtt
;
2846 err
= add_res_range(dev
, slave
, res_id
, 1, RES_EQ
, 0);
2849 err
= eq_res_start_move_to(dev
, slave
, res_id
, RES_EQ_HW
, &eq
);
2853 err
= get_res(dev
, slave
, mtt_base
, RES_MTT
, &mtt
);
2857 err
= check_mtt_range(dev
, slave
, mtt_base
, mtt_size
, mtt
);
2861 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
2865 atomic_inc(&mtt
->ref_count
);
2867 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
2868 res_end_move(dev
, slave
, RES_EQ
, res_id
);
2872 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
2874 res_abort_move(dev
, slave
, RES_EQ
, res_id
);
2876 rem_res_range(dev
, slave
, res_id
, 1, RES_EQ
, 0);
2880 int mlx4_CONFIG_DEV_wrapper(struct mlx4_dev
*dev
, int slave
,
2881 struct mlx4_vhcr
*vhcr
,
2882 struct mlx4_cmd_mailbox
*inbox
,
2883 struct mlx4_cmd_mailbox
*outbox
,
2884 struct mlx4_cmd_info
*cmd
)
2887 u8 get
= vhcr
->op_modifier
;
2892 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
2897 static int get_containing_mtt(struct mlx4_dev
*dev
, int slave
, int start
,
2898 int len
, struct res_mtt
**res
)
2900 struct mlx4_priv
*priv
= mlx4_priv(dev
);
2901 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
2902 struct res_mtt
*mtt
;
2905 spin_lock_irq(mlx4_tlock(dev
));
2906 list_for_each_entry(mtt
, &tracker
->slave_list
[slave
].res_list
[RES_MTT
],
2908 if (!check_mtt_range(dev
, slave
, start
, len
, mtt
)) {
2910 mtt
->com
.from_state
= mtt
->com
.state
;
2911 mtt
->com
.state
= RES_MTT_BUSY
;
2916 spin_unlock_irq(mlx4_tlock(dev
));
2921 static int verify_qp_parameters(struct mlx4_dev
*dev
,
2922 struct mlx4_vhcr
*vhcr
,
2923 struct mlx4_cmd_mailbox
*inbox
,
2924 enum qp_transition transition
, u8 slave
)
2928 struct mlx4_qp_context
*qp_ctx
;
2929 enum mlx4_qp_optpar optpar
;
2933 qp_ctx
= inbox
->buf
+ 8;
2934 qp_type
= (be32_to_cpu(qp_ctx
->flags
) >> 16) & 0xff;
2935 optpar
= be32_to_cpu(*(__be32
*) inbox
->buf
);
2939 case MLX4_QP_ST_XRC
:
2941 switch (transition
) {
2942 case QP_TRANS_INIT2RTR
:
2943 case QP_TRANS_RTR2RTS
:
2944 case QP_TRANS_RTS2RTS
:
2945 case QP_TRANS_SQD2SQD
:
2946 case QP_TRANS_SQD2RTS
:
2947 if (slave
!= mlx4_master_func_num(dev
))
2948 if (optpar
& MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH
) {
2949 port
= (qp_ctx
->pri_path
.sched_queue
>> 6 & 1) + 1;
2950 if (dev
->caps
.port_mask
[port
] != MLX4_PORT_TYPE_IB
)
2951 num_gids
= mlx4_get_slave_num_gids(dev
, slave
, port
);
2954 if (qp_ctx
->pri_path
.mgid_index
>= num_gids
)
2957 if (optpar
& MLX4_QP_OPTPAR_ALT_ADDR_PATH
) {
2958 port
= (qp_ctx
->alt_path
.sched_queue
>> 6 & 1) + 1;
2959 if (dev
->caps
.port_mask
[port
] != MLX4_PORT_TYPE_IB
)
2960 num_gids
= mlx4_get_slave_num_gids(dev
, slave
, port
);
2963 if (qp_ctx
->alt_path
.mgid_index
>= num_gids
)
2972 case MLX4_QP_ST_MLX
:
2973 qpn
= vhcr
->in_modifier
& 0x7fffff;
2974 port
= (qp_ctx
->pri_path
.sched_queue
>> 6 & 1) + 1;
2975 if (transition
== QP_TRANS_INIT2RTR
&&
2976 slave
!= mlx4_master_func_num(dev
) &&
2977 mlx4_is_qp_reserved(dev
, qpn
) &&
2978 !mlx4_vf_smi_enabled(dev
, slave
, port
)) {
2979 /* only enabled VFs may create MLX proxy QPs */
2980 mlx4_err(dev
, "%s: unprivileged slave %d attempting to create an MLX proxy special QP on port %d\n",
2981 __func__
, slave
, port
);
2993 int mlx4_WRITE_MTT_wrapper(struct mlx4_dev
*dev
, int slave
,
2994 struct mlx4_vhcr
*vhcr
,
2995 struct mlx4_cmd_mailbox
*inbox
,
2996 struct mlx4_cmd_mailbox
*outbox
,
2997 struct mlx4_cmd_info
*cmd
)
2999 struct mlx4_mtt mtt
;
3000 __be64
*page_list
= inbox
->buf
;
3001 u64
*pg_list
= (u64
*)page_list
;
3003 struct res_mtt
*rmtt
= NULL
;
3004 int start
= be64_to_cpu(page_list
[0]);
3005 int npages
= vhcr
->in_modifier
;
3008 err
= get_containing_mtt(dev
, slave
, start
, npages
, &rmtt
);
3012 /* Call the SW implementation of write_mtt:
3013 * - Prepare a dummy mtt struct
3014 * - Translate inbox contents to simple addresses in host endianess */
3015 mtt
.offset
= 0; /* TBD this is broken but I don't handle it since
3016 we don't really use it */
3019 for (i
= 0; i
< npages
; ++i
)
3020 pg_list
[i
+ 2] = (be64_to_cpu(page_list
[i
+ 2]) & ~1ULL);
3022 err
= __mlx4_write_mtt(dev
, &mtt
, be64_to_cpu(page_list
[0]), npages
,
3023 ((u64
*)page_list
+ 2));
3026 put_res(dev
, slave
, rmtt
->com
.res_id
, RES_MTT
);
3031 int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3032 struct mlx4_vhcr
*vhcr
,
3033 struct mlx4_cmd_mailbox
*inbox
,
3034 struct mlx4_cmd_mailbox
*outbox
,
3035 struct mlx4_cmd_info
*cmd
)
3037 int eqn
= vhcr
->in_modifier
;
3038 int res_id
= eqn
| (slave
<< 8);
3042 err
= eq_res_start_move_to(dev
, slave
, res_id
, RES_EQ_RESERVED
, &eq
);
3046 err
= get_res(dev
, slave
, eq
->mtt
->com
.res_id
, RES_MTT
, NULL
);
3050 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3054 atomic_dec(&eq
->mtt
->ref_count
);
3055 put_res(dev
, slave
, eq
->mtt
->com
.res_id
, RES_MTT
);
3056 res_end_move(dev
, slave
, RES_EQ
, res_id
);
3057 rem_res_range(dev
, slave
, res_id
, 1, RES_EQ
, 0);
3062 put_res(dev
, slave
, eq
->mtt
->com
.res_id
, RES_MTT
);
3064 res_abort_move(dev
, slave
, RES_EQ
, res_id
);
3069 int mlx4_GEN_EQE(struct mlx4_dev
*dev
, int slave
, struct mlx4_eqe
*eqe
)
3071 struct mlx4_priv
*priv
= mlx4_priv(dev
);
3072 struct mlx4_slave_event_eq_info
*event_eq
;
3073 struct mlx4_cmd_mailbox
*mailbox
;
3074 u32 in_modifier
= 0;
3079 if (!priv
->mfunc
.master
.slave_state
)
3082 event_eq
= &priv
->mfunc
.master
.slave_state
[slave
].event_eq
[eqe
->type
];
3084 /* Create the event only if the slave is registered */
3085 if (event_eq
->eqn
< 0)
3088 mutex_lock(&priv
->mfunc
.master
.gen_eqe_mutex
[slave
]);
3089 res_id
= (slave
<< 8) | event_eq
->eqn
;
3090 err
= get_res(dev
, slave
, res_id
, RES_EQ
, &req
);
3094 if (req
->com
.from_state
!= RES_EQ_HW
) {
3099 mailbox
= mlx4_alloc_cmd_mailbox(dev
);
3100 if (IS_ERR(mailbox
)) {
3101 err
= PTR_ERR(mailbox
);
3105 if (eqe
->type
== MLX4_EVENT_TYPE_CMD
) {
3107 eqe
->event
.cmd
.token
= cpu_to_be16(event_eq
->token
);
3110 memcpy(mailbox
->buf
, (u8
*) eqe
, 28);
3112 in_modifier
= (slave
& 0xff) | ((event_eq
->eqn
& 0xff) << 16);
3114 err
= mlx4_cmd(dev
, mailbox
->dma
, in_modifier
, 0,
3115 MLX4_CMD_GEN_EQE
, MLX4_CMD_TIME_CLASS_B
,
3118 put_res(dev
, slave
, res_id
, RES_EQ
);
3119 mutex_unlock(&priv
->mfunc
.master
.gen_eqe_mutex
[slave
]);
3120 mlx4_free_cmd_mailbox(dev
, mailbox
);
3124 put_res(dev
, slave
, res_id
, RES_EQ
);
3127 mutex_unlock(&priv
->mfunc
.master
.gen_eqe_mutex
[slave
]);
3131 int mlx4_QUERY_EQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3132 struct mlx4_vhcr
*vhcr
,
3133 struct mlx4_cmd_mailbox
*inbox
,
3134 struct mlx4_cmd_mailbox
*outbox
,
3135 struct mlx4_cmd_info
*cmd
)
3137 int eqn
= vhcr
->in_modifier
;
3138 int res_id
= eqn
| (slave
<< 8);
3142 err
= get_res(dev
, slave
, res_id
, RES_EQ
, &eq
);
3146 if (eq
->com
.from_state
!= RES_EQ_HW
) {
3151 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3154 put_res(dev
, slave
, res_id
, RES_EQ
);
3158 int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3159 struct mlx4_vhcr
*vhcr
,
3160 struct mlx4_cmd_mailbox
*inbox
,
3161 struct mlx4_cmd_mailbox
*outbox
,
3162 struct mlx4_cmd_info
*cmd
)
3165 int cqn
= vhcr
->in_modifier
;
3166 struct mlx4_cq_context
*cqc
= inbox
->buf
;
3167 int mtt_base
= cq_get_mtt_addr(cqc
) / dev
->caps
.mtt_entry_sz
;
3169 struct res_mtt
*mtt
;
3171 err
= cq_res_start_move_to(dev
, slave
, cqn
, RES_CQ_HW
, &cq
);
3174 err
= get_res(dev
, slave
, mtt_base
, RES_MTT
, &mtt
);
3177 err
= check_mtt_range(dev
, slave
, mtt_base
, cq_get_mtt_size(cqc
), mtt
);
3180 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3183 atomic_inc(&mtt
->ref_count
);
3185 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
3186 res_end_move(dev
, slave
, RES_CQ
, cqn
);
3190 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
3192 res_abort_move(dev
, slave
, RES_CQ
, cqn
);
3196 int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3197 struct mlx4_vhcr
*vhcr
,
3198 struct mlx4_cmd_mailbox
*inbox
,
3199 struct mlx4_cmd_mailbox
*outbox
,
3200 struct mlx4_cmd_info
*cmd
)
3203 int cqn
= vhcr
->in_modifier
;
3206 err
= cq_res_start_move_to(dev
, slave
, cqn
, RES_CQ_ALLOCATED
, &cq
);
3209 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3212 atomic_dec(&cq
->mtt
->ref_count
);
3213 res_end_move(dev
, slave
, RES_CQ
, cqn
);
3217 res_abort_move(dev
, slave
, RES_CQ
, cqn
);
3221 int mlx4_QUERY_CQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3222 struct mlx4_vhcr
*vhcr
,
3223 struct mlx4_cmd_mailbox
*inbox
,
3224 struct mlx4_cmd_mailbox
*outbox
,
3225 struct mlx4_cmd_info
*cmd
)
3227 int cqn
= vhcr
->in_modifier
;
3231 err
= get_res(dev
, slave
, cqn
, RES_CQ
, &cq
);
3235 if (cq
->com
.from_state
!= RES_CQ_HW
)
3238 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3240 put_res(dev
, slave
, cqn
, RES_CQ
);
3245 static int handle_resize(struct mlx4_dev
*dev
, int slave
,
3246 struct mlx4_vhcr
*vhcr
,
3247 struct mlx4_cmd_mailbox
*inbox
,
3248 struct mlx4_cmd_mailbox
*outbox
,
3249 struct mlx4_cmd_info
*cmd
,
3253 struct res_mtt
*orig_mtt
;
3254 struct res_mtt
*mtt
;
3255 struct mlx4_cq_context
*cqc
= inbox
->buf
;
3256 int mtt_base
= cq_get_mtt_addr(cqc
) / dev
->caps
.mtt_entry_sz
;
3258 err
= get_res(dev
, slave
, cq
->mtt
->com
.res_id
, RES_MTT
, &orig_mtt
);
3262 if (orig_mtt
!= cq
->mtt
) {
3267 err
= get_res(dev
, slave
, mtt_base
, RES_MTT
, &mtt
);
3271 err
= check_mtt_range(dev
, slave
, mtt_base
, cq_get_mtt_size(cqc
), mtt
);
3274 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3277 atomic_dec(&orig_mtt
->ref_count
);
3278 put_res(dev
, slave
, orig_mtt
->com
.res_id
, RES_MTT
);
3279 atomic_inc(&mtt
->ref_count
);
3281 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
3285 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
3287 put_res(dev
, slave
, orig_mtt
->com
.res_id
, RES_MTT
);
3293 int mlx4_MODIFY_CQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3294 struct mlx4_vhcr
*vhcr
,
3295 struct mlx4_cmd_mailbox
*inbox
,
3296 struct mlx4_cmd_mailbox
*outbox
,
3297 struct mlx4_cmd_info
*cmd
)
3299 int cqn
= vhcr
->in_modifier
;
3303 err
= get_res(dev
, slave
, cqn
, RES_CQ
, &cq
);
3307 if (cq
->com
.from_state
!= RES_CQ_HW
)
3310 if (vhcr
->op_modifier
== 0) {
3311 err
= handle_resize(dev
, slave
, vhcr
, inbox
, outbox
, cmd
, cq
);
3315 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3317 put_res(dev
, slave
, cqn
, RES_CQ
);
3322 static int srq_get_mtt_size(struct mlx4_srq_context
*srqc
)
3324 int log_srq_size
= (be32_to_cpu(srqc
->state_logsize_srqn
) >> 24) & 0xf;
3325 int log_rq_stride
= srqc
->logstride
& 7;
3326 int page_shift
= (srqc
->log_page_size
& 0x3f) + 12;
3328 if (log_srq_size
+ log_rq_stride
+ 4 < page_shift
)
3331 return 1 << (log_srq_size
+ log_rq_stride
+ 4 - page_shift
);
3334 int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3335 struct mlx4_vhcr
*vhcr
,
3336 struct mlx4_cmd_mailbox
*inbox
,
3337 struct mlx4_cmd_mailbox
*outbox
,
3338 struct mlx4_cmd_info
*cmd
)
3341 int srqn
= vhcr
->in_modifier
;
3342 struct res_mtt
*mtt
;
3343 struct res_srq
*srq
;
3344 struct mlx4_srq_context
*srqc
= inbox
->buf
;
3345 int mtt_base
= srq_get_mtt_addr(srqc
) / dev
->caps
.mtt_entry_sz
;
3347 if (srqn
!= (be32_to_cpu(srqc
->state_logsize_srqn
) & 0xffffff))
3350 err
= srq_res_start_move_to(dev
, slave
, srqn
, RES_SRQ_HW
, &srq
);
3353 err
= get_res(dev
, slave
, mtt_base
, RES_MTT
, &mtt
);
3356 err
= check_mtt_range(dev
, slave
, mtt_base
, srq_get_mtt_size(srqc
),
3361 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3365 atomic_inc(&mtt
->ref_count
);
3367 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
3368 res_end_move(dev
, slave
, RES_SRQ
, srqn
);
3372 put_res(dev
, slave
, mtt
->com
.res_id
, RES_MTT
);
3374 res_abort_move(dev
, slave
, RES_SRQ
, srqn
);
3379 int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3380 struct mlx4_vhcr
*vhcr
,
3381 struct mlx4_cmd_mailbox
*inbox
,
3382 struct mlx4_cmd_mailbox
*outbox
,
3383 struct mlx4_cmd_info
*cmd
)
3386 int srqn
= vhcr
->in_modifier
;
3387 struct res_srq
*srq
;
3389 err
= srq_res_start_move_to(dev
, slave
, srqn
, RES_SRQ_ALLOCATED
, &srq
);
3392 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3395 atomic_dec(&srq
->mtt
->ref_count
);
3397 atomic_dec(&srq
->cq
->ref_count
);
3398 res_end_move(dev
, slave
, RES_SRQ
, srqn
);
3403 res_abort_move(dev
, slave
, RES_SRQ
, srqn
);
3408 int mlx4_QUERY_SRQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3409 struct mlx4_vhcr
*vhcr
,
3410 struct mlx4_cmd_mailbox
*inbox
,
3411 struct mlx4_cmd_mailbox
*outbox
,
3412 struct mlx4_cmd_info
*cmd
)
3415 int srqn
= vhcr
->in_modifier
;
3416 struct res_srq
*srq
;
3418 err
= get_res(dev
, slave
, srqn
, RES_SRQ
, &srq
);
3421 if (srq
->com
.from_state
!= RES_SRQ_HW
) {
3425 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3427 put_res(dev
, slave
, srqn
, RES_SRQ
);
3431 int mlx4_ARM_SRQ_wrapper(struct mlx4_dev
*dev
, int slave
,
3432 struct mlx4_vhcr
*vhcr
,
3433 struct mlx4_cmd_mailbox
*inbox
,
3434 struct mlx4_cmd_mailbox
*outbox
,
3435 struct mlx4_cmd_info
*cmd
)
3438 int srqn
= vhcr
->in_modifier
;
3439 struct res_srq
*srq
;
3441 err
= get_res(dev
, slave
, srqn
, RES_SRQ
, &srq
);
3445 if (srq
->com
.from_state
!= RES_SRQ_HW
) {
3450 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3452 put_res(dev
, slave
, srqn
, RES_SRQ
);
3456 int mlx4_GEN_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3457 struct mlx4_vhcr
*vhcr
,
3458 struct mlx4_cmd_mailbox
*inbox
,
3459 struct mlx4_cmd_mailbox
*outbox
,
3460 struct mlx4_cmd_info
*cmd
)
3463 int qpn
= vhcr
->in_modifier
& 0x7fffff;
3466 err
= get_res(dev
, slave
, qpn
, RES_QP
, &qp
);
3469 if (qp
->com
.from_state
!= RES_QP_HW
) {
3474 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3476 put_res(dev
, slave
, qpn
, RES_QP
);
3480 int mlx4_INIT2INIT_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3481 struct mlx4_vhcr
*vhcr
,
3482 struct mlx4_cmd_mailbox
*inbox
,
3483 struct mlx4_cmd_mailbox
*outbox
,
3484 struct mlx4_cmd_info
*cmd
)
3486 struct mlx4_qp_context
*context
= inbox
->buf
+ 8;
3487 adjust_proxy_tun_qkey(dev
, vhcr
, context
);
3488 update_pkey_index(dev
, slave
, inbox
);
3489 return mlx4_GEN_QP_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3492 static int adjust_qp_sched_queue(struct mlx4_dev
*dev
, int slave
,
3493 struct mlx4_qp_context
*qpc
,
3494 struct mlx4_cmd_mailbox
*inbox
)
3496 enum mlx4_qp_optpar optpar
= be32_to_cpu(*(__be32
*)inbox
->buf
);
3498 int port
= mlx4_slave_convert_port(
3499 dev
, slave
, (qpc
->pri_path
.sched_queue
>> 6 & 1) + 1) - 1;
3504 pri_sched_queue
= (qpc
->pri_path
.sched_queue
& ~(1 << 6)) |
3507 if (optpar
& MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH
||
3508 mlx4_is_eth(dev
, port
+ 1)) {
3509 qpc
->pri_path
.sched_queue
= pri_sched_queue
;
3512 if (optpar
& MLX4_QP_OPTPAR_ALT_ADDR_PATH
) {
3513 port
= mlx4_slave_convert_port(
3514 dev
, slave
, (qpc
->alt_path
.sched_queue
>> 6 & 1)
3518 qpc
->alt_path
.sched_queue
=
3519 (qpc
->alt_path
.sched_queue
& ~(1 << 6)) |
3525 static int roce_verify_mac(struct mlx4_dev
*dev
, int slave
,
3526 struct mlx4_qp_context
*qpc
,
3527 struct mlx4_cmd_mailbox
*inbox
)
3531 u32 ts
= (be32_to_cpu(qpc
->flags
) >> 16) & 0xff;
3532 u8 sched
= *(u8
*)(inbox
->buf
+ 64);
3535 port
= (sched
>> 6 & 1) + 1;
3536 if (mlx4_is_eth(dev
, port
) && (ts
!= MLX4_QP_ST_MLX
)) {
3537 smac_ix
= qpc
->pri_path
.grh_mylmc
& 0x7f;
3538 if (mac_find_smac_ix_in_slave(dev
, slave
, port
, smac_ix
, &mac
))
3544 int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3545 struct mlx4_vhcr
*vhcr
,
3546 struct mlx4_cmd_mailbox
*inbox
,
3547 struct mlx4_cmd_mailbox
*outbox
,
3548 struct mlx4_cmd_info
*cmd
)
3551 struct mlx4_qp_context
*qpc
= inbox
->buf
+ 8;
3552 int qpn
= vhcr
->in_modifier
& 0x7fffff;
3554 u8 orig_sched_queue
;
3555 __be32 orig_param3
= qpc
->param3
;
3556 u8 orig_vlan_control
= qpc
->pri_path
.vlan_control
;
3557 u8 orig_fvl_rx
= qpc
->pri_path
.fvl_rx
;
3558 u8 orig_pri_path_fl
= qpc
->pri_path
.fl
;
3559 u8 orig_vlan_index
= qpc
->pri_path
.vlan_index
;
3560 u8 orig_feup
= qpc
->pri_path
.feup
;
3562 err
= adjust_qp_sched_queue(dev
, slave
, qpc
, inbox
);
3565 err
= verify_qp_parameters(dev
, vhcr
, inbox
, QP_TRANS_INIT2RTR
, slave
);
3569 if (roce_verify_mac(dev
, slave
, qpc
, inbox
))
3572 update_pkey_index(dev
, slave
, inbox
);
3573 update_gid(dev
, inbox
, (u8
)slave
);
3574 adjust_proxy_tun_qkey(dev
, vhcr
, qpc
);
3575 orig_sched_queue
= qpc
->pri_path
.sched_queue
;
3576 err
= update_vport_qp_param(dev
, inbox
, slave
, qpn
);
3580 err
= get_res(dev
, slave
, qpn
, RES_QP
, &qp
);
3583 if (qp
->com
.from_state
!= RES_QP_HW
) {
3588 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3590 /* if no error, save sched queue value passed in by VF. This is
3591 * essentially the QOS value provided by the VF. This will be useful
3592 * if we allow dynamic changes from VST back to VGT
3595 qp
->sched_queue
= orig_sched_queue
;
3596 qp
->param3
= orig_param3
;
3597 qp
->vlan_control
= orig_vlan_control
;
3598 qp
->fvl_rx
= orig_fvl_rx
;
3599 qp
->pri_path_fl
= orig_pri_path_fl
;
3600 qp
->vlan_index
= orig_vlan_index
;
3601 qp
->feup
= orig_feup
;
3603 put_res(dev
, slave
, qpn
, RES_QP
);
3607 int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3608 struct mlx4_vhcr
*vhcr
,
3609 struct mlx4_cmd_mailbox
*inbox
,
3610 struct mlx4_cmd_mailbox
*outbox
,
3611 struct mlx4_cmd_info
*cmd
)
3614 struct mlx4_qp_context
*context
= inbox
->buf
+ 8;
3616 err
= adjust_qp_sched_queue(dev
, slave
, context
, inbox
);
3619 err
= verify_qp_parameters(dev
, vhcr
, inbox
, QP_TRANS_RTR2RTS
, slave
);
3623 update_pkey_index(dev
, slave
, inbox
);
3624 update_gid(dev
, inbox
, (u8
)slave
);
3625 adjust_proxy_tun_qkey(dev
, vhcr
, context
);
3626 return mlx4_GEN_QP_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3629 int mlx4_RTS2RTS_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3630 struct mlx4_vhcr
*vhcr
,
3631 struct mlx4_cmd_mailbox
*inbox
,
3632 struct mlx4_cmd_mailbox
*outbox
,
3633 struct mlx4_cmd_info
*cmd
)
3636 struct mlx4_qp_context
*context
= inbox
->buf
+ 8;
3638 err
= adjust_qp_sched_queue(dev
, slave
, context
, inbox
);
3641 err
= verify_qp_parameters(dev
, vhcr
, inbox
, QP_TRANS_RTS2RTS
, slave
);
3645 update_pkey_index(dev
, slave
, inbox
);
3646 update_gid(dev
, inbox
, (u8
)slave
);
3647 adjust_proxy_tun_qkey(dev
, vhcr
, context
);
3648 return mlx4_GEN_QP_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3652 int mlx4_SQERR2RTS_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3653 struct mlx4_vhcr
*vhcr
,
3654 struct mlx4_cmd_mailbox
*inbox
,
3655 struct mlx4_cmd_mailbox
*outbox
,
3656 struct mlx4_cmd_info
*cmd
)
3658 struct mlx4_qp_context
*context
= inbox
->buf
+ 8;
3659 int err
= adjust_qp_sched_queue(dev
, slave
, context
, inbox
);
3662 adjust_proxy_tun_qkey(dev
, vhcr
, context
);
3663 return mlx4_GEN_QP_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3666 int mlx4_SQD2SQD_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3667 struct mlx4_vhcr
*vhcr
,
3668 struct mlx4_cmd_mailbox
*inbox
,
3669 struct mlx4_cmd_mailbox
*outbox
,
3670 struct mlx4_cmd_info
*cmd
)
3673 struct mlx4_qp_context
*context
= inbox
->buf
+ 8;
3675 err
= adjust_qp_sched_queue(dev
, slave
, context
, inbox
);
3678 err
= verify_qp_parameters(dev
, vhcr
, inbox
, QP_TRANS_SQD2SQD
, slave
);
3682 adjust_proxy_tun_qkey(dev
, vhcr
, context
);
3683 update_gid(dev
, inbox
, (u8
)slave
);
3684 update_pkey_index(dev
, slave
, inbox
);
3685 return mlx4_GEN_QP_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3688 int mlx4_SQD2RTS_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3689 struct mlx4_vhcr
*vhcr
,
3690 struct mlx4_cmd_mailbox
*inbox
,
3691 struct mlx4_cmd_mailbox
*outbox
,
3692 struct mlx4_cmd_info
*cmd
)
3695 struct mlx4_qp_context
*context
= inbox
->buf
+ 8;
3697 err
= adjust_qp_sched_queue(dev
, slave
, context
, inbox
);
3700 err
= verify_qp_parameters(dev
, vhcr
, inbox
, QP_TRANS_SQD2RTS
, slave
);
3704 adjust_proxy_tun_qkey(dev
, vhcr
, context
);
3705 update_gid(dev
, inbox
, (u8
)slave
);
3706 update_pkey_index(dev
, slave
, inbox
);
3707 return mlx4_GEN_QP_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3710 int mlx4_2RST_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
3711 struct mlx4_vhcr
*vhcr
,
3712 struct mlx4_cmd_mailbox
*inbox
,
3713 struct mlx4_cmd_mailbox
*outbox
,
3714 struct mlx4_cmd_info
*cmd
)
3717 int qpn
= vhcr
->in_modifier
& 0x7fffff;
3720 err
= qp_res_start_move_to(dev
, slave
, qpn
, RES_QP_MAPPED
, &qp
, 0);
3723 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
3727 atomic_dec(&qp
->mtt
->ref_count
);
3728 atomic_dec(&qp
->rcq
->ref_count
);
3729 atomic_dec(&qp
->scq
->ref_count
);
3731 atomic_dec(&qp
->srq
->ref_count
);
3732 res_end_move(dev
, slave
, RES_QP
, qpn
);
3736 res_abort_move(dev
, slave
, RES_QP
, qpn
);
3741 static struct res_gid
*find_gid(struct mlx4_dev
*dev
, int slave
,
3742 struct res_qp
*rqp
, u8
*gid
)
3744 struct res_gid
*res
;
3746 list_for_each_entry(res
, &rqp
->mcg_list
, list
) {
3747 if (!memcmp(res
->gid
, gid
, 16))
3753 static int add_mcg_res(struct mlx4_dev
*dev
, int slave
, struct res_qp
*rqp
,
3754 u8
*gid
, enum mlx4_protocol prot
,
3755 enum mlx4_steer_type steer
, u64 reg_id
)
3757 struct res_gid
*res
;
3760 res
= kzalloc(sizeof *res
, GFP_KERNEL
);
3764 spin_lock_irq(&rqp
->mcg_spl
);
3765 if (find_gid(dev
, slave
, rqp
, gid
)) {
3769 memcpy(res
->gid
, gid
, 16);
3772 res
->reg_id
= reg_id
;
3773 list_add_tail(&res
->list
, &rqp
->mcg_list
);
3776 spin_unlock_irq(&rqp
->mcg_spl
);
3781 static int rem_mcg_res(struct mlx4_dev
*dev
, int slave
, struct res_qp
*rqp
,
3782 u8
*gid
, enum mlx4_protocol prot
,
3783 enum mlx4_steer_type steer
, u64
*reg_id
)
3785 struct res_gid
*res
;
3788 spin_lock_irq(&rqp
->mcg_spl
);
3789 res
= find_gid(dev
, slave
, rqp
, gid
);
3790 if (!res
|| res
->prot
!= prot
|| res
->steer
!= steer
)
3793 *reg_id
= res
->reg_id
;
3794 list_del(&res
->list
);
3798 spin_unlock_irq(&rqp
->mcg_spl
);
3803 static int qp_attach(struct mlx4_dev
*dev
, int slave
, struct mlx4_qp
*qp
,
3804 u8 gid
[16], int block_loopback
, enum mlx4_protocol prot
,
3805 enum mlx4_steer_type type
, u64
*reg_id
)
3807 switch (dev
->caps
.steering_mode
) {
3808 case MLX4_STEERING_MODE_DEVICE_MANAGED
: {
3809 int port
= mlx4_slave_convert_port(dev
, slave
, gid
[5]);
3812 return mlx4_trans_to_dmfs_attach(dev
, qp
, gid
, port
,
3813 block_loopback
, prot
,
3816 case MLX4_STEERING_MODE_B0
:
3817 if (prot
== MLX4_PROT_ETH
) {
3818 int port
= mlx4_slave_convert_port(dev
, slave
, gid
[5]);
3823 return mlx4_qp_attach_common(dev
, qp
, gid
,
3824 block_loopback
, prot
, type
);
3830 static int qp_detach(struct mlx4_dev
*dev
, struct mlx4_qp
*qp
,
3831 u8 gid
[16], enum mlx4_protocol prot
,
3832 enum mlx4_steer_type type
, u64 reg_id
)
3834 switch (dev
->caps
.steering_mode
) {
3835 case MLX4_STEERING_MODE_DEVICE_MANAGED
:
3836 return mlx4_flow_detach(dev
, reg_id
);
3837 case MLX4_STEERING_MODE_B0
:
3838 return mlx4_qp_detach_common(dev
, qp
, gid
, prot
, type
);
3844 static int mlx4_adjust_port(struct mlx4_dev
*dev
, int slave
,
3845 u8
*gid
, enum mlx4_protocol prot
)
3849 if (prot
!= MLX4_PROT_ETH
)
3852 if (dev
->caps
.steering_mode
== MLX4_STEERING_MODE_B0
||
3853 dev
->caps
.steering_mode
== MLX4_STEERING_MODE_DEVICE_MANAGED
) {
3854 real_port
= mlx4_slave_convert_port(dev
, slave
, gid
[5]);
3863 int mlx4_QP_ATTACH_wrapper(struct mlx4_dev
*dev
, int slave
,
3864 struct mlx4_vhcr
*vhcr
,
3865 struct mlx4_cmd_mailbox
*inbox
,
3866 struct mlx4_cmd_mailbox
*outbox
,
3867 struct mlx4_cmd_info
*cmd
)
3869 struct mlx4_qp qp
; /* dummy for calling attach/detach */
3870 u8
*gid
= inbox
->buf
;
3871 enum mlx4_protocol prot
= (vhcr
->in_modifier
>> 28) & 0x7;
3876 int attach
= vhcr
->op_modifier
;
3877 int block_loopback
= vhcr
->in_modifier
>> 31;
3878 u8 steer_type_mask
= 2;
3879 enum mlx4_steer_type type
= (gid
[7] & steer_type_mask
) >> 1;
3881 qpn
= vhcr
->in_modifier
& 0xffffff;
3882 err
= get_res(dev
, slave
, qpn
, RES_QP
, &rqp
);
3888 err
= qp_attach(dev
, slave
, &qp
, gid
, block_loopback
, prot
,
3891 pr_err("Fail to attach rule to qp 0x%x\n", qpn
);
3894 err
= add_mcg_res(dev
, slave
, rqp
, gid
, prot
, type
, reg_id
);
3898 err
= mlx4_adjust_port(dev
, slave
, gid
, prot
);
3902 err
= rem_mcg_res(dev
, slave
, rqp
, gid
, prot
, type
, ®_id
);
3906 err
= qp_detach(dev
, &qp
, gid
, prot
, type
, reg_id
);
3908 pr_err("Fail to detach rule from qp 0x%x reg_id = 0x%llx\n",
3911 put_res(dev
, slave
, qpn
, RES_QP
);
3915 qp_detach(dev
, &qp
, gid
, prot
, type
, reg_id
);
3917 put_res(dev
, slave
, qpn
, RES_QP
);
3922 * MAC validation for Flow Steering rules.
3923 * VF can attach rules only with a mac address which is assigned to it.
3925 static int validate_eth_header_mac(int slave
, struct _rule_hw
*eth_header
,
3926 struct list_head
*rlist
)
3928 struct mac_res
*res
, *tmp
;
3931 /* make sure it isn't multicast or broadcast mac*/
3932 if (!is_multicast_ether_addr(eth_header
->eth
.dst_mac
) &&
3933 !is_broadcast_ether_addr(eth_header
->eth
.dst_mac
)) {
3934 list_for_each_entry_safe(res
, tmp
, rlist
, list
) {
3935 be_mac
= cpu_to_be64(res
->mac
<< 16);
3936 if (ether_addr_equal((u8
*)&be_mac
, eth_header
->eth
.dst_mac
))
3939 pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n",
3940 eth_header
->eth
.dst_mac
, slave
);
3947 * In case of missing eth header, append eth header with a MAC address
3948 * assigned to the VF.
3950 static int add_eth_header(struct mlx4_dev
*dev
, int slave
,
3951 struct mlx4_cmd_mailbox
*inbox
,
3952 struct list_head
*rlist
, int header_id
)
3954 struct mac_res
*res
, *tmp
;
3956 struct mlx4_net_trans_rule_hw_ctrl
*ctrl
;
3957 struct mlx4_net_trans_rule_hw_eth
*eth_header
;
3958 struct mlx4_net_trans_rule_hw_ipv4
*ip_header
;
3959 struct mlx4_net_trans_rule_hw_tcp_udp
*l4_header
;
3961 __be64 mac_msk
= cpu_to_be64(MLX4_MAC_MASK
<< 16);
3963 ctrl
= (struct mlx4_net_trans_rule_hw_ctrl
*)inbox
->buf
;
3965 eth_header
= (struct mlx4_net_trans_rule_hw_eth
*)(ctrl
+ 1);
3967 /* Clear a space in the inbox for eth header */
3968 switch (header_id
) {
3969 case MLX4_NET_TRANS_RULE_ID_IPV4
:
3971 (struct mlx4_net_trans_rule_hw_ipv4
*)(eth_header
+ 1);
3972 memmove(ip_header
, eth_header
,
3973 sizeof(*ip_header
) + sizeof(*l4_header
));
3975 case MLX4_NET_TRANS_RULE_ID_TCP
:
3976 case MLX4_NET_TRANS_RULE_ID_UDP
:
3977 l4_header
= (struct mlx4_net_trans_rule_hw_tcp_udp
*)
3979 memmove(l4_header
, eth_header
, sizeof(*l4_header
));
3984 list_for_each_entry_safe(res
, tmp
, rlist
, list
) {
3985 if (port
== res
->port
) {
3986 be_mac
= cpu_to_be64(res
->mac
<< 16);
3991 pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d\n",
3996 memset(eth_header
, 0, sizeof(*eth_header
));
3997 eth_header
->size
= sizeof(*eth_header
) >> 2;
3998 eth_header
->id
= cpu_to_be16(__sw_id_hw
[MLX4_NET_TRANS_RULE_ID_ETH
]);
3999 memcpy(eth_header
->dst_mac
, &be_mac
, ETH_ALEN
);
4000 memcpy(eth_header
->dst_mac_msk
, &mac_msk
, ETH_ALEN
);
4006 #define MLX4_UPD_QP_PATH_MASK_SUPPORTED (1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX)
4007 int mlx4_UPDATE_QP_wrapper(struct mlx4_dev
*dev
, int slave
,
4008 struct mlx4_vhcr
*vhcr
,
4009 struct mlx4_cmd_mailbox
*inbox
,
4010 struct mlx4_cmd_mailbox
*outbox
,
4011 struct mlx4_cmd_info
*cmd_info
)
4014 u32 qpn
= vhcr
->in_modifier
& 0xffffff;
4018 u64 pri_addr_path_mask
;
4019 struct mlx4_update_qp_context
*cmd
;
4022 cmd
= (struct mlx4_update_qp_context
*)inbox
->buf
;
4024 pri_addr_path_mask
= be64_to_cpu(cmd
->primary_addr_path_mask
);
4025 if (cmd
->qp_mask
|| cmd
->secondary_addr_path_mask
||
4026 (pri_addr_path_mask
& ~MLX4_UPD_QP_PATH_MASK_SUPPORTED
))
4029 /* Just change the smac for the QP */
4030 err
= get_res(dev
, slave
, qpn
, RES_QP
, &rqp
);
4032 mlx4_err(dev
, "Updating qpn 0x%x for slave %d rejected\n", qpn
, slave
);
4036 port
= (rqp
->sched_queue
>> 6 & 1) + 1;
4038 if (pri_addr_path_mask
& (1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX
)) {
4039 smac_index
= cmd
->qp_context
.pri_path
.grh_mylmc
;
4040 err
= mac_find_smac_ix_in_slave(dev
, slave
, port
,
4044 mlx4_err(dev
, "Failed to update qpn 0x%x, MAC is invalid. smac_ix: %d\n",
4050 err
= mlx4_cmd(dev
, inbox
->dma
,
4051 vhcr
->in_modifier
, 0,
4052 MLX4_CMD_UPDATE_QP
, MLX4_CMD_TIME_CLASS_A
,
4055 mlx4_err(dev
, "Failed to update qpn on qpn 0x%x, command failed\n", qpn
);
4060 put_res(dev
, slave
, qpn
, RES_QP
);
4064 int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev
*dev
, int slave
,
4065 struct mlx4_vhcr
*vhcr
,
4066 struct mlx4_cmd_mailbox
*inbox
,
4067 struct mlx4_cmd_mailbox
*outbox
,
4068 struct mlx4_cmd_info
*cmd
)
4071 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4072 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4073 struct list_head
*rlist
= &tracker
->slave_list
[slave
].res_list
[RES_MAC
];
4077 struct mlx4_net_trans_rule_hw_ctrl
*ctrl
;
4078 struct _rule_hw
*rule_header
;
4081 if (dev
->caps
.steering_mode
!=
4082 MLX4_STEERING_MODE_DEVICE_MANAGED
)
4085 ctrl
= (struct mlx4_net_trans_rule_hw_ctrl
*)inbox
->buf
;
4086 ctrl
->port
= mlx4_slave_convert_port(dev
, slave
, ctrl
->port
);
4087 if (ctrl
->port
<= 0)
4089 qpn
= be32_to_cpu(ctrl
->qpn
) & 0xffffff;
4090 err
= get_res(dev
, slave
, qpn
, RES_QP
, &rqp
);
4092 pr_err("Steering rule with qpn 0x%x rejected\n", qpn
);
4095 rule_header
= (struct _rule_hw
*)(ctrl
+ 1);
4096 header_id
= map_hw_to_sw_id(be16_to_cpu(rule_header
->id
));
4098 switch (header_id
) {
4099 case MLX4_NET_TRANS_RULE_ID_ETH
:
4100 if (validate_eth_header_mac(slave
, rule_header
, rlist
)) {
4105 case MLX4_NET_TRANS_RULE_ID_IB
:
4107 case MLX4_NET_TRANS_RULE_ID_IPV4
:
4108 case MLX4_NET_TRANS_RULE_ID_TCP
:
4109 case MLX4_NET_TRANS_RULE_ID_UDP
:
4110 pr_warn("Can't attach FS rule without L2 headers, adding L2 header\n");
4111 if (add_eth_header(dev
, slave
, inbox
, rlist
, header_id
)) {
4115 vhcr
->in_modifier
+=
4116 sizeof(struct mlx4_net_trans_rule_hw_eth
) >> 2;
4119 pr_err("Corrupted mailbox\n");
4124 err
= mlx4_cmd_imm(dev
, inbox
->dma
, &vhcr
->out_param
,
4125 vhcr
->in_modifier
, 0,
4126 MLX4_QP_FLOW_STEERING_ATTACH
, MLX4_CMD_TIME_CLASS_A
,
4131 err
= add_res_range(dev
, slave
, vhcr
->out_param
, 1, RES_FS_RULE
, qpn
);
4133 mlx4_err(dev
, "Fail to add flow steering resources\n");
4135 mlx4_cmd(dev
, vhcr
->out_param
, 0, 0,
4136 MLX4_QP_FLOW_STEERING_DETACH
, MLX4_CMD_TIME_CLASS_A
,
4140 atomic_inc(&rqp
->ref_count
);
4142 put_res(dev
, slave
, qpn
, RES_QP
);
4146 int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev
*dev
, int slave
,
4147 struct mlx4_vhcr
*vhcr
,
4148 struct mlx4_cmd_mailbox
*inbox
,
4149 struct mlx4_cmd_mailbox
*outbox
,
4150 struct mlx4_cmd_info
*cmd
)
4154 struct res_fs_rule
*rrule
;
4156 if (dev
->caps
.steering_mode
!=
4157 MLX4_STEERING_MODE_DEVICE_MANAGED
)
4160 err
= get_res(dev
, slave
, vhcr
->in_param
, RES_FS_RULE
, &rrule
);
4163 /* Release the rule form busy state before removal */
4164 put_res(dev
, slave
, vhcr
->in_param
, RES_FS_RULE
);
4165 err
= get_res(dev
, slave
, rrule
->qpn
, RES_QP
, &rqp
);
4169 err
= rem_res_range(dev
, slave
, vhcr
->in_param
, 1, RES_FS_RULE
, 0);
4171 mlx4_err(dev
, "Fail to remove flow steering resources\n");
4175 err
= mlx4_cmd(dev
, vhcr
->in_param
, 0, 0,
4176 MLX4_QP_FLOW_STEERING_DETACH
, MLX4_CMD_TIME_CLASS_A
,
4179 atomic_dec(&rqp
->ref_count
);
4181 put_res(dev
, slave
, rrule
->qpn
, RES_QP
);
4186 BUSY_MAX_RETRIES
= 10
4189 int mlx4_QUERY_IF_STAT_wrapper(struct mlx4_dev
*dev
, int slave
,
4190 struct mlx4_vhcr
*vhcr
,
4191 struct mlx4_cmd_mailbox
*inbox
,
4192 struct mlx4_cmd_mailbox
*outbox
,
4193 struct mlx4_cmd_info
*cmd
)
4196 int index
= vhcr
->in_modifier
& 0xffff;
4198 err
= get_res(dev
, slave
, index
, RES_COUNTER
, NULL
);
4202 err
= mlx4_DMA_wrapper(dev
, slave
, vhcr
, inbox
, outbox
, cmd
);
4203 put_res(dev
, slave
, index
, RES_COUNTER
);
4207 static void detach_qp(struct mlx4_dev
*dev
, int slave
, struct res_qp
*rqp
)
4209 struct res_gid
*rgid
;
4210 struct res_gid
*tmp
;
4211 struct mlx4_qp qp
; /* dummy for calling attach/detach */
4213 list_for_each_entry_safe(rgid
, tmp
, &rqp
->mcg_list
, list
) {
4214 switch (dev
->caps
.steering_mode
) {
4215 case MLX4_STEERING_MODE_DEVICE_MANAGED
:
4216 mlx4_flow_detach(dev
, rgid
->reg_id
);
4218 case MLX4_STEERING_MODE_B0
:
4219 qp
.qpn
= rqp
->local_qpn
;
4220 (void) mlx4_qp_detach_common(dev
, &qp
, rgid
->gid
,
4221 rgid
->prot
, rgid
->steer
);
4224 list_del(&rgid
->list
);
4229 static int _move_all_busy(struct mlx4_dev
*dev
, int slave
,
4230 enum mlx4_resource type
, int print
)
4232 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4233 struct mlx4_resource_tracker
*tracker
=
4234 &priv
->mfunc
.master
.res_tracker
;
4235 struct list_head
*rlist
= &tracker
->slave_list
[slave
].res_list
[type
];
4236 struct res_common
*r
;
4237 struct res_common
*tmp
;
4241 spin_lock_irq(mlx4_tlock(dev
));
4242 list_for_each_entry_safe(r
, tmp
, rlist
, list
) {
4243 if (r
->owner
== slave
) {
4245 if (r
->state
== RES_ANY_BUSY
) {
4248 "%s id 0x%llx is busy\n",
4253 r
->from_state
= r
->state
;
4254 r
->state
= RES_ANY_BUSY
;
4260 spin_unlock_irq(mlx4_tlock(dev
));
4265 static int move_all_busy(struct mlx4_dev
*dev
, int slave
,
4266 enum mlx4_resource type
)
4268 unsigned long begin
;
4273 busy
= _move_all_busy(dev
, slave
, type
, 0);
4274 if (time_after(jiffies
, begin
+ 5 * HZ
))
4281 busy
= _move_all_busy(dev
, slave
, type
, 1);
4285 static void rem_slave_qps(struct mlx4_dev
*dev
, int slave
)
4287 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4288 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4289 struct list_head
*qp_list
=
4290 &tracker
->slave_list
[slave
].res_list
[RES_QP
];
4298 err
= move_all_busy(dev
, slave
, RES_QP
);
4300 mlx4_warn(dev
, "rem_slave_qps: Could not move all qps to busy for slave %d\n",
4303 spin_lock_irq(mlx4_tlock(dev
));
4304 list_for_each_entry_safe(qp
, tmp
, qp_list
, com
.list
) {
4305 spin_unlock_irq(mlx4_tlock(dev
));
4306 if (qp
->com
.owner
== slave
) {
4307 qpn
= qp
->com
.res_id
;
4308 detach_qp(dev
, slave
, qp
);
4309 state
= qp
->com
.from_state
;
4310 while (state
!= 0) {
4312 case RES_QP_RESERVED
:
4313 spin_lock_irq(mlx4_tlock(dev
));
4314 rb_erase(&qp
->com
.node
,
4315 &tracker
->res_tree
[RES_QP
]);
4316 list_del(&qp
->com
.list
);
4317 spin_unlock_irq(mlx4_tlock(dev
));
4318 if (!valid_reserved(dev
, slave
, qpn
)) {
4319 __mlx4_qp_release_range(dev
, qpn
, 1);
4320 mlx4_release_resource(dev
, slave
,
4327 if (!valid_reserved(dev
, slave
, qpn
))
4328 __mlx4_qp_free_icm(dev
, qpn
);
4329 state
= RES_QP_RESERVED
;
4333 err
= mlx4_cmd(dev
, in_param
,
4336 MLX4_CMD_TIME_CLASS_A
,
4339 mlx4_dbg(dev
, "rem_slave_qps: failed to move slave %d qpn %d to reset\n",
4340 slave
, qp
->local_qpn
);
4341 atomic_dec(&qp
->rcq
->ref_count
);
4342 atomic_dec(&qp
->scq
->ref_count
);
4343 atomic_dec(&qp
->mtt
->ref_count
);
4345 atomic_dec(&qp
->srq
->ref_count
);
4346 state
= RES_QP_MAPPED
;
4353 spin_lock_irq(mlx4_tlock(dev
));
4355 spin_unlock_irq(mlx4_tlock(dev
));
4358 static void rem_slave_srqs(struct mlx4_dev
*dev
, int slave
)
4360 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4361 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4362 struct list_head
*srq_list
=
4363 &tracker
->slave_list
[slave
].res_list
[RES_SRQ
];
4364 struct res_srq
*srq
;
4365 struct res_srq
*tmp
;
4372 err
= move_all_busy(dev
, slave
, RES_SRQ
);
4374 mlx4_warn(dev
, "rem_slave_srqs: Could not move all srqs - too busy for slave %d\n",
4377 spin_lock_irq(mlx4_tlock(dev
));
4378 list_for_each_entry_safe(srq
, tmp
, srq_list
, com
.list
) {
4379 spin_unlock_irq(mlx4_tlock(dev
));
4380 if (srq
->com
.owner
== slave
) {
4381 srqn
= srq
->com
.res_id
;
4382 state
= srq
->com
.from_state
;
4383 while (state
!= 0) {
4385 case RES_SRQ_ALLOCATED
:
4386 __mlx4_srq_free_icm(dev
, srqn
);
4387 spin_lock_irq(mlx4_tlock(dev
));
4388 rb_erase(&srq
->com
.node
,
4389 &tracker
->res_tree
[RES_SRQ
]);
4390 list_del(&srq
->com
.list
);
4391 spin_unlock_irq(mlx4_tlock(dev
));
4392 mlx4_release_resource(dev
, slave
,
4400 err
= mlx4_cmd(dev
, in_param
, srqn
, 1,
4402 MLX4_CMD_TIME_CLASS_A
,
4405 mlx4_dbg(dev
, "rem_slave_srqs: failed to move slave %d srq %d to SW ownership\n",
4408 atomic_dec(&srq
->mtt
->ref_count
);
4410 atomic_dec(&srq
->cq
->ref_count
);
4411 state
= RES_SRQ_ALLOCATED
;
4419 spin_lock_irq(mlx4_tlock(dev
));
4421 spin_unlock_irq(mlx4_tlock(dev
));
4424 static void rem_slave_cqs(struct mlx4_dev
*dev
, int slave
)
4426 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4427 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4428 struct list_head
*cq_list
=
4429 &tracker
->slave_list
[slave
].res_list
[RES_CQ
];
4438 err
= move_all_busy(dev
, slave
, RES_CQ
);
4440 mlx4_warn(dev
, "rem_slave_cqs: Could not move all cqs - too busy for slave %d\n",
4443 spin_lock_irq(mlx4_tlock(dev
));
4444 list_for_each_entry_safe(cq
, tmp
, cq_list
, com
.list
) {
4445 spin_unlock_irq(mlx4_tlock(dev
));
4446 if (cq
->com
.owner
== slave
&& !atomic_read(&cq
->ref_count
)) {
4447 cqn
= cq
->com
.res_id
;
4448 state
= cq
->com
.from_state
;
4449 while (state
!= 0) {
4451 case RES_CQ_ALLOCATED
:
4452 __mlx4_cq_free_icm(dev
, cqn
);
4453 spin_lock_irq(mlx4_tlock(dev
));
4454 rb_erase(&cq
->com
.node
,
4455 &tracker
->res_tree
[RES_CQ
]);
4456 list_del(&cq
->com
.list
);
4457 spin_unlock_irq(mlx4_tlock(dev
));
4458 mlx4_release_resource(dev
, slave
,
4466 err
= mlx4_cmd(dev
, in_param
, cqn
, 1,
4468 MLX4_CMD_TIME_CLASS_A
,
4471 mlx4_dbg(dev
, "rem_slave_cqs: failed to move slave %d cq %d to SW ownership\n",
4473 atomic_dec(&cq
->mtt
->ref_count
);
4474 state
= RES_CQ_ALLOCATED
;
4482 spin_lock_irq(mlx4_tlock(dev
));
4484 spin_unlock_irq(mlx4_tlock(dev
));
4487 static void rem_slave_mrs(struct mlx4_dev
*dev
, int slave
)
4489 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4490 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4491 struct list_head
*mpt_list
=
4492 &tracker
->slave_list
[slave
].res_list
[RES_MPT
];
4493 struct res_mpt
*mpt
;
4494 struct res_mpt
*tmp
;
4501 err
= move_all_busy(dev
, slave
, RES_MPT
);
4503 mlx4_warn(dev
, "rem_slave_mrs: Could not move all mpts - too busy for slave %d\n",
4506 spin_lock_irq(mlx4_tlock(dev
));
4507 list_for_each_entry_safe(mpt
, tmp
, mpt_list
, com
.list
) {
4508 spin_unlock_irq(mlx4_tlock(dev
));
4509 if (mpt
->com
.owner
== slave
) {
4510 mptn
= mpt
->com
.res_id
;
4511 state
= mpt
->com
.from_state
;
4512 while (state
!= 0) {
4514 case RES_MPT_RESERVED
:
4515 __mlx4_mpt_release(dev
, mpt
->key
);
4516 spin_lock_irq(mlx4_tlock(dev
));
4517 rb_erase(&mpt
->com
.node
,
4518 &tracker
->res_tree
[RES_MPT
]);
4519 list_del(&mpt
->com
.list
);
4520 spin_unlock_irq(mlx4_tlock(dev
));
4521 mlx4_release_resource(dev
, slave
,
4527 case RES_MPT_MAPPED
:
4528 __mlx4_mpt_free_icm(dev
, mpt
->key
);
4529 state
= RES_MPT_RESERVED
;
4534 err
= mlx4_cmd(dev
, in_param
, mptn
, 0,
4536 MLX4_CMD_TIME_CLASS_A
,
4539 mlx4_dbg(dev
, "rem_slave_mrs: failed to move slave %d mpt %d to SW ownership\n",
4542 atomic_dec(&mpt
->mtt
->ref_count
);
4543 state
= RES_MPT_MAPPED
;
4550 spin_lock_irq(mlx4_tlock(dev
));
4552 spin_unlock_irq(mlx4_tlock(dev
));
4555 static void rem_slave_mtts(struct mlx4_dev
*dev
, int slave
)
4557 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4558 struct mlx4_resource_tracker
*tracker
=
4559 &priv
->mfunc
.master
.res_tracker
;
4560 struct list_head
*mtt_list
=
4561 &tracker
->slave_list
[slave
].res_list
[RES_MTT
];
4562 struct res_mtt
*mtt
;
4563 struct res_mtt
*tmp
;
4569 err
= move_all_busy(dev
, slave
, RES_MTT
);
4571 mlx4_warn(dev
, "rem_slave_mtts: Could not move all mtts - too busy for slave %d\n",
4574 spin_lock_irq(mlx4_tlock(dev
));
4575 list_for_each_entry_safe(mtt
, tmp
, mtt_list
, com
.list
) {
4576 spin_unlock_irq(mlx4_tlock(dev
));
4577 if (mtt
->com
.owner
== slave
) {
4578 base
= mtt
->com
.res_id
;
4579 state
= mtt
->com
.from_state
;
4580 while (state
!= 0) {
4582 case RES_MTT_ALLOCATED
:
4583 __mlx4_free_mtt_range(dev
, base
,
4585 spin_lock_irq(mlx4_tlock(dev
));
4586 rb_erase(&mtt
->com
.node
,
4587 &tracker
->res_tree
[RES_MTT
]);
4588 list_del(&mtt
->com
.list
);
4589 spin_unlock_irq(mlx4_tlock(dev
));
4590 mlx4_release_resource(dev
, slave
, RES_MTT
,
4591 1 << mtt
->order
, 0);
4601 spin_lock_irq(mlx4_tlock(dev
));
4603 spin_unlock_irq(mlx4_tlock(dev
));
4606 static void rem_slave_fs_rule(struct mlx4_dev
*dev
, int slave
)
4608 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4609 struct mlx4_resource_tracker
*tracker
=
4610 &priv
->mfunc
.master
.res_tracker
;
4611 struct list_head
*fs_rule_list
=
4612 &tracker
->slave_list
[slave
].res_list
[RES_FS_RULE
];
4613 struct res_fs_rule
*fs_rule
;
4614 struct res_fs_rule
*tmp
;
4619 err
= move_all_busy(dev
, slave
, RES_FS_RULE
);
4621 mlx4_warn(dev
, "rem_slave_fs_rule: Could not move all mtts to busy for slave %d\n",
4624 spin_lock_irq(mlx4_tlock(dev
));
4625 list_for_each_entry_safe(fs_rule
, tmp
, fs_rule_list
, com
.list
) {
4626 spin_unlock_irq(mlx4_tlock(dev
));
4627 if (fs_rule
->com
.owner
== slave
) {
4628 base
= fs_rule
->com
.res_id
;
4629 state
= fs_rule
->com
.from_state
;
4630 while (state
!= 0) {
4632 case RES_FS_RULE_ALLOCATED
:
4634 err
= mlx4_cmd(dev
, base
, 0, 0,
4635 MLX4_QP_FLOW_STEERING_DETACH
,
4636 MLX4_CMD_TIME_CLASS_A
,
4639 spin_lock_irq(mlx4_tlock(dev
));
4640 rb_erase(&fs_rule
->com
.node
,
4641 &tracker
->res_tree
[RES_FS_RULE
]);
4642 list_del(&fs_rule
->com
.list
);
4643 spin_unlock_irq(mlx4_tlock(dev
));
4653 spin_lock_irq(mlx4_tlock(dev
));
4655 spin_unlock_irq(mlx4_tlock(dev
));
4658 static void rem_slave_eqs(struct mlx4_dev
*dev
, int slave
)
4660 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4661 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4662 struct list_head
*eq_list
=
4663 &tracker
->slave_list
[slave
].res_list
[RES_EQ
];
4670 struct mlx4_cmd_mailbox
*mailbox
;
4672 err
= move_all_busy(dev
, slave
, RES_EQ
);
4674 mlx4_warn(dev
, "rem_slave_eqs: Could not move all eqs - too busy for slave %d\n",
4677 spin_lock_irq(mlx4_tlock(dev
));
4678 list_for_each_entry_safe(eq
, tmp
, eq_list
, com
.list
) {
4679 spin_unlock_irq(mlx4_tlock(dev
));
4680 if (eq
->com
.owner
== slave
) {
4681 eqn
= eq
->com
.res_id
;
4682 state
= eq
->com
.from_state
;
4683 while (state
!= 0) {
4685 case RES_EQ_RESERVED
:
4686 spin_lock_irq(mlx4_tlock(dev
));
4687 rb_erase(&eq
->com
.node
,
4688 &tracker
->res_tree
[RES_EQ
]);
4689 list_del(&eq
->com
.list
);
4690 spin_unlock_irq(mlx4_tlock(dev
));
4696 mailbox
= mlx4_alloc_cmd_mailbox(dev
);
4697 if (IS_ERR(mailbox
)) {
4701 err
= mlx4_cmd_box(dev
, slave
, 0,
4704 MLX4_CMD_TIME_CLASS_A
,
4707 mlx4_dbg(dev
, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n",
4709 mlx4_free_cmd_mailbox(dev
, mailbox
);
4710 atomic_dec(&eq
->mtt
->ref_count
);
4711 state
= RES_EQ_RESERVED
;
4719 spin_lock_irq(mlx4_tlock(dev
));
4721 spin_unlock_irq(mlx4_tlock(dev
));
4724 static void rem_slave_counters(struct mlx4_dev
*dev
, int slave
)
4726 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4727 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4728 struct list_head
*counter_list
=
4729 &tracker
->slave_list
[slave
].res_list
[RES_COUNTER
];
4730 struct res_counter
*counter
;
4731 struct res_counter
*tmp
;
4735 err
= move_all_busy(dev
, slave
, RES_COUNTER
);
4737 mlx4_warn(dev
, "rem_slave_counters: Could not move all counters - too busy for slave %d\n",
4740 spin_lock_irq(mlx4_tlock(dev
));
4741 list_for_each_entry_safe(counter
, tmp
, counter_list
, com
.list
) {
4742 if (counter
->com
.owner
== slave
) {
4743 index
= counter
->com
.res_id
;
4744 rb_erase(&counter
->com
.node
,
4745 &tracker
->res_tree
[RES_COUNTER
]);
4746 list_del(&counter
->com
.list
);
4748 __mlx4_counter_free(dev
, index
);
4749 mlx4_release_resource(dev
, slave
, RES_COUNTER
, 1, 0);
4752 spin_unlock_irq(mlx4_tlock(dev
));
4755 static void rem_slave_xrcdns(struct mlx4_dev
*dev
, int slave
)
4757 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4758 struct mlx4_resource_tracker
*tracker
= &priv
->mfunc
.master
.res_tracker
;
4759 struct list_head
*xrcdn_list
=
4760 &tracker
->slave_list
[slave
].res_list
[RES_XRCD
];
4761 struct res_xrcdn
*xrcd
;
4762 struct res_xrcdn
*tmp
;
4766 err
= move_all_busy(dev
, slave
, RES_XRCD
);
4768 mlx4_warn(dev
, "rem_slave_xrcdns: Could not move all xrcdns - too busy for slave %d\n",
4771 spin_lock_irq(mlx4_tlock(dev
));
4772 list_for_each_entry_safe(xrcd
, tmp
, xrcdn_list
, com
.list
) {
4773 if (xrcd
->com
.owner
== slave
) {
4774 xrcdn
= xrcd
->com
.res_id
;
4775 rb_erase(&xrcd
->com
.node
, &tracker
->res_tree
[RES_XRCD
]);
4776 list_del(&xrcd
->com
.list
);
4778 __mlx4_xrcd_free(dev
, xrcdn
);
4781 spin_unlock_irq(mlx4_tlock(dev
));
4784 void mlx4_delete_all_resources_for_slave(struct mlx4_dev
*dev
, int slave
)
4786 struct mlx4_priv
*priv
= mlx4_priv(dev
);
4787 mlx4_reset_roce_gids(dev
, slave
);
4788 mutex_lock(&priv
->mfunc
.master
.res_tracker
.slave_list
[slave
].mutex
);
4789 rem_slave_vlans(dev
, slave
);
4790 rem_slave_macs(dev
, slave
);
4791 rem_slave_fs_rule(dev
, slave
);
4792 rem_slave_qps(dev
, slave
);
4793 rem_slave_srqs(dev
, slave
);
4794 rem_slave_cqs(dev
, slave
);
4795 rem_slave_mrs(dev
, slave
);
4796 rem_slave_eqs(dev
, slave
);
4797 rem_slave_mtts(dev
, slave
);
4798 rem_slave_counters(dev
, slave
);
4799 rem_slave_xrcdns(dev
, slave
);
4800 mutex_unlock(&priv
->mfunc
.master
.res_tracker
.slave_list
[slave
].mutex
);
4803 void mlx4_vf_immed_vlan_work_handler(struct work_struct
*_work
)
4805 struct mlx4_vf_immed_vlan_work
*work
=
4806 container_of(_work
, struct mlx4_vf_immed_vlan_work
, work
);
4807 struct mlx4_cmd_mailbox
*mailbox
;
4808 struct mlx4_update_qp_context
*upd_context
;
4809 struct mlx4_dev
*dev
= &work
->priv
->dev
;
4810 struct mlx4_resource_tracker
*tracker
=
4811 &work
->priv
->mfunc
.master
.res_tracker
;
4812 struct list_head
*qp_list
=
4813 &tracker
->slave_list
[work
->slave
].res_list
[RES_QP
];
4816 u64 qp_path_mask_vlan_ctrl
=
4817 ((1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED
) |
4818 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P
) |
4819 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED
) |
4820 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED
) |
4821 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P
) |
4822 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED
));
4824 u64 qp_path_mask
= ((1ULL << MLX4_UPD_QP_PATH_MASK_VLAN_INDEX
) |
4825 (1ULL << MLX4_UPD_QP_PATH_MASK_FVL
) |
4826 (1ULL << MLX4_UPD_QP_PATH_MASK_CV
) |
4827 (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_HIDE_CQE_VLAN
) |
4828 (1ULL << MLX4_UPD_QP_PATH_MASK_FEUP
) |
4829 (1ULL << MLX4_UPD_QP_PATH_MASK_FVL_RX
) |
4830 (1ULL << MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE
));
4833 int port
, errors
= 0;
4836 if (mlx4_is_slave(dev
)) {
4837 mlx4_warn(dev
, "Trying to update-qp in slave %d\n",
4842 mailbox
= mlx4_alloc_cmd_mailbox(dev
);
4843 if (IS_ERR(mailbox
))
4845 if (work
->flags
& MLX4_VF_IMMED_VLAN_FLAG_LINK_DISABLE
) /* block all */
4846 vlan_control
= MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED
|
4847 MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED
|
4848 MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED
|
4849 MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED
|
4850 MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED
|
4851 MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED
;
4852 else if (!work
->vlan_id
)
4853 vlan_control
= MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED
|
4854 MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED
;
4856 vlan_control
= MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED
|
4857 MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED
|
4858 MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED
;
4860 upd_context
= mailbox
->buf
;
4861 upd_context
->qp_mask
= cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_VSD
);
4863 spin_lock_irq(mlx4_tlock(dev
));
4864 list_for_each_entry_safe(qp
, tmp
, qp_list
, com
.list
) {
4865 spin_unlock_irq(mlx4_tlock(dev
));
4866 if (qp
->com
.owner
== work
->slave
) {
4867 if (qp
->com
.from_state
!= RES_QP_HW
||
4868 !qp
->sched_queue
|| /* no INIT2RTR trans yet */
4869 mlx4_is_qp_reserved(dev
, qp
->local_qpn
) ||
4870 qp
->qpc_flags
& (1 << MLX4_RSS_QPC_FLAG_OFFSET
)) {
4871 spin_lock_irq(mlx4_tlock(dev
));
4874 port
= (qp
->sched_queue
>> 6 & 1) + 1;
4875 if (port
!= work
->port
) {
4876 spin_lock_irq(mlx4_tlock(dev
));
4879 if (MLX4_QP_ST_RC
== ((qp
->qpc_flags
>> 16) & 0xff))
4880 upd_context
->primary_addr_path_mask
= cpu_to_be64(qp_path_mask
);
4882 upd_context
->primary_addr_path_mask
=
4883 cpu_to_be64(qp_path_mask
| qp_path_mask_vlan_ctrl
);
4884 if (work
->vlan_id
== MLX4_VGT
) {
4885 upd_context
->qp_context
.param3
= qp
->param3
;
4886 upd_context
->qp_context
.pri_path
.vlan_control
= qp
->vlan_control
;
4887 upd_context
->qp_context
.pri_path
.fvl_rx
= qp
->fvl_rx
;
4888 upd_context
->qp_context
.pri_path
.vlan_index
= qp
->vlan_index
;
4889 upd_context
->qp_context
.pri_path
.fl
= qp
->pri_path_fl
;
4890 upd_context
->qp_context
.pri_path
.feup
= qp
->feup
;
4891 upd_context
->qp_context
.pri_path
.sched_queue
=
4894 upd_context
->qp_context
.param3
= qp
->param3
& ~cpu_to_be32(MLX4_STRIP_VLAN
);
4895 upd_context
->qp_context
.pri_path
.vlan_control
= vlan_control
;
4896 upd_context
->qp_context
.pri_path
.vlan_index
= work
->vlan_ix
;
4897 upd_context
->qp_context
.pri_path
.fvl_rx
=
4898 qp
->fvl_rx
| MLX4_FVL_RX_FORCE_ETH_VLAN
;
4899 upd_context
->qp_context
.pri_path
.fl
=
4900 qp
->pri_path_fl
| MLX4_FL_CV
| MLX4_FL_ETH_HIDE_CQE_VLAN
;
4901 upd_context
->qp_context
.pri_path
.feup
=
4902 qp
->feup
| MLX4_FEUP_FORCE_ETH_UP
| MLX4_FVL_FORCE_ETH_VLAN
;
4903 upd_context
->qp_context
.pri_path
.sched_queue
=
4904 qp
->sched_queue
& 0xC7;
4905 upd_context
->qp_context
.pri_path
.sched_queue
|=
4906 ((work
->qos
& 0x7) << 3);
4909 err
= mlx4_cmd(dev
, mailbox
->dma
,
4910 qp
->local_qpn
& 0xffffff,
4911 0, MLX4_CMD_UPDATE_QP
,
4912 MLX4_CMD_TIME_CLASS_C
, MLX4_CMD_NATIVE
);
4914 mlx4_info(dev
, "UPDATE_QP failed for slave %d, port %d, qpn %d (%d)\n",
4915 work
->slave
, port
, qp
->local_qpn
, err
);
4919 spin_lock_irq(mlx4_tlock(dev
));
4921 spin_unlock_irq(mlx4_tlock(dev
));
4922 mlx4_free_cmd_mailbox(dev
, mailbox
);
4925 mlx4_err(dev
, "%d UPDATE_QP failures for slave %d, port %d\n",
4926 errors
, work
->slave
, work
->port
);
4928 /* unregister previous vlan_id if needed and we had no errors
4929 * while updating the QPs
4931 if (work
->flags
& MLX4_VF_IMMED_VLAN_FLAG_VLAN
&& !errors
&&
4932 NO_INDX
!= work
->orig_vlan_ix
)
4933 __mlx4_unregister_vlan(&work
->priv
->dev
, work
->port
,
4934 work
->orig_vlan_id
);