Ejemplo n.º 1
0
static int
mlx4_en_prepare_rx_desc(struct mlx4_en_priv *priv,
    struct mlx4_en_rx_ring *ring, int index)
{
	struct mlx4_en_rx_desc *rx_desc = (struct mlx4_en_rx_desc *)
	    (ring->buf + (index * ring->stride));
	struct mlx4_en_rx_mbuf *mb_list = ring->mbuf + index;

	mb_list->mbuf = NULL;

	if (mlx4_en_alloc_buf(ring, &rx_desc->data[0].addr, mb_list)) {
		priv->port_stats.rx_alloc_failed++;
		return (-ENOMEM);
	}
	return (0);
}
Ejemplo n.º 2
0
/* Unmap a completed descriptor and free unused pages */
static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
				    struct mlx4_en_rx_desc *rx_desc,
				    struct mbuf **mb_list,
				    int length)
{
	struct mlx4_en_dev *mdev = priv->mdev;
	struct mlx4_en_frag_info *frag_info;
	dma_addr_t dma;
	struct mbuf *mb;
	int nr;

	mb = mb_list[0];
	mb->m_pkthdr.len = length;
	/* Collect used fragments while replacing them in the HW descirptors */
	for (nr = 0; nr < priv->num_frags; nr++) {
		frag_info = &priv->frag_info[nr];
		if (length <= frag_info->frag_prefix_size)
			break;
		if (nr) 
			mb->m_next = mb_list[nr];
		mb = mb_list[nr];
		mb->m_len = frag_info[nr].frag_size;
		dma = be64_to_cpu(rx_desc->data[nr].addr);

		/* Allocate a replacement page */
		if (mlx4_en_alloc_buf(priv, rx_desc, mb_list, nr))
			goto fail;

		/* Unmap buffer */
		pci_unmap_single(mdev->pdev, dma, frag_info[nr].frag_size,
				 PCI_DMA_FROMDEVICE);
	}
	/* Adjust size of last fragment to match actual length */
	mb->m_len = length - priv->frag_info[nr - 1].frag_prefix_size;
	mb->m_next = NULL;
	return 0;

fail:
	/* Drop all accumulated fragments (which have already been replaced in
	 * the descriptor) of this packet; remaining fragments are reused... */
	while (nr > 0) {
		nr--;
		m_free(mb_list[nr]);
	}
	return -ENOMEM;
}
Ejemplo n.º 3
0
static int mlx4_en_prepare_rx_desc(struct mlx4_en_priv *priv,
				   struct mlx4_en_rx_ring *ring, int index)
{
	struct mlx4_en_rx_desc *rx_desc = ring->buf + (index * ring->stride);
	struct mbuf **mb_list = ring->rx_info + (index << priv->log_rx_info);
	int i;

	for (i = 0; i < priv->num_frags; i++)
		if (mlx4_en_alloc_buf(priv, rx_desc, mb_list, i))
			goto err;

	return 0;

err:
	while (i--)
		m_free(mb_list[i]);
	return -ENOMEM;
}