eth_copy_and_sum(), 8390s and Alphas.

Paul Gortmaker (gpg109@rsphy1.anu.edu.au)
Wed, 26 Jul 1995 15:51:23 +1000 (EST)


Okay, I have got all the shmem 8390 cards converted over to be
eth_copy_and_sum() capable. Yes, I even had to mess with non-shmem
drivers, because they all use *_block_input() to read the 8390 4 byte
header. But *_block_input() needs to accept a skb if we want to use
eth_copy_and_sum(). This meant implementing a *_get_8390_hdr() -- which
is good from a performance point of view, as it is optimized to take
advantage of the fact that the header is only 4 bytes, and that it is 8390
page aligned. (In fact the wd and e21 driver did this already by checking
if the length was 4, and then just dereferenced the location as an int.)

In the process, I made all the memcpy() calls into the appropriate
memcpy_{from,to}io() calls and removed some HZ == 100 assumptions, so
that the Alpha guys can try and run any of the shared memory 8390 cards.
This also gets rid of a lot of type casts as a nice side effect.
I'd be interested in any feedback from alpha users. (NB: I am not
subscribed to linux-alpha.)

Also, all the individual *_block_input() functions were returning an
int that was promptly ignored by the 8390 core, so I changed it to
a void. May save a register on the call...

I have tested the 4 most common cards (wd, 3c503, ne2k, and smc-ultra)
with these changes, and they all work as expected. For the other four
less common cards (hp, hp-plus, e2100, ac3200) I made sure that they
at least compiled as I don't have the hardware to test them.

The cards that can use eth_copy_and_sum() are:
wd.c 3c503.c ac3200.c e2100.c and smc-ultra.c

The cards that can't use eth_copy_and_sum() are the PIO cards, those
being the hp.c and ne.c. The hp-plus card is included in this group as
well, even when it is in shared mem mode.

[[ The hp-plus is a strange one and deserves further mention. The problem
is that it wants all I/O and memory access to be whole words. Don has
made the memory access rounded to double word with a (count+3)&~3. So
it can't use eth_copy_and_sum() because this word-access-only
requirement will not be respected by eth_copy_and_sum(). The zero to
three extra bytes required by the above rounding are now easily dealt
with since we read the headers separately. Before, I believe it would
have stomped on the 3 bytes at the end of the data area (skb->tail)
in a worst-case scenario. ]]

However, I couldn't note any change in CPU overhead or xfer rate when
testing between two 486 boxes, using 8013 and 8216 cards. This might
be different on a cache-less 386, as Alan pointed out earlier.
Tom also mentioned a faster csum_partial_copy() that I have not tried.

The main outstanding issue is a non-i386 one, that being that
eth_copy_and_sum() [due to the memcpy()] and csum_partial_copy()
need to be aware of whether the src pointer is I/O memory to do
extra magic as in the memcpy() vs. memcpy_fromio() case. For example,
the lance requires the former, while shared memory drivers will
require the latter. (On an i386 they are one and the same.)

Because of the two above reasons, I have made this patch so that
it is an extra two line change to implement eth_copy_and_sum() for
any of the 5 above cards on i386 hardware, but made it (hopefully)
"alpha-compatible" as is.

The two line change would be as follows for ix86 users wanting to try it.

+ #include <linux/etherdevice.h>
[...]
- memcpy_fromio(skb->data, dev->mem_start + ring_offset, count);
+ eth_copy_and_sum(skb, (char *)dev->mem_start + ring_offset, count, 0);

The patch below also makes the assumption that skb->data will be equal
to the return value of skb_push() when called on a new skb. Hopefully
Alan won't change this for the forseeable future. :-)

The patch works against both p11 and p12. Feel free to mail me if you
have any questions.

Paul.

begin 600 8390_cards_diff.gz
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
;R&E6K,V2U:_M#/;2M0+8_IN_`#O`U-ICBP``
`
end