int mlx4_ib_destroy_srq(struct ib_srq *srq) { struct mlx4_ib_dev *dev = to_mdev(srq->device); struct mlx4_ib_srq *msrq = to_msrq(srq); struct mlx4_ib_cq *cq; mlx4_srq_invalidate(dev->dev, &msrq->msrq); if (srq->xrc_cq && !srq->uobject) { cq = to_mcq(srq->xrc_cq); spin_lock_irq(&cq->lock); __mlx4_ib_cq_clean(cq, -1, msrq); mlx4_srq_remove(dev->dev, &msrq->msrq); spin_unlock_irq(&cq->lock); } else mlx4_srq_remove(dev->dev, &msrq->msrq); mlx4_srq_free(dev->dev, &msrq->msrq); mlx4_mtt_cleanup(dev->dev, &msrq->mtt); if (srq->uobject) { mlx4_ib_db_unmap_user(to_mucontext(srq->uobject->context), &msrq->db); ib_umem_release(msrq->umem); } else { kfree(msrq->wrid); mlx4_buf_free(dev->dev, msrq->msrq.max << msrq->msrq.wqe_shift, &msrq->buf); mlx4_db_free(dev->dev, &msrq->db); } kfree(msrq); return 0; }
void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv, struct mlx4_en_rx_ring *ring) { struct mlx4_en_dev *mdev = priv->mdev; mlx4_srq_free(mdev->dev, &ring->srq); mlx4_en_free_rx_buf(priv, ring); mlx4_en_destroy_allocator(priv, ring); }
int mlx4_ib_destroy_srq(struct ib_srq *srq) { struct mlx4_ib_dev *dev = to_mdev(srq->device); struct mlx4_ib_srq *msrq = to_msrq(srq); mlx4_srq_free(dev->dev, &msrq->msrq); mlx4_mtt_cleanup(dev->dev, &msrq->mtt); if (srq->uobject) { mlx4_ib_db_unmap_user(to_mucontext(srq->uobject->context), &msrq->db); ib_umem_release(msrq->umem); } else { kfree(msrq->wrid); mlx4_buf_free(dev->dev, msrq->msrq.max << msrq->msrq.wqe_shift, &msrq->buf); mlx4_db_free(dev->dev, &msrq->db); } kfree(msrq); return 0; }
int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) { struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_wqe_srq_next_seg *next; struct mlx4_en_rx_ring *ring; int i; int ring_ind; int err; int stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) + DS_SIZE * priv->num_frags); int max_gs = (stride - sizeof(struct mlx4_wqe_srq_next_seg)) / DS_SIZE; for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { ring = &priv->rx_ring[ring_ind]; ring->prod = 0; ring->cons = 0; ring->actual_size = 0; ring->cqn = priv->rx_cq[ring_ind].mcq.cqn; ring->stride = stride; ring->log_stride = ffs(ring->stride) - 1; ring->buf_size = ring->size * ring->stride; memset(ring->rx_info, 0, sizeof(*(ring->rx_info))); memset(ring->buf, 0, ring->buf_size); mlx4_en_update_rx_prod_db(ring); /* Initailize all descriptors */ for (i = 0; i < ring->size; i++) mlx4_en_init_rx_desc(priv, ring, i); /* Initialize page allocators */ err = mlx4_en_init_allocator(priv, ring); if (err) { mlx4_err(mdev, "Failed initializing ring allocator\n"); goto err_allocator; } /* Fill Rx buffers */ ring->full = 0; } if (mlx4_en_fill_rx_buffers(priv)) goto err_buffers; for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { ring = &priv->rx_ring[ring_ind]; mlx4_en_update_rx_prod_db(ring); /* Configure SRQ representing the ring */ ring->srq.max = ring->size; ring->srq.max_gs = max_gs; ring->srq.wqe_shift = ilog2(ring->stride); for (i = 0; i < ring->srq.max; ++i) { next = get_wqe(ring, i); next->next_wqe_index = cpu_to_be16((i + 1) & (ring->srq.max - 1)); } err = mlx4_srq_alloc(mdev->dev, mdev->priv_pdn, &ring->wqres.mtt, ring->wqres.db.dma, &ring->srq); if (err){ mlx4_err(mdev, "Failed to allocate srq\n"); goto err_srq; } ring->srq.event = mlx4_en_srq_event; } return 0; err_srq: while (ring_ind >= 0) { ring = &priv->rx_ring[ring_ind]; mlx4_srq_free(mdev->dev, &ring->srq); ring_ind--; } err_buffers: for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) mlx4_en_free_rx_buf(priv, &priv->rx_ring[ring_ind]); ring_ind = priv->rx_ring_num - 1; err_allocator: while (ring_ind >= 0) { mlx4_en_destroy_allocator(priv, &priv->rx_ring[ring_ind]); ring_ind--; } return err; }