| .. | .. |
|---|
| 35 | 35 | struct mlx5_ib_gsi_wr { |
|---|
| 36 | 36 | struct ib_cqe cqe; |
|---|
| 37 | 37 | struct ib_wc wc; |
|---|
| 38 | | - int send_flags; |
|---|
| 39 | 38 | bool completed:1; |
|---|
| 40 | 39 | }; |
|---|
| 41 | | - |
|---|
| 42 | | -struct mlx5_ib_gsi_qp { |
|---|
| 43 | | - struct ib_qp ibqp; |
|---|
| 44 | | - struct ib_qp *rx_qp; |
|---|
| 45 | | - u8 port_num; |
|---|
| 46 | | - struct ib_qp_cap cap; |
|---|
| 47 | | - enum ib_sig_type sq_sig_type; |
|---|
| 48 | | - /* Serialize qp state modifications */ |
|---|
| 49 | | - struct mutex mutex; |
|---|
| 50 | | - struct ib_cq *cq; |
|---|
| 51 | | - struct mlx5_ib_gsi_wr *outstanding_wrs; |
|---|
| 52 | | - u32 outstanding_pi, outstanding_ci; |
|---|
| 53 | | - int num_qps; |
|---|
| 54 | | - /* Protects access to the tx_qps. Post send operations synchronize |
|---|
| 55 | | - * with tx_qp creation in setup_qp(). Also protects the |
|---|
| 56 | | - * outstanding_wrs array and indices. |
|---|
| 57 | | - */ |
|---|
| 58 | | - spinlock_t lock; |
|---|
| 59 | | - struct ib_qp **tx_qps; |
|---|
| 60 | | -}; |
|---|
| 61 | | - |
|---|
| 62 | | -static struct mlx5_ib_gsi_qp *gsi_qp(struct ib_qp *qp) |
|---|
| 63 | | -{ |
|---|
| 64 | | - return container_of(qp, struct mlx5_ib_gsi_qp, ibqp); |
|---|
| 65 | | -} |
|---|
| 66 | 40 | |
|---|
| 67 | 41 | static bool mlx5_ib_deth_sqpn_cap(struct mlx5_ib_dev *dev) |
|---|
| 68 | 42 | { |
|---|
| .. | .. |
|---|
| 70 | 44 | } |
|---|
| 71 | 45 | |
|---|
| 72 | 46 | /* Call with gsi->lock locked */ |
|---|
| 73 | | -static void generate_completions(struct mlx5_ib_gsi_qp *gsi) |
|---|
| 47 | +static void generate_completions(struct mlx5_ib_qp *mqp) |
|---|
| 74 | 48 | { |
|---|
| 75 | | - struct ib_cq *gsi_cq = gsi->ibqp.send_cq; |
|---|
| 49 | + struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; |
|---|
| 50 | + struct ib_cq *gsi_cq = mqp->ibqp.send_cq; |
|---|
| 76 | 51 | struct mlx5_ib_gsi_wr *wr; |
|---|
| 77 | 52 | u32 index; |
|---|
| 78 | 53 | |
|---|
| .. | .. |
|---|
| 83 | 58 | if (!wr->completed) |
|---|
| 84 | 59 | break; |
|---|
| 85 | 60 | |
|---|
| 86 | | - if (gsi->sq_sig_type == IB_SIGNAL_ALL_WR || |
|---|
| 87 | | - wr->send_flags & IB_SEND_SIGNALED) |
|---|
| 88 | | - WARN_ON_ONCE(mlx5_ib_generate_wc(gsi_cq, &wr->wc)); |
|---|
| 89 | | - |
|---|
| 61 | + WARN_ON_ONCE(mlx5_ib_generate_wc(gsi_cq, &wr->wc)); |
|---|
| 90 | 62 | wr->completed = false; |
|---|
| 91 | 63 | } |
|---|
| 92 | 64 | |
|---|
| .. | .. |
|---|
| 98 | 70 | struct mlx5_ib_gsi_qp *gsi = cq->cq_context; |
|---|
| 99 | 71 | struct mlx5_ib_gsi_wr *wr = |
|---|
| 100 | 72 | container_of(wc->wr_cqe, struct mlx5_ib_gsi_wr, cqe); |
|---|
| 73 | + struct mlx5_ib_qp *mqp = container_of(gsi, struct mlx5_ib_qp, gsi); |
|---|
| 101 | 74 | u64 wr_id; |
|---|
| 102 | 75 | unsigned long flags; |
|---|
| 103 | 76 | |
|---|
| .. | .. |
|---|
| 106 | 79 | wr_id = wr->wc.wr_id; |
|---|
| 107 | 80 | wr->wc = *wc; |
|---|
| 108 | 81 | wr->wc.wr_id = wr_id; |
|---|
| 109 | | - wr->wc.qp = &gsi->ibqp; |
|---|
| 82 | + wr->wc.qp = &mqp->ibqp; |
|---|
| 110 | 83 | |
|---|
| 111 | | - generate_completions(gsi); |
|---|
| 84 | + generate_completions(mqp); |
|---|
| 112 | 85 | spin_unlock_irqrestore(&gsi->lock, flags); |
|---|
| 113 | 86 | } |
|---|
| 114 | 87 | |
|---|
| 115 | | -struct ib_qp *mlx5_ib_gsi_create_qp(struct ib_pd *pd, |
|---|
| 116 | | - struct ib_qp_init_attr *init_attr) |
|---|
| 88 | +int mlx5_ib_create_gsi(struct ib_pd *pd, struct mlx5_ib_qp *mqp, |
|---|
| 89 | + struct ib_qp_init_attr *attr) |
|---|
| 117 | 90 | { |
|---|
| 118 | 91 | struct mlx5_ib_dev *dev = to_mdev(pd->device); |
|---|
| 119 | 92 | struct mlx5_ib_gsi_qp *gsi; |
|---|
| 120 | | - struct ib_qp_init_attr hw_init_attr = *init_attr; |
|---|
| 121 | | - const u8 port_num = init_attr->port_num; |
|---|
| 122 | | - const int num_pkeys = pd->device->attrs.max_pkeys; |
|---|
| 123 | | - const int num_qps = mlx5_ib_deth_sqpn_cap(dev) ? num_pkeys : 0; |
|---|
| 93 | + struct ib_qp_init_attr hw_init_attr = *attr; |
|---|
| 94 | + const u8 port_num = attr->port_num; |
|---|
| 95 | + int num_qps = 0; |
|---|
| 124 | 96 | int ret; |
|---|
| 125 | 97 | |
|---|
| 126 | | - mlx5_ib_dbg(dev, "creating GSI QP\n"); |
|---|
| 127 | | - |
|---|
| 128 | | - if (port_num > ARRAY_SIZE(dev->devr.ports) || port_num < 1) { |
|---|
| 129 | | - mlx5_ib_warn(dev, |
|---|
| 130 | | - "invalid port number %d during GSI QP creation\n", |
|---|
| 131 | | - port_num); |
|---|
| 132 | | - return ERR_PTR(-EINVAL); |
|---|
| 98 | + if (mlx5_ib_deth_sqpn_cap(dev)) { |
|---|
| 99 | + if (MLX5_CAP_GEN(dev->mdev, |
|---|
| 100 | + port_type) == MLX5_CAP_PORT_TYPE_IB) |
|---|
| 101 | + num_qps = pd->device->attrs.max_pkeys; |
|---|
| 102 | + else if (dev->lag_active) |
|---|
| 103 | + num_qps = MLX5_MAX_PORTS; |
|---|
| 133 | 104 | } |
|---|
| 134 | 105 | |
|---|
| 135 | | - gsi = kzalloc(sizeof(*gsi), GFP_KERNEL); |
|---|
| 136 | | - if (!gsi) |
|---|
| 137 | | - return ERR_PTR(-ENOMEM); |
|---|
| 138 | | - |
|---|
| 106 | + gsi = &mqp->gsi; |
|---|
| 139 | 107 | gsi->tx_qps = kcalloc(num_qps, sizeof(*gsi->tx_qps), GFP_KERNEL); |
|---|
| 140 | | - if (!gsi->tx_qps) { |
|---|
| 141 | | - ret = -ENOMEM; |
|---|
| 142 | | - goto err_free; |
|---|
| 143 | | - } |
|---|
| 108 | + if (!gsi->tx_qps) |
|---|
| 109 | + return -ENOMEM; |
|---|
| 144 | 110 | |
|---|
| 145 | | - gsi->outstanding_wrs = kcalloc(init_attr->cap.max_send_wr, |
|---|
| 146 | | - sizeof(*gsi->outstanding_wrs), |
|---|
| 147 | | - GFP_KERNEL); |
|---|
| 111 | + gsi->outstanding_wrs = |
|---|
| 112 | + kcalloc(attr->cap.max_send_wr, sizeof(*gsi->outstanding_wrs), |
|---|
| 113 | + GFP_KERNEL); |
|---|
| 148 | 114 | if (!gsi->outstanding_wrs) { |
|---|
| 149 | 115 | ret = -ENOMEM; |
|---|
| 150 | 116 | goto err_free_tx; |
|---|
| 151 | 117 | } |
|---|
| 152 | | - |
|---|
| 153 | | - mutex_init(&gsi->mutex); |
|---|
| 154 | 118 | |
|---|
| 155 | 119 | mutex_lock(&dev->devr.mutex); |
|---|
| 156 | 120 | |
|---|
| .. | .. |
|---|
| 163 | 127 | gsi->num_qps = num_qps; |
|---|
| 164 | 128 | spin_lock_init(&gsi->lock); |
|---|
| 165 | 129 | |
|---|
| 166 | | - gsi->cap = init_attr->cap; |
|---|
| 167 | | - gsi->sq_sig_type = init_attr->sq_sig_type; |
|---|
| 168 | | - gsi->ibqp.qp_num = 1; |
|---|
| 130 | + gsi->cap = attr->cap; |
|---|
| 169 | 131 | gsi->port_num = port_num; |
|---|
| 170 | 132 | |
|---|
| 171 | | - gsi->cq = ib_alloc_cq(pd->device, gsi, init_attr->cap.max_send_wr, 0, |
|---|
| 133 | + gsi->cq = ib_alloc_cq(pd->device, gsi, attr->cap.max_send_wr, 0, |
|---|
| 172 | 134 | IB_POLL_SOFTIRQ); |
|---|
| 173 | 135 | if (IS_ERR(gsi->cq)) { |
|---|
| 174 | 136 | mlx5_ib_warn(dev, "unable to create send CQ for GSI QP. error %ld\n", |
|---|
| .. | .. |
|---|
| 184 | 146 | hw_init_attr.cap.max_send_sge = 0; |
|---|
| 185 | 147 | hw_init_attr.cap.max_inline_data = 0; |
|---|
| 186 | 148 | } |
|---|
| 187 | | - gsi->rx_qp = ib_create_qp(pd, &hw_init_attr); |
|---|
| 149 | + |
|---|
| 150 | + gsi->rx_qp = mlx5_ib_create_qp(pd, &hw_init_attr, NULL); |
|---|
| 188 | 151 | if (IS_ERR(gsi->rx_qp)) { |
|---|
| 189 | 152 | mlx5_ib_warn(dev, "unable to create hardware GSI QP. error %ld\n", |
|---|
| 190 | 153 | PTR_ERR(gsi->rx_qp)); |
|---|
| 191 | 154 | ret = PTR_ERR(gsi->rx_qp); |
|---|
| 192 | 155 | goto err_destroy_cq; |
|---|
| 193 | 156 | } |
|---|
| 157 | + gsi->rx_qp->device = pd->device; |
|---|
| 158 | + gsi->rx_qp->pd = pd; |
|---|
| 159 | + gsi->rx_qp->real_qp = gsi->rx_qp; |
|---|
| 194 | 160 | |
|---|
| 195 | | - dev->devr.ports[init_attr->port_num - 1].gsi = gsi; |
|---|
| 161 | + gsi->rx_qp->qp_type = hw_init_attr.qp_type; |
|---|
| 162 | + gsi->rx_qp->send_cq = hw_init_attr.send_cq; |
|---|
| 163 | + gsi->rx_qp->recv_cq = hw_init_attr.recv_cq; |
|---|
| 164 | + gsi->rx_qp->event_handler = hw_init_attr.event_handler; |
|---|
| 165 | + spin_lock_init(&gsi->rx_qp->mr_lock); |
|---|
| 166 | + INIT_LIST_HEAD(&gsi->rx_qp->rdma_mrs); |
|---|
| 167 | + INIT_LIST_HEAD(&gsi->rx_qp->sig_mrs); |
|---|
| 168 | + |
|---|
| 169 | + dev->devr.ports[attr->port_num - 1].gsi = gsi; |
|---|
| 196 | 170 | |
|---|
| 197 | 171 | mutex_unlock(&dev->devr.mutex); |
|---|
| 198 | 172 | |
|---|
| 199 | | - return &gsi->ibqp; |
|---|
| 173 | + return 0; |
|---|
| 200 | 174 | |
|---|
| 201 | 175 | err_destroy_cq: |
|---|
| 202 | 176 | ib_free_cq(gsi->cq); |
|---|
| .. | .. |
|---|
| 205 | 179 | kfree(gsi->outstanding_wrs); |
|---|
| 206 | 180 | err_free_tx: |
|---|
| 207 | 181 | kfree(gsi->tx_qps); |
|---|
| 208 | | -err_free: |
|---|
| 209 | | - kfree(gsi); |
|---|
| 210 | | - return ERR_PTR(ret); |
|---|
| 182 | + return ret; |
|---|
| 211 | 183 | } |
|---|
| 212 | 184 | |
|---|
| 213 | | -int mlx5_ib_gsi_destroy_qp(struct ib_qp *qp) |
|---|
| 185 | +int mlx5_ib_destroy_gsi(struct mlx5_ib_qp *mqp) |
|---|
| 214 | 186 | { |
|---|
| 215 | | - struct mlx5_ib_dev *dev = to_mdev(qp->device); |
|---|
| 216 | | - struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); |
|---|
| 187 | + struct mlx5_ib_dev *dev = to_mdev(mqp->ibqp.device); |
|---|
| 188 | + struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; |
|---|
| 217 | 189 | const int port_num = gsi->port_num; |
|---|
| 218 | 190 | int qp_index; |
|---|
| 219 | 191 | int ret; |
|---|
| 220 | 192 | |
|---|
| 221 | | - mlx5_ib_dbg(dev, "destroying GSI QP\n"); |
|---|
| 222 | | - |
|---|
| 223 | 193 | mutex_lock(&dev->devr.mutex); |
|---|
| 224 | | - ret = ib_destroy_qp(gsi->rx_qp); |
|---|
| 194 | + ret = mlx5_ib_destroy_qp(gsi->rx_qp, NULL); |
|---|
| 225 | 195 | if (ret) { |
|---|
| 226 | 196 | mlx5_ib_warn(dev, "unable to destroy hardware GSI QP. error %d\n", |
|---|
| 227 | 197 | ret); |
|---|
| .. | .. |
|---|
| 243 | 213 | |
|---|
| 244 | 214 | kfree(gsi->outstanding_wrs); |
|---|
| 245 | 215 | kfree(gsi->tx_qps); |
|---|
| 246 | | - kfree(gsi); |
|---|
| 216 | + kfree(mqp); |
|---|
| 247 | 217 | |
|---|
| 248 | 218 | return 0; |
|---|
| 249 | 219 | } |
|---|
| .. | .. |
|---|
| 261 | 231 | .max_send_sge = gsi->cap.max_send_sge, |
|---|
| 262 | 232 | .max_inline_data = gsi->cap.max_inline_data, |
|---|
| 263 | 233 | }, |
|---|
| 264 | | - .sq_sig_type = gsi->sq_sig_type, |
|---|
| 265 | 234 | .qp_type = IB_QPT_UD, |
|---|
| 266 | | - .create_flags = mlx5_ib_create_qp_sqpn_qp1(), |
|---|
| 235 | + .create_flags = MLX5_IB_QP_CREATE_SQPN_QP1, |
|---|
| 267 | 236 | }; |
|---|
| 268 | 237 | |
|---|
| 269 | 238 | return ib_create_qp(pd, &init_attr); |
|---|
| 270 | 239 | } |
|---|
| 271 | 240 | |
|---|
| 272 | 241 | static int modify_to_rts(struct mlx5_ib_gsi_qp *gsi, struct ib_qp *qp, |
|---|
| 273 | | - u16 qp_index) |
|---|
| 242 | + u16 pkey_index) |
|---|
| 274 | 243 | { |
|---|
| 275 | 244 | struct mlx5_ib_dev *dev = to_mdev(qp->device); |
|---|
| 276 | 245 | struct ib_qp_attr attr; |
|---|
| .. | .. |
|---|
| 279 | 248 | |
|---|
| 280 | 249 | mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_QKEY | IB_QP_PORT; |
|---|
| 281 | 250 | attr.qp_state = IB_QPS_INIT; |
|---|
| 282 | | - attr.pkey_index = qp_index; |
|---|
| 251 | + attr.pkey_index = pkey_index; |
|---|
| 283 | 252 | attr.qkey = IB_QP1_QKEY; |
|---|
| 284 | 253 | attr.port_num = gsi->port_num; |
|---|
| 285 | 254 | ret = ib_modify_qp(qp, &attr, mask); |
|---|
| .. | .. |
|---|
| 313 | 282 | { |
|---|
| 314 | 283 | struct ib_device *device = gsi->rx_qp->device; |
|---|
| 315 | 284 | struct mlx5_ib_dev *dev = to_mdev(device); |
|---|
| 285 | + int pkey_index = qp_index; |
|---|
| 286 | + struct mlx5_ib_qp *mqp; |
|---|
| 316 | 287 | struct ib_qp *qp; |
|---|
| 317 | 288 | unsigned long flags; |
|---|
| 318 | 289 | u16 pkey; |
|---|
| 319 | 290 | int ret; |
|---|
| 320 | 291 | |
|---|
| 321 | | - ret = ib_query_pkey(device, gsi->port_num, qp_index, &pkey); |
|---|
| 292 | + if (MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_IB) |
|---|
| 293 | + pkey_index = 0; |
|---|
| 294 | + |
|---|
| 295 | + ret = ib_query_pkey(device, gsi->port_num, pkey_index, &pkey); |
|---|
| 322 | 296 | if (ret) { |
|---|
| 323 | 297 | mlx5_ib_warn(dev, "unable to read P_Key at port %d, index %d\n", |
|---|
| 324 | 298 | gsi->port_num, qp_index); |
|---|
| .. | .. |
|---|
| 347 | 321 | return; |
|---|
| 348 | 322 | } |
|---|
| 349 | 323 | |
|---|
| 350 | | - ret = modify_to_rts(gsi, qp, qp_index); |
|---|
| 324 | + mqp = to_mqp(qp); |
|---|
| 325 | + if (dev->lag_active) |
|---|
| 326 | + mqp->gsi_lag_port = qp_index + 1; |
|---|
| 327 | + ret = modify_to_rts(gsi, qp, pkey_index); |
|---|
| 351 | 328 | if (ret) |
|---|
| 352 | 329 | goto err_destroy_qp; |
|---|
| 353 | 330 | |
|---|
| .. | .. |
|---|
| 364 | 341 | |
|---|
| 365 | 342 | static void setup_qps(struct mlx5_ib_gsi_qp *gsi) |
|---|
| 366 | 343 | { |
|---|
| 344 | + struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device); |
|---|
| 367 | 345 | u16 qp_index; |
|---|
| 368 | 346 | |
|---|
| 347 | + mutex_lock(&dev->devr.mutex); |
|---|
| 369 | 348 | for (qp_index = 0; qp_index < gsi->num_qps; ++qp_index) |
|---|
| 370 | 349 | setup_qp(gsi, qp_index); |
|---|
| 350 | + mutex_unlock(&dev->devr.mutex); |
|---|
| 371 | 351 | } |
|---|
| 372 | 352 | |
|---|
| 373 | 353 | int mlx5_ib_gsi_modify_qp(struct ib_qp *qp, struct ib_qp_attr *attr, |
|---|
| 374 | 354 | int attr_mask) |
|---|
| 375 | 355 | { |
|---|
| 376 | 356 | struct mlx5_ib_dev *dev = to_mdev(qp->device); |
|---|
| 377 | | - struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); |
|---|
| 357 | + struct mlx5_ib_qp *mqp = to_mqp(qp); |
|---|
| 358 | + struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; |
|---|
| 378 | 359 | int ret; |
|---|
| 379 | 360 | |
|---|
| 380 | 361 | mlx5_ib_dbg(dev, "modifying GSI QP to state %d\n", attr->qp_state); |
|---|
| 381 | 362 | |
|---|
| 382 | | - mutex_lock(&gsi->mutex); |
|---|
| 383 | 363 | ret = ib_modify_qp(gsi->rx_qp, attr, attr_mask); |
|---|
| 384 | 364 | if (ret) { |
|---|
| 385 | 365 | mlx5_ib_warn(dev, "unable to modify GSI rx QP: %d\n", ret); |
|---|
| 386 | | - goto unlock; |
|---|
| 366 | + return ret; |
|---|
| 387 | 367 | } |
|---|
| 388 | 368 | |
|---|
| 389 | 369 | if (to_mqp(gsi->rx_qp)->state == IB_QPS_RTS) |
|---|
| 390 | 370 | setup_qps(gsi); |
|---|
| 391 | | - |
|---|
| 392 | | -unlock: |
|---|
| 393 | | - mutex_unlock(&gsi->mutex); |
|---|
| 394 | | - |
|---|
| 395 | | - return ret; |
|---|
| 371 | + return 0; |
|---|
| 396 | 372 | } |
|---|
| 397 | 373 | |
|---|
| 398 | 374 | int mlx5_ib_gsi_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, |
|---|
| 399 | 375 | int qp_attr_mask, |
|---|
| 400 | 376 | struct ib_qp_init_attr *qp_init_attr) |
|---|
| 401 | 377 | { |
|---|
| 402 | | - struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); |
|---|
| 378 | + struct mlx5_ib_qp *mqp = to_mqp(qp); |
|---|
| 379 | + struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; |
|---|
| 403 | 380 | int ret; |
|---|
| 404 | 381 | |
|---|
| 405 | | - mutex_lock(&gsi->mutex); |
|---|
| 406 | 382 | ret = ib_query_qp(gsi->rx_qp, qp_attr, qp_attr_mask, qp_init_attr); |
|---|
| 407 | 383 | qp_init_attr->cap = gsi->cap; |
|---|
| 408 | | - mutex_unlock(&gsi->mutex); |
|---|
| 409 | | - |
|---|
| 410 | 384 | return ret; |
|---|
| 411 | 385 | } |
|---|
| 412 | 386 | |
|---|
| 413 | 387 | /* Call with gsi->lock locked */ |
|---|
| 414 | | -static int mlx5_ib_add_outstanding_wr(struct mlx5_ib_gsi_qp *gsi, |
|---|
| 388 | +static int mlx5_ib_add_outstanding_wr(struct mlx5_ib_qp *mqp, |
|---|
| 415 | 389 | struct ib_ud_wr *wr, struct ib_wc *wc) |
|---|
| 416 | 390 | { |
|---|
| 391 | + struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; |
|---|
| 417 | 392 | struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device); |
|---|
| 418 | 393 | struct mlx5_ib_gsi_wr *gsi_wr; |
|---|
| 419 | 394 | |
|---|
| .. | .. |
|---|
| 442 | 417 | } |
|---|
| 443 | 418 | |
|---|
| 444 | 419 | /* Call with gsi->lock locked */ |
|---|
| 445 | | -static int mlx5_ib_gsi_silent_drop(struct mlx5_ib_gsi_qp *gsi, |
|---|
| 446 | | - struct ib_ud_wr *wr) |
|---|
| 420 | +static int mlx5_ib_gsi_silent_drop(struct mlx5_ib_qp *mqp, struct ib_ud_wr *wr) |
|---|
| 447 | 421 | { |
|---|
| 448 | 422 | struct ib_wc wc = { |
|---|
| 449 | 423 | { .wr_id = wr->wr.wr_id }, |
|---|
| 450 | 424 | .status = IB_WC_SUCCESS, |
|---|
| 451 | 425 | .opcode = IB_WC_SEND, |
|---|
| 452 | | - .qp = &gsi->ibqp, |
|---|
| 426 | + .qp = &mqp->ibqp, |
|---|
| 453 | 427 | }; |
|---|
| 454 | 428 | int ret; |
|---|
| 455 | 429 | |
|---|
| 456 | | - ret = mlx5_ib_add_outstanding_wr(gsi, wr, &wc); |
|---|
| 430 | + ret = mlx5_ib_add_outstanding_wr(mqp, wr, &wc); |
|---|
| 457 | 431 | if (ret) |
|---|
| 458 | 432 | return ret; |
|---|
| 459 | 433 | |
|---|
| 460 | | - generate_completions(gsi); |
|---|
| 434 | + generate_completions(mqp); |
|---|
| 461 | 435 | |
|---|
| 462 | 436 | return 0; |
|---|
| 463 | 437 | } |
|---|
| .. | .. |
|---|
| 466 | 440 | static struct ib_qp *get_tx_qp(struct mlx5_ib_gsi_qp *gsi, struct ib_ud_wr *wr) |
|---|
| 467 | 441 | { |
|---|
| 468 | 442 | struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device); |
|---|
| 443 | + struct mlx5_ib_ah *ah = to_mah(wr->ah); |
|---|
| 469 | 444 | int qp_index = wr->pkey_index; |
|---|
| 470 | 445 | |
|---|
| 471 | | - if (!mlx5_ib_deth_sqpn_cap(dev)) |
|---|
| 446 | + if (!gsi->num_qps) |
|---|
| 472 | 447 | return gsi->rx_qp; |
|---|
| 448 | + |
|---|
| 449 | + if (dev->lag_active && ah->xmit_port) |
|---|
| 450 | + qp_index = ah->xmit_port - 1; |
|---|
| 473 | 451 | |
|---|
| 474 | 452 | if (qp_index >= gsi->num_qps) |
|---|
| 475 | 453 | return NULL; |
|---|
| .. | .. |
|---|
| 480 | 458 | int mlx5_ib_gsi_post_send(struct ib_qp *qp, const struct ib_send_wr *wr, |
|---|
| 481 | 459 | const struct ib_send_wr **bad_wr) |
|---|
| 482 | 460 | { |
|---|
| 483 | | - struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); |
|---|
| 461 | + struct mlx5_ib_qp *mqp = to_mqp(qp); |
|---|
| 462 | + struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; |
|---|
| 484 | 463 | struct ib_qp *tx_qp; |
|---|
| 485 | 464 | unsigned long flags; |
|---|
| 486 | 465 | int ret; |
|---|
| .. | .. |
|---|
| 493 | 472 | spin_lock_irqsave(&gsi->lock, flags); |
|---|
| 494 | 473 | tx_qp = get_tx_qp(gsi, &cur_wr); |
|---|
| 495 | 474 | if (!tx_qp) { |
|---|
| 496 | | - ret = mlx5_ib_gsi_silent_drop(gsi, &cur_wr); |
|---|
| 475 | + ret = mlx5_ib_gsi_silent_drop(mqp, &cur_wr); |
|---|
| 497 | 476 | if (ret) |
|---|
| 498 | 477 | goto err; |
|---|
| 499 | 478 | spin_unlock_irqrestore(&gsi->lock, flags); |
|---|
| 500 | 479 | continue; |
|---|
| 501 | 480 | } |
|---|
| 502 | 481 | |
|---|
| 503 | | - ret = mlx5_ib_add_outstanding_wr(gsi, &cur_wr, NULL); |
|---|
| 482 | + ret = mlx5_ib_add_outstanding_wr(mqp, &cur_wr, NULL); |
|---|
| 504 | 483 | if (ret) |
|---|
| 505 | 484 | goto err; |
|---|
| 506 | 485 | |
|---|
| .. | .. |
|---|
| 524 | 503 | int mlx5_ib_gsi_post_recv(struct ib_qp *qp, const struct ib_recv_wr *wr, |
|---|
| 525 | 504 | const struct ib_recv_wr **bad_wr) |
|---|
| 526 | 505 | { |
|---|
| 527 | | - struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); |
|---|
| 506 | + struct mlx5_ib_qp *mqp = to_mqp(qp); |
|---|
| 507 | + struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; |
|---|
| 528 | 508 | |
|---|
| 529 | 509 | return ib_post_recv(gsi->rx_qp, wr, bad_wr); |
|---|
| 530 | 510 | } |
|---|
| .. | .. |
|---|
| 534 | 514 | if (!gsi) |
|---|
| 535 | 515 | return; |
|---|
| 536 | 516 | |
|---|
| 537 | | - mutex_lock(&gsi->mutex); |
|---|
| 538 | 517 | setup_qps(gsi); |
|---|
| 539 | | - mutex_unlock(&gsi->mutex); |
|---|
| 540 | 518 | } |
|---|