Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 1 | /* |
Saeed Mahameed | 302bdf6 | 2015-04-02 17:07:29 +0300 | [diff] [blame] | 2 | * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 3 | * |
| 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: |
| 9 | * |
| 10 | * Redistribution and use in source and binary forms, with or |
| 11 | * without modification, are permitted provided that the following |
| 12 | * conditions are met: |
| 13 | * |
| 14 | * - Redistributions of source code must retain the above |
| 15 | * copyright notice, this list of conditions and the following |
| 16 | * disclaimer. |
| 17 | * |
| 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. |
| 22 | * |
| 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 |
| 30 | * SOFTWARE. |
| 31 | */ |
| 32 | |
| 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" |
| 38 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 39 | void mlx5_init_mkey_table(struct mlx5_core_dev *dev) |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 40 | { |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 41 | struct mlx5_mkey_table *table = &dev->priv.mkey_table; |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 42 | |
Majd Dibbiny | a31208b | 2015-09-25 10:49:14 +0300 | [diff] [blame] | 43 | memset(table, 0, sizeof(*table)); |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 44 | rwlock_init(&table->lock); |
| 45 | INIT_RADIX_TREE(&table->tree, GFP_ATOMIC); |
| 46 | } |
| 47 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 48 | void mlx5_cleanup_mkey_table(struct mlx5_core_dev *dev) |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 49 | { |
| 50 | } |
| 51 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 52 | int mlx5_core_create_mkey(struct mlx5_core_dev *dev, |
| 53 | struct mlx5_core_mkey *mkey, |
Eli Cohen | 746b558 | 2013-10-23 09:53:14 +0300 | [diff] [blame] | 54 | struct mlx5_create_mkey_mbox_in *in, int inlen, |
| 55 | mlx5_cmd_cbk_t callback, void *context, |
| 56 | struct mlx5_create_mkey_mbox_out *out) |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 57 | { |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 58 | struct mlx5_mkey_table *table = &dev->priv.mkey_table; |
Eli Cohen | 746b558 | 2013-10-23 09:53:14 +0300 | [diff] [blame] | 59 | struct mlx5_create_mkey_mbox_out lout; |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 60 | int err; |
| 61 | u8 key; |
| 62 | |
Eli Cohen | 746b558 | 2013-10-23 09:53:14 +0300 | [diff] [blame] | 63 | memset(&lout, 0, sizeof(lout)); |
| 64 | spin_lock_irq(&dev->priv.mkey_lock); |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 65 | key = dev->priv.mkey_key++; |
Eli Cohen | 746b558 | 2013-10-23 09:53:14 +0300 | [diff] [blame] | 66 | spin_unlock_irq(&dev->priv.mkey_lock); |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 67 | in->seg.qpn_mkey7_0 |= cpu_to_be32(key); |
| 68 | in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_MKEY); |
Eli Cohen | 746b558 | 2013-10-23 09:53:14 +0300 | [diff] [blame] | 69 | if (callback) { |
| 70 | err = mlx5_cmd_exec_cb(dev, in, inlen, out, sizeof(*out), |
| 71 | callback, context); |
| 72 | return err; |
| 73 | } else { |
| 74 | err = mlx5_cmd_exec(dev, in, inlen, &lout, sizeof(lout)); |
| 75 | } |
| 76 | |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 77 | if (err) { |
Joe Perches | 1a91de2 | 2014-05-07 12:52:57 -0700 | [diff] [blame] | 78 | mlx5_core_dbg(dev, "cmd exec failed %d\n", err); |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 79 | return err; |
| 80 | } |
| 81 | |
Eli Cohen | 746b558 | 2013-10-23 09:53:14 +0300 | [diff] [blame] | 82 | if (lout.hdr.status) { |
| 83 | mlx5_core_dbg(dev, "status %d\n", lout.hdr.status); |
| 84 | return mlx5_cmd_status_to_err(&lout.hdr); |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 85 | } |
| 86 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 87 | mkey->iova = be64_to_cpu(in->seg.start_addr); |
| 88 | mkey->size = be64_to_cpu(in->seg.len); |
| 89 | mkey->key = mlx5_idx_to_mkey(be32_to_cpu(lout.mkey) & 0xffffff) | key; |
| 90 | mkey->pd = be32_to_cpu(in->seg.flags_pd) & 0xffffff; |
Haggai Eran | b475598 | 2014-05-22 14:50:10 +0300 | [diff] [blame] | 91 | |
Eli Cohen | 746b558 | 2013-10-23 09:53:14 +0300 | [diff] [blame] | 92 | mlx5_core_dbg(dev, "out 0x%x, key 0x%x, mkey 0x%x\n", |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 93 | be32_to_cpu(lout.mkey), key, mkey->key); |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 94 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 95 | /* connect to mkey tree */ |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 96 | write_lock_irq(&table->lock); |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 97 | err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key), mkey); |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 98 | write_unlock_irq(&table->lock); |
Sagi Grimberg | 6ef07a9 | 2014-06-08 10:00:59 +0300 | [diff] [blame] | 99 | if (err) { |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 100 | mlx5_core_warn(dev, "failed radix tree insert of mkey 0x%x, %d\n", |
| 101 | mlx5_base_mkey(mkey->key), err); |
| 102 | mlx5_core_destroy_mkey(dev, mkey); |
Sagi Grimberg | 6ef07a9 | 2014-06-08 10:00:59 +0300 | [diff] [blame] | 103 | } |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 104 | |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 105 | return err; |
| 106 | } |
| 107 | EXPORT_SYMBOL(mlx5_core_create_mkey); |
| 108 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 109 | int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, |
| 110 | struct mlx5_core_mkey *mkey) |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 111 | { |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 112 | struct mlx5_mkey_table *table = &dev->priv.mkey_table; |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 113 | struct mlx5_destroy_mkey_mbox_in in; |
| 114 | struct mlx5_destroy_mkey_mbox_out out; |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 115 | struct mlx5_core_mkey *deleted_mkey; |
Sagi Grimberg | 3bcdb17 | 2014-02-23 14:19:10 +0200 | [diff] [blame] | 116 | unsigned long flags; |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 117 | int err; |
| 118 | |
| 119 | memset(&in, 0, sizeof(in)); |
| 120 | memset(&out, 0, sizeof(out)); |
| 121 | |
Sagi Grimberg | 6ef07a9 | 2014-06-08 10:00:59 +0300 | [diff] [blame] | 122 | write_lock_irqsave(&table->lock, flags); |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 123 | deleted_mkey = radix_tree_delete(&table->tree, mlx5_base_mkey(mkey->key)); |
Sagi Grimberg | 6ef07a9 | 2014-06-08 10:00:59 +0300 | [diff] [blame] | 124 | write_unlock_irqrestore(&table->lock, flags); |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 125 | if (!deleted_mkey) { |
| 126 | mlx5_core_warn(dev, "failed radix tree delete of mkey 0x%x\n", |
| 127 | mlx5_base_mkey(mkey->key)); |
Sagi Grimberg | 6ef07a9 | 2014-06-08 10:00:59 +0300 | [diff] [blame] | 128 | return -ENOENT; |
| 129 | } |
| 130 | |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 131 | in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_MKEY); |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 132 | in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mkey->key)); |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 133 | err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); |
| 134 | if (err) |
| 135 | return err; |
| 136 | |
| 137 | if (out.hdr.status) |
| 138 | return mlx5_cmd_status_to_err(&out.hdr); |
| 139 | |
| 140 | return err; |
| 141 | } |
| 142 | EXPORT_SYMBOL(mlx5_core_destroy_mkey); |
| 143 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 144 | int mlx5_core_query_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mkey *mkey, |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 145 | struct mlx5_query_mkey_mbox_out *out, int outlen) |
| 146 | { |
Achiad Shochat | 60722c2 | 2015-04-02 17:07:24 +0300 | [diff] [blame] | 147 | struct mlx5_query_mkey_mbox_in in; |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 148 | int err; |
| 149 | |
| 150 | memset(&in, 0, sizeof(in)); |
| 151 | memset(out, 0, outlen); |
| 152 | |
| 153 | in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_MKEY); |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 154 | in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mkey->key)); |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 155 | err = mlx5_cmd_exec(dev, &in, sizeof(in), out, outlen); |
| 156 | if (err) |
| 157 | return err; |
| 158 | |
| 159 | if (out->hdr.status) |
| 160 | return mlx5_cmd_status_to_err(&out->hdr); |
| 161 | |
| 162 | return err; |
| 163 | } |
| 164 | EXPORT_SYMBOL(mlx5_core_query_mkey); |
| 165 | |
Matan Barak | a606b0f | 2016-02-29 18:05:28 +0200 | [diff] [blame] | 166 | int mlx5_core_dump_fill_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mkey *_mkey, |
Eli Cohen | e126ba9 | 2013-07-07 17:25:49 +0300 | [diff] [blame] | 167 | u32 *mkey) |
| 168 | { |
| 169 | struct mlx5_query_special_ctxs_mbox_in in; |
| 170 | struct mlx5_query_special_ctxs_mbox_out out; |
| 171 | int err; |
| 172 | |
| 173 | memset(&in, 0, sizeof(in)); |
| 174 | memset(&out, 0, sizeof(out)); |
| 175 | |
| 176 | in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS); |
| 177 | err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); |
| 178 | if (err) |
| 179 | return err; |
| 180 | |
| 181 | if (out.hdr.status) |
| 182 | return mlx5_cmd_status_to_err(&out.hdr); |
| 183 | |
| 184 | *mkey = be32_to_cpu(out.dump_fill_mkey); |
| 185 | |
| 186 | return err; |
| 187 | } |
| 188 | EXPORT_SYMBOL(mlx5_core_dump_fill_mkey); |
Sagi Grimberg | 3121e3c | 2014-02-23 14:19:06 +0200 | [diff] [blame] | 189 | |
| 190 | int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn, |
| 191 | int npsvs, u32 *sig_index) |
| 192 | { |
| 193 | struct mlx5_allocate_psv_in in; |
| 194 | struct mlx5_allocate_psv_out out; |
| 195 | int i, err; |
| 196 | |
| 197 | if (npsvs > MLX5_MAX_PSVS) |
| 198 | return -EINVAL; |
| 199 | |
| 200 | memset(&in, 0, sizeof(in)); |
| 201 | memset(&out, 0, sizeof(out)); |
| 202 | |
| 203 | in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_PSV); |
| 204 | in.npsv_pd = cpu_to_be32((npsvs << 28) | pdn); |
| 205 | err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); |
| 206 | if (err) { |
| 207 | mlx5_core_err(dev, "cmd exec failed %d\n", err); |
| 208 | return err; |
| 209 | } |
| 210 | |
| 211 | if (out.hdr.status) { |
Joe Perches | 1a91de2 | 2014-05-07 12:52:57 -0700 | [diff] [blame] | 212 | mlx5_core_err(dev, "create_psv bad status %d\n", |
| 213 | out.hdr.status); |
Sagi Grimberg | 3121e3c | 2014-02-23 14:19:06 +0200 | [diff] [blame] | 214 | return mlx5_cmd_status_to_err(&out.hdr); |
| 215 | } |
| 216 | |
| 217 | for (i = 0; i < npsvs; i++) |
| 218 | sig_index[i] = be32_to_cpu(out.psv_idx[i]) & 0xffffff; |
| 219 | |
| 220 | return err; |
| 221 | } |
| 222 | EXPORT_SYMBOL(mlx5_core_create_psv); |
| 223 | |
| 224 | int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num) |
| 225 | { |
| 226 | struct mlx5_destroy_psv_in in; |
| 227 | struct mlx5_destroy_psv_out out; |
| 228 | int err; |
| 229 | |
| 230 | memset(&in, 0, sizeof(in)); |
| 231 | memset(&out, 0, sizeof(out)); |
| 232 | |
| 233 | in.psv_number = cpu_to_be32(psv_num); |
| 234 | in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_PSV); |
| 235 | err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); |
| 236 | if (err) { |
| 237 | mlx5_core_err(dev, "destroy_psv cmd exec failed %d\n", err); |
| 238 | goto out; |
| 239 | } |
| 240 | |
| 241 | if (out.hdr.status) { |
Joe Perches | 1a91de2 | 2014-05-07 12:52:57 -0700 | [diff] [blame] | 242 | mlx5_core_err(dev, "destroy_psv bad status %d\n", |
| 243 | out.hdr.status); |
Sagi Grimberg | 3121e3c | 2014-02-23 14:19:06 +0200 | [diff] [blame] | 244 | err = mlx5_cmd_status_to_err(&out.hdr); |
| 245 | goto out; |
| 246 | } |
| 247 | |
| 248 | out: |
| 249 | return err; |
| 250 | } |
| 251 | EXPORT_SYMBOL(mlx5_core_destroy_psv); |