2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <linux/kernel.h>
34 #include <linux/module.h>
35 #include <linux/mlx5/driver.h>
36 #include <linux/mlx5/cmd.h>
37 #include "mlx5_core.h"
39 void mlx5_init_mkey_table(struct mlx5_core_dev
*dev
)
41 struct mlx5_mkey_table
*table
= &dev
->priv
.mkey_table
;
43 memset(table
, 0, sizeof(*table
));
44 rwlock_init(&table
->lock
);
45 INIT_RADIX_TREE(&table
->tree
, GFP_ATOMIC
);
48 void mlx5_cleanup_mkey_table(struct mlx5_core_dev
*dev
)
52 int mlx5_core_create_mkey_cb(struct mlx5_core_dev
*dev
,
53 struct mlx5_core_mkey
*mkey
,
56 mlx5_cmd_cbk_t callback
, void *context
)
58 struct mlx5_mkey_table
*table
= &dev
->priv
.mkey_table
;
59 u32 lout
[MLX5_ST_SZ_DW(create_mkey_out
)] = {0};
65 spin_lock_irq(&dev
->priv
.mkey_lock
);
66 key
= dev
->priv
.mkey_key
++;
67 spin_unlock_irq(&dev
->priv
.mkey_lock
);
68 mkc
= MLX5_ADDR_OF(create_mkey_in
, in
, memory_key_mkey_entry
);
70 MLX5_SET(create_mkey_in
, in
, opcode
, MLX5_CMD_OP_CREATE_MKEY
);
71 MLX5_SET(mkc
, mkc
, mkey_7_0
, key
);
74 return mlx5_cmd_exec_cb(dev
, in
, inlen
, out
, outlen
,
77 err
= mlx5_cmd_exec(dev
, in
, inlen
, lout
, sizeof(lout
));
81 mkey_index
= MLX5_GET(create_mkey_out
, lout
, mkey_index
);
82 mkey
->iova
= MLX5_GET64(mkc
, mkc
, start_addr
);
83 mkey
->size
= MLX5_GET64(mkc
, mkc
, len
);
84 mkey
->key
= mlx5_idx_to_mkey(mkey_index
) | key
;
85 mkey
->pd
= MLX5_GET(mkc
, mkc
, pd
);
87 mlx5_core_dbg(dev
, "out 0x%x, key 0x%x, mkey 0x%x\n",
88 mkey_index
, key
, mkey
->key
);
90 /* connect to mkey tree */
91 write_lock_irq(&table
->lock
);
92 err
= radix_tree_insert(&table
->tree
, mlx5_base_mkey(mkey
->key
), mkey
);
93 write_unlock_irq(&table
->lock
);
95 mlx5_core_warn(dev
, "failed radix tree insert of mkey 0x%x, %d\n",
96 mlx5_base_mkey(mkey
->key
), err
);
97 mlx5_core_destroy_mkey(dev
, mkey
);
102 EXPORT_SYMBOL(mlx5_core_create_mkey_cb
);
104 int mlx5_core_create_mkey(struct mlx5_core_dev
*dev
,
105 struct mlx5_core_mkey
*mkey
,
108 return mlx5_core_create_mkey_cb(dev
, mkey
, in
, inlen
,
109 NULL
, 0, NULL
, NULL
);
111 EXPORT_SYMBOL(mlx5_core_create_mkey
);
113 int mlx5_core_destroy_mkey(struct mlx5_core_dev
*dev
,
114 struct mlx5_core_mkey
*mkey
)
116 struct mlx5_mkey_table
*table
= &dev
->priv
.mkey_table
;
117 u32 out
[MLX5_ST_SZ_DW(destroy_mkey_out
)] = {0};
118 u32 in
[MLX5_ST_SZ_DW(destroy_mkey_in
)] = {0};
119 struct mlx5_core_mkey
*deleted_mkey
;
122 write_lock_irqsave(&table
->lock
, flags
);
123 deleted_mkey
= radix_tree_delete(&table
->tree
, mlx5_base_mkey(mkey
->key
));
124 write_unlock_irqrestore(&table
->lock
, flags
);
126 mlx5_core_warn(dev
, "failed radix tree delete of mkey 0x%x\n",
127 mlx5_base_mkey(mkey
->key
));
131 MLX5_SET(destroy_mkey_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_MKEY
);
132 MLX5_SET(destroy_mkey_in
, in
, mkey_index
, mlx5_mkey_to_idx(mkey
->key
));
133 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
135 EXPORT_SYMBOL(mlx5_core_destroy_mkey
);
137 int mlx5_core_query_mkey(struct mlx5_core_dev
*dev
, struct mlx5_core_mkey
*mkey
,
138 u32
*out
, int outlen
)
140 u32 in
[MLX5_ST_SZ_DW(query_mkey_in
)] = {0};
142 memset(out
, 0, outlen
);
143 MLX5_SET(query_mkey_in
, in
, opcode
, MLX5_CMD_OP_QUERY_MKEY
);
144 MLX5_SET(query_mkey_in
, in
, mkey_index
, mlx5_mkey_to_idx(mkey
->key
));
145 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, outlen
);
147 EXPORT_SYMBOL(mlx5_core_query_mkey
);
149 int mlx5_core_dump_fill_mkey(struct mlx5_core_dev
*dev
, struct mlx5_core_mkey
*_mkey
,
152 u32 out
[MLX5_ST_SZ_DW(query_special_contexts_out
)] = {0};
153 u32 in
[MLX5_ST_SZ_DW(query_special_contexts_in
)] = {0};
156 MLX5_SET(query_special_contexts_in
, in
, opcode
,
157 MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS
);
158 err
= mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
160 *mkey
= MLX5_GET(query_special_contexts_out
, out
,
164 EXPORT_SYMBOL(mlx5_core_dump_fill_mkey
);
166 static inline u32
mlx5_get_psv(u32
*out
, int psv_index
)
169 case 1: return MLX5_GET(create_psv_out
, out
, psv1_index
);
170 case 2: return MLX5_GET(create_psv_out
, out
, psv2_index
);
171 case 3: return MLX5_GET(create_psv_out
, out
, psv3_index
);
172 default: return MLX5_GET(create_psv_out
, out
, psv0_index
);
176 int mlx5_core_create_psv(struct mlx5_core_dev
*dev
, u32 pdn
,
177 int npsvs
, u32
*sig_index
)
179 u32 out
[MLX5_ST_SZ_DW(create_psv_out
)] = {0};
180 u32 in
[MLX5_ST_SZ_DW(create_psv_in
)] = {0};
183 if (npsvs
> MLX5_MAX_PSVS
)
186 MLX5_SET(create_psv_in
, in
, opcode
, MLX5_CMD_OP_CREATE_PSV
);
187 MLX5_SET(create_psv_in
, in
, pd
, pdn
);
188 MLX5_SET(create_psv_in
, in
, num_psv
, npsvs
);
190 err
= mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
194 for (i
= 0; i
< npsvs
; i
++)
195 sig_index
[i
] = mlx5_get_psv(out
, i
);
199 EXPORT_SYMBOL(mlx5_core_create_psv
);
201 int mlx5_core_destroy_psv(struct mlx5_core_dev
*dev
, int psv_num
)
203 u32 out
[MLX5_ST_SZ_DW(destroy_psv_out
)] = {0};
204 u32 in
[MLX5_ST_SZ_DW(destroy_psv_in
)] = {0};
206 MLX5_SET(destroy_psv_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_PSV
);
207 MLX5_SET(destroy_psv_in
, in
, psvn
, psv_num
);
208 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
210 EXPORT_SYMBOL(mlx5_core_destroy_psv
);