1 /* 2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd. 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 <linux/mlx5/driver.h> 34 #include "mlx5_core.h" 35 #include <linux/mlx5/transobj.h> 36 37 int mlx5_core_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn) 38 { 39 u32 in[MLX5_ST_SZ_DW(alloc_transport_domain_in)]; 40 u32 out[MLX5_ST_SZ_DW(alloc_transport_domain_out)]; 41 int err; 42 43 memset(in, 0, sizeof(in)); 44 memset(out, 0, sizeof(out)); 45 46 MLX5_SET(alloc_transport_domain_in, in, opcode, 47 MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN); 48 49 err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); 50 if (!err) 51 *tdn = MLX5_GET(alloc_transport_domain_out, out, 52 transport_domain); 53 54 return err; 55 } 56 EXPORT_SYMBOL(mlx5_core_alloc_transport_domain); 57 58 void mlx5_core_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn) 59 { 60 u32 in[MLX5_ST_SZ_DW(dealloc_transport_domain_in)]; 61 u32 out[MLX5_ST_SZ_DW(dealloc_transport_domain_out)]; 62 63 memset(in, 0, sizeof(in)); 64 memset(out, 0, sizeof(out)); 65 66 MLX5_SET(dealloc_transport_domain_in, in, opcode, 67 MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN); 68 MLX5_SET(dealloc_transport_domain_in, in, transport_domain, tdn); 69 70 mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); 71 } 72 EXPORT_SYMBOL(mlx5_core_dealloc_transport_domain); 73 74 int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn) 75 { 76 u32 out[MLX5_ST_SZ_DW(create_rq_out)]; 77 int err; 78 79 MLX5_SET(create_rq_in, in, opcode, MLX5_CMD_OP_CREATE_RQ); 80 81 memset(out, 0, sizeof(out)); 82 err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 83 if (!err) 84 *rqn = MLX5_GET(create_rq_out, out, rqn); 85 86 return err; 87 } 88 89 int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen) 90 { 91 u32 out[MLX5_ST_SZ_DW(modify_rq_out)]; 92 93 MLX5_SET(modify_rq_in, in, rqn, rqn); 94 MLX5_SET(modify_rq_in, in, opcode, MLX5_CMD_OP_MODIFY_RQ); 95 96 memset(out, 0, sizeof(out)); 97 return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 98 } 99 EXPORT_SYMBOL(mlx5_core_modify_rq); 100 101 void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn) 102 { 103 u32 in[MLX5_ST_SZ_DW(destroy_rq_in)]; 104 u32 out[MLX5_ST_SZ_DW(destroy_rq_out)]; 105 106 memset(in, 0, sizeof(in)); 107 108 MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ); 109 MLX5_SET(destroy_rq_in, in, rqn, rqn); 110 111 mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); 112 } 113 114 int mlx5_core_query_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *out) 115 { 116 u32 in[MLX5_ST_SZ_DW(query_rq_in)] = {0}; 117 int outlen = MLX5_ST_SZ_BYTES(query_rq_out); 118 119 MLX5_SET(query_rq_in, in, opcode, MLX5_CMD_OP_QUERY_RQ); 120 MLX5_SET(query_rq_in, in, rqn, rqn); 121 122 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen); 123 } 124 EXPORT_SYMBOL(mlx5_core_query_rq); 125 126 int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn) 127 { 128 u32 out[MLX5_ST_SZ_DW(create_sq_out)]; 129 int err; 130 131 MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ); 132 133 memset(out, 0, sizeof(out)); 134 err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 135 if (!err) 136 *sqn = MLX5_GET(create_sq_out, out, sqn); 137 138 return err; 139 } 140 141 int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen) 142 { 143 u32 out[MLX5_ST_SZ_DW(modify_sq_out)]; 144 145 MLX5_SET(modify_sq_in, in, sqn, sqn); 146 MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ); 147 148 memset(out, 0, sizeof(out)); 149 return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 150 } 151 EXPORT_SYMBOL(mlx5_core_modify_sq); 152 153 void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn) 154 { 155 u32 in[MLX5_ST_SZ_DW(destroy_sq_in)]; 156 u32 out[MLX5_ST_SZ_DW(destroy_sq_out)]; 157 158 memset(in, 0, sizeof(in)); 159 160 MLX5_SET(destroy_sq_in, in, opcode, MLX5_CMD_OP_DESTROY_SQ); 161 MLX5_SET(destroy_sq_in, in, sqn, sqn); 162 163 mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); 164 } 165 166 int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out) 167 { 168 u32 in[MLX5_ST_SZ_DW(query_sq_in)] = {0}; 169 int outlen = MLX5_ST_SZ_BYTES(query_sq_out); 170 171 MLX5_SET(query_sq_in, in, opcode, MLX5_CMD_OP_QUERY_SQ); 172 MLX5_SET(query_sq_in, in, sqn, sqn); 173 174 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen); 175 } 176 EXPORT_SYMBOL(mlx5_core_query_sq); 177 178 int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen, 179 u32 *tirn) 180 { 181 u32 out[MLX5_ST_SZ_DW(create_tir_out)]; 182 int err; 183 184 MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR); 185 186 memset(out, 0, sizeof(out)); 187 err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 188 if (!err) 189 *tirn = MLX5_GET(create_tir_out, out, tirn); 190 191 return err; 192 } 193 EXPORT_SYMBOL(mlx5_core_create_tir); 194 195 int mlx5_core_modify_tir(struct mlx5_core_dev *dev, u32 tirn, u32 *in, 196 int inlen) 197 { 198 u32 out[MLX5_ST_SZ_DW(modify_tir_out)]; 199 200 MLX5_SET(modify_tir_in, in, tirn, tirn); 201 MLX5_SET(modify_tir_in, in, opcode, MLX5_CMD_OP_MODIFY_TIR); 202 203 memset(out, 0, sizeof(out)); 204 return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 205 } 206 207 void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn) 208 { 209 u32 in[MLX5_ST_SZ_DW(destroy_tir_in)]; 210 u32 out[MLX5_ST_SZ_DW(destroy_tir_out)]; 211 212 memset(in, 0, sizeof(in)); 213 214 MLX5_SET(destroy_tir_in, in, opcode, MLX5_CMD_OP_DESTROY_TIR); 215 MLX5_SET(destroy_tir_in, in, tirn, tirn); 216 217 mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); 218 } 219 EXPORT_SYMBOL(mlx5_core_destroy_tir); 220 221 int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen, 222 u32 *tisn) 223 { 224 u32 out[MLX5_ST_SZ_DW(create_tis_out)]; 225 int err; 226 227 MLX5_SET(create_tis_in, in, opcode, MLX5_CMD_OP_CREATE_TIS); 228 229 memset(out, 0, sizeof(out)); 230 err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 231 if (!err) 232 *tisn = MLX5_GET(create_tis_out, out, tisn); 233 234 return err; 235 } 236 EXPORT_SYMBOL(mlx5_core_create_tis); 237 238 int mlx5_core_modify_tis(struct mlx5_core_dev *dev, u32 tisn, u32 *in, 239 int inlen) 240 { 241 u32 out[MLX5_ST_SZ_DW(modify_tis_out)] = {0}; 242 243 MLX5_SET(modify_tis_in, in, tisn, tisn); 244 MLX5_SET(modify_tis_in, in, opcode, MLX5_CMD_OP_MODIFY_TIS); 245 246 return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 247 } 248 EXPORT_SYMBOL(mlx5_core_modify_tis); 249 250 void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn) 251 { 252 u32 in[MLX5_ST_SZ_DW(destroy_tis_in)]; 253 u32 out[MLX5_ST_SZ_DW(destroy_tis_out)]; 254 255 memset(in, 0, sizeof(in)); 256 257 MLX5_SET(destroy_tis_in, in, opcode, MLX5_CMD_OP_DESTROY_TIS); 258 MLX5_SET(destroy_tis_in, in, tisn, tisn); 259 260 mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); 261 } 262 EXPORT_SYMBOL(mlx5_core_destroy_tis); 263 264 int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen, 265 u32 *rmpn) 266 { 267 u32 out[MLX5_ST_SZ_DW(create_rmp_out)]; 268 int err; 269 270 MLX5_SET(create_rmp_in, in, opcode, MLX5_CMD_OP_CREATE_RMP); 271 272 memset(out, 0, sizeof(out)); 273 err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 274 if (!err) 275 *rmpn = MLX5_GET(create_rmp_out, out, rmpn); 276 277 return err; 278 } 279 280 int mlx5_core_modify_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen) 281 { 282 u32 out[MLX5_ST_SZ_DW(modify_rmp_out)]; 283 284 MLX5_SET(modify_rmp_in, in, opcode, MLX5_CMD_OP_MODIFY_RMP); 285 286 memset(out, 0, sizeof(out)); 287 return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 288 } 289 290 int mlx5_core_destroy_rmp(struct mlx5_core_dev *dev, u32 rmpn) 291 { 292 u32 in[MLX5_ST_SZ_DW(destroy_rmp_in)]; 293 u32 out[MLX5_ST_SZ_DW(destroy_rmp_out)]; 294 295 memset(in, 0, sizeof(in)); 296 297 MLX5_SET(destroy_rmp_in, in, opcode, MLX5_CMD_OP_DESTROY_RMP); 298 MLX5_SET(destroy_rmp_in, in, rmpn, rmpn); 299 300 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, 301 sizeof(out)); 302 } 303 304 int mlx5_core_query_rmp(struct mlx5_core_dev *dev, u32 rmpn, u32 *out) 305 { 306 u32 in[MLX5_ST_SZ_DW(query_rmp_in)]; 307 int outlen = MLX5_ST_SZ_BYTES(query_rmp_out); 308 309 memset(in, 0, sizeof(in)); 310 MLX5_SET(query_rmp_in, in, opcode, MLX5_CMD_OP_QUERY_RMP); 311 MLX5_SET(query_rmp_in, in, rmpn, rmpn); 312 313 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen); 314 } 315 316 int mlx5_core_arm_rmp(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm) 317 { 318 void *in; 319 void *rmpc; 320 void *wq; 321 void *bitmask; 322 int err; 323 324 in = mlx5_vzalloc(MLX5_ST_SZ_BYTES(modify_rmp_in)); 325 if (!in) 326 return -ENOMEM; 327 328 rmpc = MLX5_ADDR_OF(modify_rmp_in, in, ctx); 329 bitmask = MLX5_ADDR_OF(modify_rmp_in, in, bitmask); 330 wq = MLX5_ADDR_OF(rmpc, rmpc, wq); 331 332 MLX5_SET(modify_rmp_in, in, rmp_state, MLX5_RMPC_STATE_RDY); 333 MLX5_SET(modify_rmp_in, in, rmpn, rmpn); 334 MLX5_SET(wq, wq, lwm, lwm); 335 MLX5_SET(rmp_bitmask, bitmask, lwm, 1); 336 MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_RDY); 337 338 err = mlx5_core_modify_rmp(dev, in, MLX5_ST_SZ_BYTES(modify_rmp_in)); 339 340 kvfree(in); 341 342 return err; 343 } 344 345 int mlx5_core_create_xsrq(struct mlx5_core_dev *dev, u32 *in, int inlen, 346 u32 *xsrqn) 347 { 348 u32 out[MLX5_ST_SZ_DW(create_xrc_srq_out)]; 349 int err; 350 351 MLX5_SET(create_xrc_srq_in, in, opcode, MLX5_CMD_OP_CREATE_XRC_SRQ); 352 353 memset(out, 0, sizeof(out)); 354 err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 355 if (!err) 356 *xsrqn = MLX5_GET(create_xrc_srq_out, out, xrc_srqn); 357 358 return err; 359 } 360 361 int mlx5_core_destroy_xsrq(struct mlx5_core_dev *dev, u32 xsrqn) 362 { 363 u32 in[MLX5_ST_SZ_DW(destroy_xrc_srq_in)]; 364 u32 out[MLX5_ST_SZ_DW(destroy_xrc_srq_out)]; 365 366 memset(in, 0, sizeof(in)); 367 memset(out, 0, sizeof(out)); 368 369 MLX5_SET(destroy_xrc_srq_in, in, opcode, MLX5_CMD_OP_DESTROY_XRC_SRQ); 370 MLX5_SET(destroy_xrc_srq_in, in, xrc_srqn, xsrqn); 371 372 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, 373 sizeof(out)); 374 } 375 376 int mlx5_core_query_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u32 *out) 377 { 378 u32 in[MLX5_ST_SZ_DW(query_xrc_srq_in)]; 379 void *srqc; 380 void *xrc_srqc; 381 int err; 382 383 memset(in, 0, sizeof(in)); 384 MLX5_SET(query_xrc_srq_in, in, opcode, MLX5_CMD_OP_QUERY_XRC_SRQ); 385 MLX5_SET(query_xrc_srq_in, in, xrc_srqn, xsrqn); 386 387 err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), 388 out, 389 MLX5_ST_SZ_BYTES(query_xrc_srq_out)); 390 if (!err) { 391 xrc_srqc = MLX5_ADDR_OF(query_xrc_srq_out, out, 392 xrc_srq_context_entry); 393 srqc = MLX5_ADDR_OF(query_srq_out, out, srq_context_entry); 394 memcpy(srqc, xrc_srqc, MLX5_ST_SZ_BYTES(srqc)); 395 } 396 397 return err; 398 } 399 400 int mlx5_core_arm_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u16 lwm) 401 { 402 u32 in[MLX5_ST_SZ_DW(arm_xrc_srq_in)]; 403 u32 out[MLX5_ST_SZ_DW(arm_xrc_srq_out)]; 404 405 memset(in, 0, sizeof(in)); 406 memset(out, 0, sizeof(out)); 407 408 MLX5_SET(arm_xrc_srq_in, in, opcode, MLX5_CMD_OP_ARM_XRC_SRQ); 409 MLX5_SET(arm_xrc_srq_in, in, xrc_srqn, xsrqn); 410 MLX5_SET(arm_xrc_srq_in, in, lwm, lwm); 411 MLX5_SET(arm_xrc_srq_in, in, op_mod, 412 MLX5_ARM_XRC_SRQ_IN_OP_MOD_XRC_SRQ); 413 414 return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, 415 sizeof(out)); 416 } 417 418 int mlx5_core_create_rqt(struct mlx5_core_dev *dev, u32 *in, int inlen, 419 u32 *rqtn) 420 { 421 u32 out[MLX5_ST_SZ_DW(create_rqt_out)]; 422 int err; 423 424 MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT); 425 426 memset(out, 0, sizeof(out)); 427 err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 428 if (!err) 429 *rqtn = MLX5_GET(create_rqt_out, out, rqtn); 430 431 return err; 432 } 433 434 int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in, 435 int inlen) 436 { 437 u32 out[MLX5_ST_SZ_DW(modify_rqt_out)]; 438 439 MLX5_SET(modify_rqt_in, in, rqtn, rqtn); 440 MLX5_SET(modify_rqt_in, in, opcode, MLX5_CMD_OP_MODIFY_RQT); 441 442 memset(out, 0, sizeof(out)); 443 return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out)); 444 } 445 446 void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn) 447 { 448 u32 in[MLX5_ST_SZ_DW(destroy_rqt_in)]; 449 u32 out[MLX5_ST_SZ_DW(destroy_rqt_out)]; 450 451 memset(in, 0, sizeof(in)); 452 453 MLX5_SET(destroy_rqt_in, in, opcode, MLX5_CMD_OP_DESTROY_RQT); 454 MLX5_SET(destroy_rqt_in, in, rqtn, rqtn); 455 456 mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); 457 } 458