int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr) { struct mlx5_mr_table *table = &dev->priv.mr_table; struct mlx5_destroy_mkey_mbox_in in; struct mlx5_destroy_mkey_mbox_out out; struct mlx5_core_mr *deleted_mr; unsigned long flags; int err; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); write_lock_irqsave(&table->lock, flags); deleted_mr = radix_tree_delete(&table->tree, mlx5_base_mkey(mr->key)); write_unlock_irqrestore(&table->lock, flags); if (!deleted_mr) { mlx5_core_warn(dev, "failed radix tree delete of mr 0x%x\n", mlx5_base_mkey(mr->key)); return -ENOENT; } in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_MKEY); in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mr->key)); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) return err; if (out.hdr.status) return mlx5_cmd_status_to_err(&out.hdr); return err; }
int mlx5_core_set_dc_cnak_trace(struct mlx5_core_dev *dev, int enable, u64 addr) { struct mlx5_cmd_set_dc_cnak_mbox_in *in; struct mlx5_cmd_set_dc_cnak_mbox_out out; int err; in = kzalloc(sizeof(*in), GFP_KERNEL); if (!in) return -ENOMEM; memset(&out, 0, sizeof(out)); in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_SET_DC_CNAK_TRACE); in->enable = !!enable << 7; in->pa = cpu_to_be64(addr); err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out)); if (err) goto out; if (out.hdr.status) err = mlx5_cmd_status_to_err(&out.hdr); out: kfree(in); return err; }
int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn, int npsvs, u32 *sig_index) { struct mlx5_allocate_psv_in in; struct mlx5_allocate_psv_out out; int i, err; if (npsvs > MLX5_MAX_PSVS) return -EINVAL; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_PSV); in.npsv_pd = cpu_to_be32((npsvs << 28) | pdn); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) { mlx5_core_err(dev, "cmd exec failed %d\n", err); return err; } if (out.hdr.status) { mlx5_core_err(dev, "create_psv bad status %d\n", out.hdr.status); return mlx5_cmd_status_to_err(&out.hdr); } for (i = 0; i < npsvs; i++) sig_index[i] = be32_to_cpu(out.psv_idx[i]) & 0xffffff; return err; }
int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num) { struct mlx5_destroy_psv_in in; struct mlx5_destroy_psv_out out; int err; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.psv_number = cpu_to_be32(psv_num); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_PSV); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) { mlx5_core_err(dev, "destroy_psv cmd exec failed %d\n", err); goto out; } if (out.hdr.status) { mlx5_core_err(dev, "destroy_psv bad status %d\n", out.hdr.status); err = mlx5_cmd_status_to_err(&out.hdr); goto out; } out: return err; }
int mlx5_core_create_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mkey *mkey, struct mlx5_create_mkey_mbox_in *in, int inlen, mlx5_cmd_cbk_t callback, void *context, struct mlx5_create_mkey_mbox_out *out) { struct mlx5_mkey_table *table = &dev->priv.mkey_table; struct mlx5_create_mkey_mbox_out lout; int err; u8 key; memset(&lout, 0, sizeof(lout)); spin_lock_irq(&dev->priv.mkey_lock); key = dev->priv.mkey_key++; spin_unlock_irq(&dev->priv.mkey_lock); in->seg.qpn_mkey7_0 |= cpu_to_be32(key); in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_MKEY); if (callback) { err = mlx5_cmd_exec_cb(dev, in, inlen, out, sizeof(*out), callback, context); return err; } else { err = mlx5_cmd_exec(dev, in, inlen, &lout, sizeof(lout)); } if (err) { mlx5_core_dbg(dev, "cmd exec failed %d\n", err); return err; } if (lout.hdr.status) { mlx5_core_dbg(dev, "status %d\n", lout.hdr.status); return mlx5_cmd_status_to_err(&lout.hdr); } mkey->iova = be64_to_cpu(in->seg.start_addr); mkey->size = be64_to_cpu(in->seg.len); mkey->key = mlx5_idx_to_mkey(be32_to_cpu(lout.mkey) & 0xffffff) | key; mkey->pd = be32_to_cpu(in->seg.flags_pd) & 0xffffff; mlx5_core_dbg(dev, "out 0x%x, key 0x%x, mkey 0x%x\n", be32_to_cpu(lout.mkey), key, mkey->key); /* connect to mkey tree */ write_lock_irq(&table->lock); err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key), mkey); write_unlock_irq(&table->lock); if (err) { mlx5_core_warn(dev, "failed radix tree insert of mkey 0x%x, %d\n", mlx5_base_mkey(mkey->key), err); mlx5_core_destroy_mkey(dev, mkey); } return err; }
int mlx5_core_create_dct(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct, struct mlx5_create_dct_mbox_in *in) { struct mlx5_qp_table *table = &dev->priv.qp_table; struct mlx5_create_dct_mbox_out out; struct mlx5_destroy_dct_mbox_in din; struct mlx5_destroy_dct_mbox_out dout; int err; init_completion(&dct->drained); memset(&out, 0, sizeof(out)); in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_DCT); err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out)); if (err) { mlx5_core_warn(dev, "create DCT failed, ret %d", err); return err; } if (out.hdr.status) return mlx5_cmd_status_to_err(dev, &out.hdr); dct->dctn = be32_to_cpu(out.dctn) & 0xffffff; dct->common.res = MLX5_RES_DCT; spin_lock_irq(&table->lock); err = radix_tree_insert(&table->tree, dct->dctn, dct); spin_unlock_irq(&table->lock); if (err) { mlx5_core_warn(dev, "err %d", err); goto err_cmd; } err = mlx5_debug_dct_add(dev, dct); if (err) mlx5_core_dbg(dev, "failed adding DCT 0x%x to debug file system\n", dct->dctn); dct->pid = current->pid; atomic_set(&dct->common.refcount, 1); init_completion(&dct->common.free); return 0; err_cmd: memset(&din, 0, sizeof(din)); memset(&dout, 0, sizeof(dout)); din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_DCT); din.dctn = cpu_to_be32(dct->dctn); mlx5_cmd_exec(dev, &din, sizeof(din), &out, sizeof(dout)); return err; }
int mlx5_core_create_qp(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp, struct mlx5_create_qp_mbox_in *in, int inlen) { struct mlx5_create_qp_mbox_out out; struct mlx5_destroy_qp_mbox_in din; struct mlx5_destroy_qp_mbox_out dout; int err; memset(&out, 0, sizeof(out)); in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_QP); err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out)); if (err) { mlx5_core_warn(dev, "ret %d\n", err); return err; } if (out.hdr.status) { mlx5_core_warn(dev, "current num of QPs 0x%x\n", atomic_read(&dev->num_qps)); return mlx5_cmd_status_to_err(dev, &out.hdr); } qp->qpn = be32_to_cpu(out.qpn) & 0xffffff; mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn); err = create_qprqsq_common(dev, qp, MLX5_RES_QP); if (err) goto err_cmd; err = mlx5_debug_qp_add(dev, qp); if (err) mlx5_core_dbg(dev, "failed adding QP 0x%x to debug file system\n", qp->qpn); atomic_inc(&dev->num_qps); return 0; err_cmd: memset(&din, 0, sizeof(din)); memset(&dout, 0, sizeof(dout)); din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_QP); din.qpn = cpu_to_be32(qp->qpn); mlx5_cmd_exec(dev, &din, sizeof(din), &out, sizeof(dout)); return err; }
int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, struct mlx5_modify_cq_mbox_in *in, int in_sz) { struct mlx5_modify_cq_mbox_out out; int err; memset(&out, 0, sizeof(out)); in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MODIFY_CQ); err = mlx5_cmd_exec(dev, in, in_sz, &out, sizeof(out)); if (err) return err; if (out.hdr.status) return mlx5_cmd_status_to_err(&out.hdr); return 0; }
int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, struct mlx5_create_cq_mbox_in *in, int inlen) { int err; struct mlx5_cq_table *table = &dev->priv.cq_table; struct mlx5_create_cq_mbox_out out; struct mlx5_destroy_cq_mbox_in din; struct mlx5_destroy_cq_mbox_out dout; in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_CQ); memset(&out, 0, sizeof(out)); err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out)); if (err) return err; if (out.hdr.status) return mlx5_cmd_status_to_err(&out.hdr); cq->cqn = be32_to_cpu(out.cqn) & 0xffffff; cq->cons_index = 0; cq->arm_sn = 0; atomic_set(&cq->refcount, 1); init_completion(&cq->free); spin_lock_irq(&table->lock); err = radix_tree_insert(&table->tree, cq->cqn, cq); spin_unlock_irq(&table->lock); if (err) goto err_cmd; cq->pid = current->pid; err = mlx5_debug_cq_add(dev, cq); if (err) mlx5_core_dbg(dev, "failed adding CP 0x%x to debug file system\n", cq->cqn); return 0; err_cmd: memset(&din, 0, sizeof(din)); memset(&dout, 0, sizeof(dout)); din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_CQ); mlx5_cmd_exec(dev, &din, sizeof(din), &dout, sizeof(dout)); return err; }
static int mlx5_core_disable_hca(struct mlx5_core_dev *dev) { int err; struct mlx5_disable_hca_mbox_in in; struct mlx5_disable_hca_mbox_out out; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DISABLE_HCA); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) return err; if (out.hdr.status) return mlx5_cmd_status_to_err(&out.hdr); return 0; }
int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn) { struct mlx5_free_uar_mbox_in in; struct mlx5_free_uar_mbox_out out; int err; memset(&in, 0, sizeof(in)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DEALLOC_UAR); in.uarn = cpu_to_be32(uarn); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) goto ex; if (out.hdr.status) err = mlx5_cmd_status_to_err(&out.hdr); ex: return err; }
int mlx5_core_query_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr, struct mlx5_query_mkey_mbox_out *out, int outlen) { struct mlx5_query_mkey_mbox_in in; int err; memset(&in, 0, sizeof(in)); memset(out, 0, outlen); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_MKEY); in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mr->key)); err = mlx5_cmd_exec(dev, &in, sizeof(in), out, outlen); if (err) return err; if (out->hdr.status) return mlx5_cmd_status_to_err(&out->hdr); return err; }
int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn) { struct mlx5_detach_mcg_mbox_in in; struct mlx5_detach_mcg_mbox_out out; int err; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DETTACH_FROM_MCG); memcpy(in.gid, mgid, sizeof(*mgid)); in.qpn = cpu_to_be32(qpn); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) return err; if (out.hdr.status) err = mlx5_cmd_status_to_err(&out.hdr); return err; }
int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr) { struct mlx5_destroy_mkey_mbox_in in; struct mlx5_destroy_mkey_mbox_out out; int err; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_MKEY); in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mr->key)); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) return err; if (out.hdr.status) return mlx5_cmd_status_to_err(&out.hdr); return err; }
int mlx5_core_query_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, struct mlx5_query_cq_mbox_out *out) { struct mlx5_query_cq_mbox_in in; int err; memset(&in, 0, sizeof(in)); memset(out, 0, sizeof(*out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_CQ); in.cqn = cpu_to_be32(cq->cqn); err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out)); if (err) return err; if (out->hdr.status) return mlx5_cmd_status_to_err(&out->hdr); return err; }
int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) { struct mlx5_cq_table *table = &dev->priv.cq_table; struct mlx5_destroy_cq_mbox_in in; struct mlx5_destroy_cq_mbox_out out; struct mlx5_core_cq *tmp; int err; spin_lock_irq(&table->lock); tmp = radix_tree_delete(&table->tree, cq->cqn); spin_unlock_irq(&table->lock); if (!tmp) { mlx5_core_warn(dev, "cq 0x%x not found in tree\n", cq->cqn); return -EINVAL; } if (tmp != cq) { mlx5_core_warn(dev, "corruption on srqn 0x%x\n", cq->cqn); return -EINVAL; } memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_CQ); in.cqn = cpu_to_be32(cq->cqn); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) return err; if (out.hdr.status) return mlx5_cmd_status_to_err(&out.hdr); synchronize_irq(cq->irqn); mlx5_debug_cq_remove(dev, cq); if (atomic_dec_and_test(&cq->refcount)) complete(&cq->free); wait_for_completion(&cq->free); return 0; }
int mlx5_core_dump_fill_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr, u32 *mkey) { struct mlx5_query_special_ctxs_mbox_in in; struct mlx5_query_special_ctxs_mbox_out out; int err; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) return err; if (out.hdr.status) return mlx5_cmd_status_to_err(&out.hdr); *mkey = be32_to_cpu(out.dump_fill_mkey); return err; }
int mlx5_core_create_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr, struct mlx5_create_mkey_mbox_in *in, int inlen, mlx5_cmd_cbk_t callback, void *context, struct mlx5_create_mkey_mbox_out *out) { struct mlx5_create_mkey_mbox_out lout; int err; u8 key; memset(&lout, 0, sizeof(lout)); spin_lock_irq(&dev->priv.mkey_lock); key = dev->priv.mkey_key++; spin_unlock_irq(&dev->priv.mkey_lock); in->seg.qpn_mkey7_0 |= cpu_to_be32(key); in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_MKEY); if (callback) { err = mlx5_cmd_exec_cb(dev, in, inlen, out, sizeof(*out), callback, context); return err; } else { err = mlx5_cmd_exec(dev, in, inlen, &lout, sizeof(lout)); } if (err) { mlx5_core_dbg(dev, "cmd exec faile %d\n", err); return err; } if (lout.hdr.status) { mlx5_core_dbg(dev, "status %d\n", lout.hdr.status); return mlx5_cmd_status_to_err(&lout.hdr); } mr->key = mlx5_idx_to_mkey(be32_to_cpu(lout.mkey) & 0xffffff) | key; mlx5_core_dbg(dev, "out 0x%x, key 0x%x, mkey 0x%x\n", be32_to_cpu(lout.mkey), key, mr->key); return err; }
int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in, int size_in, void *data_out, int size_out, u16 reg_num, int arg, int write) { struct mlx5_access_reg_mbox_in *in = NULL; struct mlx5_access_reg_mbox_out *out = NULL; int err = -ENOMEM; in = mlx5_vzalloc(sizeof(*in) + size_in); if (!in) return -ENOMEM; out = mlx5_vzalloc(sizeof(*out) + size_out); if (!out) goto ex1; memcpy(in->data, data_in, size_in); in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ACCESS_REG); in->hdr.opmod = cpu_to_be16(!write); in->arg = cpu_to_be32(arg); in->register_id = cpu_to_be16(reg_num); err = mlx5_cmd_exec(dev, in, sizeof(*in) + size_in, out, sizeof(*out) + size_out); if (err) goto ex2; if (out->hdr.status) err = mlx5_cmd_status_to_err(&out->hdr); if (!err) memcpy(data_out, out->data, size_out); ex2: kvfree(out); ex1: kvfree(in); return err; }
int mlx5_cmd_alloc_uar(struct mlx5_core_dev *dev, u32 *uarn) { struct mlx5_alloc_uar_mbox_in in; struct mlx5_alloc_uar_mbox_out out; int err; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ALLOC_UAR); err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); if (err) goto ex; if (out.hdr.status) { err = mlx5_cmd_status_to_err(&out.hdr); goto ex; } *uarn = be32_to_cpu(out.uarn) & 0xffffff; ex: return err; }
static int handle_hca_cap(struct mlx5_core_dev *dev) { struct mlx5_cmd_query_hca_cap_mbox_out *query_out = NULL; struct mlx5_cmd_set_hca_cap_mbox_in *set_ctx = NULL; struct mlx5_cmd_query_hca_cap_mbox_in query_ctx; struct mlx5_cmd_set_hca_cap_mbox_out set_out; u64 flags; int err; memset(&query_ctx, 0, sizeof(query_ctx)); query_out = kzalloc(sizeof(*query_out), GFP_KERNEL); if (!query_out) return -ENOMEM; set_ctx = kzalloc(sizeof(*set_ctx), GFP_KERNEL); if (!set_ctx) { err = -ENOMEM; goto query_ex; } query_ctx.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP); query_ctx.hdr.opmod = cpu_to_be16(HCA_CAP_OPMOD_GET_CUR); err = mlx5_cmd_exec(dev, &query_ctx, sizeof(query_ctx), query_out, sizeof(*query_out)); if (err) goto query_ex; err = mlx5_cmd_status_to_err(&query_out->hdr); if (err) { mlx5_core_warn(dev, "query hca cap failed, %d\n", err); goto query_ex; } copy_rw_fields(&set_ctx->hca_cap, &query_out->hca_cap); if (dev->profile->mask & MLX5_PROF_MASK_QP_SIZE) set_ctx->hca_cap.log_max_qp = dev->profile->log_max_qp; flags = be64_to_cpu(query_out->hca_cap.flags); /* disable checksum */ flags &= ~MLX5_DEV_CAP_FLAG_CMDIF_CSUM; set_ctx->hca_cap.flags = cpu_to_be64(flags); memset(&set_out, 0, sizeof(set_out)); set_ctx->hca_cap.log_uar_page_sz = cpu_to_be16(PAGE_SHIFT - 12); set_ctx->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_SET_HCA_CAP); err = mlx5_cmd_exec(dev, set_ctx, sizeof(*set_ctx), &set_out, sizeof(set_out)); if (err) { mlx5_core_warn(dev, "set hca cap failed, %d\n", err); goto query_ex; } err = mlx5_cmd_status_to_err(&set_out.hdr); if (err) goto query_ex; query_ex: kfree(query_out); kfree(set_ctx); return err; }