Skip to content

Commit

Permalink
[CASSINI]: Fix endianness bug.
Browse files Browse the repository at this point in the history
Here's proposed fix for RX checksum handling in cassini; it affects
little-endian working with half-duplex gigabit, but obviously needs
testing on big-endian too.

The problem is, we need to convert checksum to fixed-endian *before*
correcting for (unstripped) FCS.  On big-endian it won't matter
(conversion is no-op), on little-endian it will, but only if FCS is
not stripped by hardware; i.e. in half-duplex gigabit mode when
->crc_size is set.

cassini.c part is that fix, cassini.h one consists of trivial
endianness annotations.  With that applied the sucker is endian-clean,
according to sparse.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Al Viro authored and David S. Miller committed Jan 4, 2008
1 parent 2d60abc commit e5e0254
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 12 deletions.
8 changes: 5 additions & 3 deletions drivers/net/cassini.c
Original file line number Diff line number Diff line change
Expand Up @@ -1979,6 +1979,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
struct cas_page *page;
struct sk_buff *skb;
void *addr, *crcaddr;
__sum16 csum;
char *p;

hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]);
Expand Down Expand Up @@ -2158,14 +2159,15 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
skb_put(skb, alloclen);
}

i = CAS_VAL(RX_COMP4_TCP_CSUM, words[3]);
csum = (__force __sum16)htons(CAS_VAL(RX_COMP4_TCP_CSUM, words[3]));
if (cp->crc_size) {
/* checksum includes FCS. strip it out. */
i = csum_fold(csum_partial(crcaddr, cp->crc_size, i));
csum = csum_fold(csum_partial(crcaddr, cp->crc_size,
csum_unfold(csum)));
if (addr)
cas_page_unmap(addr);
}
skb->csum = ntohs(i ^ 0xffff);
skb->csum = csum_unfold(~csum);
skb->ip_summed = CHECKSUM_COMPLETE;
skb->protocol = eth_type_trans(skb, cp->dev);
return len;
Expand Down
18 changes: 9 additions & 9 deletions drivers/net/cassini.h
Original file line number Diff line number Diff line change
Expand Up @@ -4122,17 +4122,17 @@ cas_saturn_patch_t cas_saturn_patch[] = {
inserted into
outgoing frame. */
struct cas_tx_desc {
u64 control;
u64 buffer;
__le64 control;
__le64 buffer;
};

/* descriptor ring for free buffers contains page-sized buffers. the index
* value is not used by the hw in any way. it's just stored and returned in
* the completion ring.
*/
struct cas_rx_desc {
u64 index;
u64 buffer;
__le64 index;
__le64 buffer;
};

/* received packets are put on the completion ring. */
Expand Down Expand Up @@ -4210,10 +4210,10 @@ struct cas_rx_desc {
#define RX_INDEX_RELEASE 0x0000000000002000ULL

struct cas_rx_comp {
u64 word1;
u64 word2;
u64 word3;
u64 word4;
__le64 word1;
__le64 word2;
__le64 word3;
__le64 word4;
};

enum link_state {
Expand Down Expand Up @@ -4252,7 +4252,7 @@ struct cas_init_block {
struct cas_rx_comp rxcs[N_RX_COMP_RINGS][INIT_BLOCK_RX_COMP];
struct cas_rx_desc rxds[N_RX_DESC_RINGS][INIT_BLOCK_RX_DESC];
struct cas_tx_desc txds[N_TX_RINGS][INIT_BLOCK_TX];
u64 tx_compwb;
__le64 tx_compwb;
};

/* tiny buffers to deal with target abort issue. we allocate a bit
Expand Down

0 comments on commit e5e0254

Please sign in to comment.