Let the dma do the work for you. Set up two descriptors...
the first one
points at the first few octets that needed realignment and
the second
one points at the rest of the data after you remove the
first few octets
from it in order to align that. Does that make sense?
If the data starts on address 1, then move three octets to
an aligned
address. Now the three octets are aligned, and the rest of
the data is
aligned on address 4.
First check to see if you even need to realign anything. If
not, then
circumvent everything and use one descriptor. If realignment
is
necessary, then calculate how many bytes you need to remove
from the
start of the original data in order to align it. Then align
the removed
octets and set up the first descriptor to transmit these
(don't set the
MCD_FEC_END_FRAME flag). The second descriptor would then
point at rest
of the data (with MCD_FEC_END_FRAME flag set).
One point though, set up the second descriptor first with
the
MCD_FEC_BUF_READY flag set before setting MCD_FEC_BUF_READY
in the
first. As soon as that flag is set, the dma will start
sending, so just
to be safe, have them both ready when handing the first off
to the dma.
I haven't done any timings with this sort of thing, but I
assume it
would be much faster than what you have. If you can, it
would be
interesting to see what sort of speedup would result.
-Scott Hauck
NextNet/Motorola
On Thu, 2006-07-13 at 14:28 +0200, Tobias Simon wrote:
> Hi Folks,
>
> I'm trying to improve the MCF Ethernet Driver because
it stresses the CPU too
> much _altough_ it is using the DMA capabilities of
Coldfire.
>
> The fec_tx function (at the end to this Mail) allocates
an aligned buffer,
> because Ethernet DMA runs in 4-Byte aligned mode. I
think the problem is that
> every packet data must be copied via
"memcpy" to this aligned buffer, which
> is done by the cpu.
>
> Is there a way - perhaps using
"skb_reserve"- to get an aligned sk_buff - so
> that this annoying memcpy could be ommited, or is it
just impossible and i
> have to run DMA in another Mode?
>
>
> Yours Sincerely,
> Tobias Simon
>
> --------------- code snippet follows
--------------------
>
> int fec_tx(struct sk_buff *skb, struct net_device *dev)
> {
>
> //Receive the pointer to the private structure
> struct fec_priv *fp = (struct fec_priv *)
dev->priv;
>
> void *data, *data_aligned;
> int offset;
>
> data = kmalloc(skb->len + 15, GFP_DMA |
GFP_ATOMIC);
>
> if (!data)
> {
> fp->fecpriv_stat.tx_dropped++;
> dev_kfree_skb(skb);
> return 0;
> }
>
> offset = (((unsigned long)virt_to_phys(data) + 15)
& 0xFFFFFFF0) - (unsigned
> long)virt_to_phys(data);
> data_aligned = (void*)((unsigned long)data + offset);
> memcpy(data_aligned, skb->data, skb->len);
>
>
> spin_lock_irq(&fp->fecpriv_lock);
>
> // Initialize the descriptor
> fp->fecpriv_txbuf[fp->fecpriv_next_tx] = data;
>
fp->fecpriv_txdesc[fp->fecpriv_next_tx].dataPointer =
(unsigned int)
> virt_to_phys(data_aligned);
> fp->fecpriv_txdesc[fp->fecpriv_next_tx].length =
skb->len;
> fp->fecpriv_txdesc[fp->fecpriv_next_tx].statCtrl
|= (MCD_FEC_END_FRAME |
> MCD_FEC_BUF_READY);
> fp->fecpriv_next_tx = (fp->fecpriv_next_tx + 1)
& FEC_TX_INDEX_MASK;
>
> if (fp->fecpriv_txbuf[fp->fecpriv_current_tx]
&& fp->fecpriv_current_tx ==
> fp->fecpriv_next_tx)
> netif_stop_queue(dev);
>
> spin_unlock_irq(&fp->fecpriv_lock);
>
> // Tell the DMA to continue the transmission
> MCD_continDma(fp->fecpriv_fec_tx_channel);
>
> dev_kfree_skb(skb);
>
> dev->trans_start = jiffies;
>
> return 0;
> }
>
------------------------------------------------------------
--------
> To Subscribe send a message to: ColdFire-On Lists.Wildrice.com
> To Unsubscribe send a message to: ColdFire-Off Lists.Wildrice.com
> For further information, visit: <http://www.Wild
Rice.com/ColdFire/>
>
--
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . .
h a u c k s n e x t n e t w i r e l e s s . c o m
------------------------------------------------------------
--------
To Subscribe send a message to: ColdFire-On Lists.Wildrice.com
To Unsubscribe send a message to: ColdFire-Off Lists.Wildrice.com
For further information, visit: <http://www.Wild
Rice.com/ColdFire/>
|