On Friday 23 March 2007 22:24, Will Dyson wrote:
> When the chip is limited to 30bit DMA, allocate RX buffers in ZONE_DMA. When
> the network stack passes us TX buffers that cannot be mapped because of the
> limitation (with an address > 1GB), allocate a bounce buffer in ZONE_DMA and
> copy the packet there.

I _still_ think that this should be fixed in the arch DMA code
and _not_ in every single driver on earth. But I discussed this in
the past.

> Signed-off-by: Will Dyson <[EMAIL PROTECTED]>
> ---
>  .../net/wireless/mac80211/bcm43xx/bcm43xx_dma.c    |   52
> +++++++++++++++++---
>  1 files changed, 45 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c
> b/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c
> index d09b849..8f6d434 100644
> --- a/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c
> +++ b/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_dma.c
> @@ -397,6 +397,9 @@ static int alloc_ringmemory(struct bcm43xx_dmaring
> *ring)

Your patches are all damaged. Please fix your mailer.

>  {
>      struct device *dev = ring->dev->dev->dev;
> 
> +    /* Dont need to test for 30bit dma here.
> +     * dma_alloc_coherent respects the dma_mask
> +     */
>      ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
>                          &(ring->dmabase), GFP_KERNEL);
>      if (!ring->descbase) {
> @@ -549,11 +552,15 @@ static int alloc_initial_descbuffers(struct
> bcm43xx_dmaring *ring)
>      int i, err = -ENOMEM;
>      struct bcm43xx_dmadesc_generic *desc;
>      struct bcm43xx_dmadesc_meta *meta;
> +    gfp_t flags = GFP_KERNEL;
> +
> +    if (bcm43xx_dma30(ring->dev))
> +        flags = GFP_DMA;

Ehm, no. This would always allocate in the DMA zone, even if there
is no requirement to do so (on i386 for example).

>      for (i = 0; i < ring->nr_slots; i++) {
>          desc = ring->ops->idx2desc(ring, i, &meta);
> 
> -        err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
> +        err = setup_rx_descbuffer(ring, desc, meta, flags);
>          if (err) {
>              printk(KERN_ERR PFX "Failed to allocate initial
> descbuffers\n");
>              goto err_unwind;
> @@ -730,6 +737,7 @@ struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct
> bcm43xx_wldev *dev,
>      struct bcm43xx_dmaring *ring;
>      int err;
>      int nr_slots;
> +    gfp_t dma_flags = GFP_KERNEL;
> 
>      ring = kzalloc(sizeof(*ring), GFP_KERNEL);
>      if (!ring)
> @@ -744,9 +752,12 @@ struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct
> bcm43xx_wldev *dev,
>      if (!ring->meta)
>          goto err_kfree_ring;
>      if (for_tx) {
> +        if (bcm43xx_dma30(dev))
> +            dma_flags = GFP_DMA;

Same here.

> +        /* only this allocation is for DMA */
>          ring->txhdr_cache = kcalloc(nr_slots,
>                          sizeof(struct bcm43xx_txhdr_fw4),
> -                        GFP_KERNEL);
> +                        dma_flags);
>          if (!ring->txhdr_cache)
>              goto err_kfree_meta;
>      }
> @@ -1020,9 +1031,11 @@ static int dma_tx_fragment(struct bcm43xx_dmaring
> *ring,
>      const struct bcm43xx_dma_ops *ops = ring->ops;
>      u8 *header;
>      int slot;
> +    int err;
>      struct bcm43xx_dmadesc_generic *desc;
>      struct bcm43xx_dmadesc_meta *meta;
>      struct bcm43xx_dmadesc_meta *meta_hdr;
> +    struct sk_buff *bounce_skb;
> 
>  #define SLOTS_PER_PACKET  2
>      assert(skb_shinfo(skb)->nr_frags == 0);
> @@ -1052,9 +1065,27 @@ static int dma_tx_fragment(struct bcm43xx_dmaring
> *ring,
>      memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
>      meta->skb = skb;
>      meta->is_last_fragment = 1;
> +
>      meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
> -    if(dma_mapping_error(meta->dmaaddr))
> -        goto out_unmap_hdr;
> +
> +    /* create a bounce buffer in zone_dma on mapping failure. */
> +    if (dma_mapping_error(meta->dmaaddr)) {
> +        bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC|GFP_DMA);
                                                         ^^^^^^
Whitespace.


> +        if(!bounce_skb) {
             ^
Whitespace.

> +            err = -ENOMEM;
> +            goto out_unmap_hdr;
> +        }
> +
> +        memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
> +        dev_kfree_skb_any(skb);
> +        skb = bounce_skb;
> +        meta->skb = skb;
> +        meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
> +        if (dma_mapping_error(meta->dmaaddr)) {
> +            err = -EIO;
> +            goto out_free_bounce;
> +        }
> +    }
> 
>      ops->fill_descriptor(ring, desc, meta->dmaaddr,
>                   skb->len, 0, 1, 1);
> @@ -1064,10 +1095,12 @@ static int dma_tx_fragment(struct bcm43xx_dmaring
> *ring,
>      ops->poke_tx(ring, next_slot(ring, slot));
>      return 0;
> 
> +out_free_bounce:
> +    dev_kfree_skb_any(skb);
>  out_unmap_hdr:
>      unmap_descbuffer(ring, meta_hdr->dmaaddr,
>              sizeof(struct bcm43xx_txhdr_fw4), 1);
> -    return -EIO;
> +    return err;
>  }
> 
>  int bcm43xx_dma_tx(struct bcm43xx_wldev *dev,
> @@ -1088,7 +1121,7 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev *dev,
> 
>      err = dma_tx_fragment(ring, skb, ctl);
>      if (unlikely(err)) {
> -        printkl(KERN_ERR PFX "DMA tx mapping failure\n");
> +        printkl(KERN_ERR PFX "DMA tx failure\n");
>          return NETDEV_TX_BUSY;
>      }
> 
> @@ -1186,6 +1219,7 @@ static void dma_rx(struct bcm43xx_dmaring *ring,
>      u16 len;
>      int err;
>      dma_addr_t dmaaddr;
> +    gfp_t dma_flags;
> 
>      desc = ops->idx2desc(ring, *slot, &meta);
> 
> @@ -1253,8 +1287,12 @@ static void dma_rx(struct bcm43xx_dmaring *ring,
>          goto drop;
>      }
> 
> +    dma_flags = GFP_ATOMIC;
> +    if (bcm43xx_dma30(ring->dev))
> +        dma_flags |= GFP_DMA;

always DMA...

>      dmaaddr = meta->dmaaddr;
> -    err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
> +    err = setup_rx_descbuffer(ring, desc, meta, dma_flags);
>      if (unlikely(err)) {
>          dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n");
>          sync_descbuffer_for_device(ring, dmaaddr,
> -- 
> 1.5.0.3
> 
> 
> 

-- 
Greetings Michael.
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to