root/drivers/infiniband/hw/mlx5/cmd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlx5_cmd_dump_fill_mkey
  2. mlx5_cmd_null_mkey
  3. mlx5_cmd_query_cong_params
  4. mlx5_cmd_modify_cong_params
  5. mlx5_cmd_alloc_memic
  6. mlx5_cmd_dealloc_memic
  7. mlx5_cmd_query_ext_ppcnt_counters
  8. mlx5_cmd_destroy_tir
  9. mlx5_cmd_destroy_tis
  10. mlx5_cmd_destroy_rqt
  11. mlx5_cmd_alloc_transport_domain
  12. mlx5_cmd_dealloc_transport_domain
  13. mlx5_cmd_dealloc_pd
  14. mlx5_cmd_attach_mcg
  15. mlx5_cmd_detach_mcg
  16. mlx5_cmd_xrcd_alloc
  17. mlx5_cmd_xrcd_dealloc
  18. mlx5_cmd_alloc_q_counter
  19. mlx5_cmd_mad_ifc

   1 /*
   2  * Copyright (c) 2017, Mellanox Technologies. All rights reserved.
   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 "cmd.h"
  34 
  35 int mlx5_cmd_dump_fill_mkey(struct mlx5_core_dev *dev, u32 *mkey)
  36 {
  37         u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {0};
  38         u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)]   = {0};
  39         int err;
  40 
  41         MLX5_SET(query_special_contexts_in, in, opcode,
  42                  MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
  43         err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  44         if (!err)
  45                 *mkey = MLX5_GET(query_special_contexts_out, out,
  46                                  dump_fill_mkey);
  47         return err;
  48 }
  49 
  50 int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey)
  51 {
  52         u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {};
  53         u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)]   = {};
  54         int err;
  55 
  56         MLX5_SET(query_special_contexts_in, in, opcode,
  57                  MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
  58         err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  59         if (!err)
  60                 *null_mkey = MLX5_GET(query_special_contexts_out, out,
  61                                       null_mkey);
  62         return err;
  63 }
  64 
  65 int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
  66                                void *out, int out_size)
  67 {
  68         u32 in[MLX5_ST_SZ_DW(query_cong_params_in)] = { };
  69 
  70         MLX5_SET(query_cong_params_in, in, opcode,
  71                  MLX5_CMD_OP_QUERY_CONG_PARAMS);
  72         MLX5_SET(query_cong_params_in, in, cong_protocol, cong_point);
  73 
  74         return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size);
  75 }
  76 
  77 int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *dev,
  78                                 void *in, int in_size)
  79 {
  80         u32 out[MLX5_ST_SZ_DW(modify_cong_params_out)] = { };
  81 
  82         return mlx5_cmd_exec(dev, in, in_size, out, sizeof(out));
  83 }
  84 
  85 int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
  86                          u64 length, u32 alignment)
  87 {
  88         struct mlx5_core_dev *dev = dm->dev;
  89         u64 num_memic_hw_pages = MLX5_CAP_DEV_MEM(dev, memic_bar_size)
  90                                         >> PAGE_SHIFT;
  91         u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr);
  92         u32 max_alignment = MLX5_CAP_DEV_MEM(dev, log_max_memic_addr_alignment);
  93         u32 num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
  94         u32 out[MLX5_ST_SZ_DW(alloc_memic_out)] = {};
  95         u32 in[MLX5_ST_SZ_DW(alloc_memic_in)] = {};
  96         u32 mlx5_alignment;
  97         u64 page_idx = 0;
  98         int ret = 0;
  99 
 100         if (!length || (length & MLX5_MEMIC_ALLOC_SIZE_MASK))
 101                 return -EINVAL;
 102 
 103         /* mlx5 device sets alignment as 64*2^driver_value
 104          * so normalizing is needed.
 105          */
 106         mlx5_alignment = (alignment < MLX5_MEMIC_BASE_ALIGN) ? 0 :
 107                          alignment - MLX5_MEMIC_BASE_ALIGN;
 108         if (mlx5_alignment > max_alignment)
 109                 return -EINVAL;
 110 
 111         MLX5_SET(alloc_memic_in, in, opcode, MLX5_CMD_OP_ALLOC_MEMIC);
 112         MLX5_SET(alloc_memic_in, in, range_size, num_pages * PAGE_SIZE);
 113         MLX5_SET(alloc_memic_in, in, memic_size, length);
 114         MLX5_SET(alloc_memic_in, in, log_memic_addr_alignment,
 115                  mlx5_alignment);
 116 
 117         while (page_idx < num_memic_hw_pages) {
 118                 spin_lock(&dm->lock);
 119                 page_idx = bitmap_find_next_zero_area(dm->memic_alloc_pages,
 120                                                       num_memic_hw_pages,
 121                                                       page_idx,
 122                                                       num_pages, 0);
 123 
 124                 if (page_idx < num_memic_hw_pages)
 125                         bitmap_set(dm->memic_alloc_pages,
 126                                    page_idx, num_pages);
 127 
 128                 spin_unlock(&dm->lock);
 129 
 130                 if (page_idx >= num_memic_hw_pages)
 131                         break;
 132 
 133                 MLX5_SET64(alloc_memic_in, in, range_start_addr,
 134                            hw_start_addr + (page_idx * PAGE_SIZE));
 135 
 136                 ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 137                 if (ret) {
 138                         spin_lock(&dm->lock);
 139                         bitmap_clear(dm->memic_alloc_pages,
 140                                      page_idx, num_pages);
 141                         spin_unlock(&dm->lock);
 142 
 143                         if (ret == -EAGAIN) {
 144                                 page_idx++;
 145                                 continue;
 146                         }
 147 
 148                         return ret;
 149                 }
 150 
 151                 *addr = dev->bar_addr +
 152                         MLX5_GET64(alloc_memic_out, out, memic_start_addr);
 153 
 154                 return 0;
 155         }
 156 
 157         return -ENOMEM;
 158 }
 159 
 160 int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length)
 161 {
 162         struct mlx5_core_dev *dev = dm->dev;
 163         u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr);
 164         u32 num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
 165         u32 out[MLX5_ST_SZ_DW(dealloc_memic_out)] = {0};
 166         u32 in[MLX5_ST_SZ_DW(dealloc_memic_in)] = {0};
 167         u64 start_page_idx;
 168         int err;
 169 
 170         addr -= dev->bar_addr;
 171         start_page_idx = (addr - hw_start_addr) >> PAGE_SHIFT;
 172 
 173         MLX5_SET(dealloc_memic_in, in, opcode, MLX5_CMD_OP_DEALLOC_MEMIC);
 174         MLX5_SET64(dealloc_memic_in, in, memic_start_addr, addr);
 175         MLX5_SET(dealloc_memic_in, in, memic_size, length);
 176 
 177         err =  mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 178 
 179         if (!err) {
 180                 spin_lock(&dm->lock);
 181                 bitmap_clear(dm->memic_alloc_pages,
 182                              start_page_idx, num_pages);
 183                 spin_unlock(&dm->lock);
 184         }
 185 
 186         return err;
 187 }
 188 
 189 int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out)
 190 {
 191         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
 192         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
 193 
 194         MLX5_SET(ppcnt_reg, in, local_port, 1);
 195 
 196         MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP);
 197         return  mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPCNT,
 198                                      0, 0);
 199 }
 200 
 201 void mlx5_cmd_destroy_tir(struct mlx5_core_dev *dev, u32 tirn, u16 uid)
 202 {
 203         u32 in[MLX5_ST_SZ_DW(destroy_tir_in)]   = {};
 204         u32 out[MLX5_ST_SZ_DW(destroy_tir_out)] = {};
 205 
 206         MLX5_SET(destroy_tir_in, in, opcode, MLX5_CMD_OP_DESTROY_TIR);
 207         MLX5_SET(destroy_tir_in, in, tirn, tirn);
 208         MLX5_SET(destroy_tir_in, in, uid, uid);
 209         mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 210 }
 211 
 212 void mlx5_cmd_destroy_tis(struct mlx5_core_dev *dev, u32 tisn, u16 uid)
 213 {
 214         u32 in[MLX5_ST_SZ_DW(destroy_tis_in)]   = {0};
 215         u32 out[MLX5_ST_SZ_DW(destroy_tis_out)] = {0};
 216 
 217         MLX5_SET(destroy_tis_in, in, opcode, MLX5_CMD_OP_DESTROY_TIS);
 218         MLX5_SET(destroy_tis_in, in, tisn, tisn);
 219         MLX5_SET(destroy_tis_in, in, uid, uid);
 220         mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 221 }
 222 
 223 void mlx5_cmd_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn, u16 uid)
 224 {
 225         u32 in[MLX5_ST_SZ_DW(destroy_rqt_in)]   = {};
 226         u32 out[MLX5_ST_SZ_DW(destroy_rqt_out)] = {};
 227 
 228         MLX5_SET(destroy_rqt_in, in, opcode, MLX5_CMD_OP_DESTROY_RQT);
 229         MLX5_SET(destroy_rqt_in, in, rqtn, rqtn);
 230         MLX5_SET(destroy_rqt_in, in, uid, uid);
 231         mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 232 }
 233 
 234 int mlx5_cmd_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn,
 235                                     u16 uid)
 236 {
 237         u32 in[MLX5_ST_SZ_DW(alloc_transport_domain_in)]   = {0};
 238         u32 out[MLX5_ST_SZ_DW(alloc_transport_domain_out)] = {0};
 239         int err;
 240 
 241         MLX5_SET(alloc_transport_domain_in, in, opcode,
 242                  MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN);
 243         MLX5_SET(alloc_transport_domain_in, in, uid, uid);
 244 
 245         err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 246         if (!err)
 247                 *tdn = MLX5_GET(alloc_transport_domain_out, out,
 248                                 transport_domain);
 249 
 250         return err;
 251 }
 252 
 253 void mlx5_cmd_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn,
 254                                        u16 uid)
 255 {
 256         u32 in[MLX5_ST_SZ_DW(dealloc_transport_domain_in)]   = {0};
 257         u32 out[MLX5_ST_SZ_DW(dealloc_transport_domain_out)] = {0};
 258 
 259         MLX5_SET(dealloc_transport_domain_in, in, opcode,
 260                  MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN);
 261         MLX5_SET(dealloc_transport_domain_in, in, uid, uid);
 262         MLX5_SET(dealloc_transport_domain_in, in, transport_domain, tdn);
 263         mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 264 }
 265 
 266 void mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid)
 267 {
 268         u32 out[MLX5_ST_SZ_DW(dealloc_pd_out)] = {};
 269         u32 in[MLX5_ST_SZ_DW(dealloc_pd_in)]   = {};
 270 
 271         MLX5_SET(dealloc_pd_in, in, opcode, MLX5_CMD_OP_DEALLOC_PD);
 272         MLX5_SET(dealloc_pd_in, in, pd, pdn);
 273         MLX5_SET(dealloc_pd_in, in, uid, uid);
 274         mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 275 }
 276 
 277 int mlx5_cmd_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid,
 278                         u32 qpn, u16 uid)
 279 {
 280         u32 out[MLX5_ST_SZ_DW(attach_to_mcg_out)] = {};
 281         u32 in[MLX5_ST_SZ_DW(attach_to_mcg_in)]   = {};
 282         void *gid;
 283 
 284         MLX5_SET(attach_to_mcg_in, in, opcode, MLX5_CMD_OP_ATTACH_TO_MCG);
 285         MLX5_SET(attach_to_mcg_in, in, qpn, qpn);
 286         MLX5_SET(attach_to_mcg_in, in, uid, uid);
 287         gid = MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid);
 288         memcpy(gid, mgid, sizeof(*mgid));
 289         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 290 }
 291 
 292 int mlx5_cmd_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid,
 293                         u32 qpn, u16 uid)
 294 {
 295         u32 out[MLX5_ST_SZ_DW(detach_from_mcg_out)] = {};
 296         u32 in[MLX5_ST_SZ_DW(detach_from_mcg_in)]   = {};
 297         void *gid;
 298 
 299         MLX5_SET(detach_from_mcg_in, in, opcode, MLX5_CMD_OP_DETACH_FROM_MCG);
 300         MLX5_SET(detach_from_mcg_in, in, qpn, qpn);
 301         MLX5_SET(detach_from_mcg_in, in, uid, uid);
 302         gid = MLX5_ADDR_OF(detach_from_mcg_in, in, multicast_gid);
 303         memcpy(gid, mgid, sizeof(*mgid));
 304         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 305 }
 306 
 307 int mlx5_cmd_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn, u16 uid)
 308 {
 309         u32 out[MLX5_ST_SZ_DW(alloc_xrcd_out)] = {};
 310         u32 in[MLX5_ST_SZ_DW(alloc_xrcd_in)]   = {};
 311         int err;
 312 
 313         MLX5_SET(alloc_xrcd_in, in, opcode, MLX5_CMD_OP_ALLOC_XRCD);
 314         MLX5_SET(alloc_xrcd_in, in, uid, uid);
 315         err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 316         if (!err)
 317                 *xrcdn = MLX5_GET(alloc_xrcd_out, out, xrcd);
 318         return err;
 319 }
 320 
 321 int mlx5_cmd_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn, u16 uid)
 322 {
 323         u32 out[MLX5_ST_SZ_DW(dealloc_xrcd_out)] = {};
 324         u32 in[MLX5_ST_SZ_DW(dealloc_xrcd_in)]   = {};
 325 
 326         MLX5_SET(dealloc_xrcd_in, in, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
 327         MLX5_SET(dealloc_xrcd_in, in, xrcd, xrcdn);
 328         MLX5_SET(dealloc_xrcd_in, in, uid, uid);
 329         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 330 }
 331 
 332 int mlx5_cmd_alloc_q_counter(struct mlx5_core_dev *dev, u16 *counter_id,
 333                              u16 uid)
 334 {
 335         u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)]   = {0};
 336         u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {0};
 337         int err;
 338 
 339         MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
 340         MLX5_SET(alloc_q_counter_in, in, uid, uid);
 341 
 342         err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 343         if (!err)
 344                 *counter_id = MLX5_GET(alloc_q_counter_out, out,
 345                                        counter_set_id);
 346         return err;
 347 }
 348 
 349 int mlx5_cmd_mad_ifc(struct mlx5_core_dev *dev, const void *inb, void *outb,
 350                      u16 opmod, u8 port)
 351 {
 352         int outlen = MLX5_ST_SZ_BYTES(mad_ifc_out);
 353         int inlen = MLX5_ST_SZ_BYTES(mad_ifc_in);
 354         int err = -ENOMEM;
 355         void *data;
 356         void *resp;
 357         u32 *out;
 358         u32 *in;
 359 
 360         in = kzalloc(inlen, GFP_KERNEL);
 361         out = kzalloc(outlen, GFP_KERNEL);
 362         if (!in || !out)
 363                 goto out;
 364 
 365         MLX5_SET(mad_ifc_in, in, opcode, MLX5_CMD_OP_MAD_IFC);
 366         MLX5_SET(mad_ifc_in, in, op_mod, opmod);
 367         MLX5_SET(mad_ifc_in, in, port, port);
 368 
 369         data = MLX5_ADDR_OF(mad_ifc_in, in, mad);
 370         memcpy(data, inb, MLX5_FLD_SZ_BYTES(mad_ifc_in, mad));
 371 
 372         err = mlx5_cmd_exec(dev, in, inlen, out, outlen);
 373         if (err)
 374                 goto out;
 375 
 376         resp = MLX5_ADDR_OF(mad_ifc_out, out, response_mad_packet);
 377         memcpy(outb, resp,
 378                MLX5_FLD_SZ_BYTES(mad_ifc_out, response_mad_packet));
 379 
 380 out:
 381         kfree(out);
 382         kfree(in);
 383         return err;
 384 }

/* [<][>][^][v][top][bottom][index][help] */