1*04876c12SAharon Landau // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2*04876c12SAharon Landau /* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */ 3*04876c12SAharon Landau 4*04876c12SAharon Landau #include "mlx5_ib.h" 5*04876c12SAharon Landau #include "umr.h" 6*04876c12SAharon Landau 7*04876c12SAharon Landau enum { 8*04876c12SAharon Landau MAX_UMR_WR = 128, 9*04876c12SAharon Landau }; 10*04876c12SAharon Landau 11*04876c12SAharon Landau static int mlx5r_umr_qp_rst2rts(struct mlx5_ib_dev *dev, struct ib_qp *qp) 12*04876c12SAharon Landau { 13*04876c12SAharon Landau struct ib_qp_attr attr = {}; 14*04876c12SAharon Landau int ret; 15*04876c12SAharon Landau 16*04876c12SAharon Landau attr.qp_state = IB_QPS_INIT; 17*04876c12SAharon Landau attr.port_num = 1; 18*04876c12SAharon Landau ret = ib_modify_qp(qp, &attr, 19*04876c12SAharon Landau IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT); 20*04876c12SAharon Landau if (ret) { 21*04876c12SAharon Landau mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n"); 22*04876c12SAharon Landau return ret; 23*04876c12SAharon Landau } 24*04876c12SAharon Landau 25*04876c12SAharon Landau memset(&attr, 0, sizeof(attr)); 26*04876c12SAharon Landau attr.qp_state = IB_QPS_RTR; 27*04876c12SAharon Landau 28*04876c12SAharon Landau ret = ib_modify_qp(qp, &attr, IB_QP_STATE); 29*04876c12SAharon Landau if (ret) { 30*04876c12SAharon Landau mlx5_ib_dbg(dev, "Couldn't modify umr QP to rtr\n"); 31*04876c12SAharon Landau return ret; 32*04876c12SAharon Landau } 33*04876c12SAharon Landau 34*04876c12SAharon Landau memset(&attr, 0, sizeof(attr)); 35*04876c12SAharon Landau attr.qp_state = IB_QPS_RTS; 36*04876c12SAharon Landau ret = ib_modify_qp(qp, &attr, IB_QP_STATE); 37*04876c12SAharon Landau if (ret) { 38*04876c12SAharon Landau mlx5_ib_dbg(dev, "Couldn't modify umr QP to rts\n"); 39*04876c12SAharon Landau return ret; 40*04876c12SAharon Landau } 41*04876c12SAharon Landau 42*04876c12SAharon Landau return 0; 43*04876c12SAharon Landau } 44*04876c12SAharon Landau 45*04876c12SAharon Landau int mlx5r_umr_resource_init(struct mlx5_ib_dev *dev) 46*04876c12SAharon Landau { 47*04876c12SAharon Landau struct ib_qp_init_attr init_attr = {}; 48*04876c12SAharon Landau struct ib_pd *pd; 49*04876c12SAharon Landau struct ib_cq *cq; 50*04876c12SAharon Landau struct ib_qp *qp; 51*04876c12SAharon Landau int ret; 52*04876c12SAharon Landau 53*04876c12SAharon Landau pd = ib_alloc_pd(&dev->ib_dev, 0); 54*04876c12SAharon Landau if (IS_ERR(pd)) { 55*04876c12SAharon Landau mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n"); 56*04876c12SAharon Landau return PTR_ERR(pd); 57*04876c12SAharon Landau } 58*04876c12SAharon Landau 59*04876c12SAharon Landau cq = ib_alloc_cq(&dev->ib_dev, NULL, 128, 0, IB_POLL_SOFTIRQ); 60*04876c12SAharon Landau if (IS_ERR(cq)) { 61*04876c12SAharon Landau mlx5_ib_dbg(dev, "Couldn't create CQ for sync UMR QP\n"); 62*04876c12SAharon Landau ret = PTR_ERR(cq); 63*04876c12SAharon Landau goto destroy_pd; 64*04876c12SAharon Landau } 65*04876c12SAharon Landau 66*04876c12SAharon Landau init_attr.send_cq = cq; 67*04876c12SAharon Landau init_attr.recv_cq = cq; 68*04876c12SAharon Landau init_attr.sq_sig_type = IB_SIGNAL_ALL_WR; 69*04876c12SAharon Landau init_attr.cap.max_send_wr = MAX_UMR_WR; 70*04876c12SAharon Landau init_attr.cap.max_send_sge = 1; 71*04876c12SAharon Landau init_attr.qp_type = MLX5_IB_QPT_REG_UMR; 72*04876c12SAharon Landau init_attr.port_num = 1; 73*04876c12SAharon Landau qp = ib_create_qp(pd, &init_attr); 74*04876c12SAharon Landau if (IS_ERR(qp)) { 75*04876c12SAharon Landau mlx5_ib_dbg(dev, "Couldn't create sync UMR QP\n"); 76*04876c12SAharon Landau ret = PTR_ERR(qp); 77*04876c12SAharon Landau goto destroy_cq; 78*04876c12SAharon Landau } 79*04876c12SAharon Landau 80*04876c12SAharon Landau ret = mlx5r_umr_qp_rst2rts(dev, qp); 81*04876c12SAharon Landau if (ret) 82*04876c12SAharon Landau goto destroy_qp; 83*04876c12SAharon Landau 84*04876c12SAharon Landau dev->umrc.qp = qp; 85*04876c12SAharon Landau dev->umrc.cq = cq; 86*04876c12SAharon Landau dev->umrc.pd = pd; 87*04876c12SAharon Landau 88*04876c12SAharon Landau sema_init(&dev->umrc.sem, MAX_UMR_WR); 89*04876c12SAharon Landau 90*04876c12SAharon Landau return 0; 91*04876c12SAharon Landau 92*04876c12SAharon Landau destroy_qp: 93*04876c12SAharon Landau ib_destroy_qp(qp); 94*04876c12SAharon Landau destroy_cq: 95*04876c12SAharon Landau ib_free_cq(cq); 96*04876c12SAharon Landau destroy_pd: 97*04876c12SAharon Landau ib_dealloc_pd(pd); 98*04876c12SAharon Landau return ret; 99*04876c12SAharon Landau } 100*04876c12SAharon Landau 101*04876c12SAharon Landau void mlx5r_umr_resource_cleanup(struct mlx5_ib_dev *dev) 102*04876c12SAharon Landau { 103*04876c12SAharon Landau ib_destroy_qp(dev->umrc.qp); 104*04876c12SAharon Landau ib_free_cq(dev->umrc.cq); 105*04876c12SAharon Landau ib_dealloc_pd(dev->umrc.pd); 106*04876c12SAharon Landau } 107