mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
[CASSINI]: Fix endianness bug.
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>
This commit is contained in:
parent
2d60abc2a9
commit
e5e025401f
@ -1979,6 +1979,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
|
|||||||
struct cas_page *page;
|
struct cas_page *page;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
void *addr, *crcaddr;
|
void *addr, *crcaddr;
|
||||||
|
__sum16 csum;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]);
|
hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]);
|
||||||
@ -2158,14 +2159,15 @@ end_copy_pkt:
|
|||||||
skb_put(skb, alloclen);
|
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) {
|
if (cp->crc_size) {
|
||||||
/* checksum includes FCS. strip it out. */
|
/* 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)
|
if (addr)
|
||||||
cas_page_unmap(addr);
|
cas_page_unmap(addr);
|
||||||
}
|
}
|
||||||
skb->csum = ntohs(i ^ 0xffff);
|
skb->csum = csum_unfold(~csum);
|
||||||
skb->ip_summed = CHECKSUM_COMPLETE;
|
skb->ip_summed = CHECKSUM_COMPLETE;
|
||||||
skb->protocol = eth_type_trans(skb, cp->dev);
|
skb->protocol = eth_type_trans(skb, cp->dev);
|
||||||
return len;
|
return len;
|
||||||
|
@ -4122,8 +4122,8 @@ cas_saturn_patch_t cas_saturn_patch[] = {
|
|||||||
inserted into
|
inserted into
|
||||||
outgoing frame. */
|
outgoing frame. */
|
||||||
struct cas_tx_desc {
|
struct cas_tx_desc {
|
||||||
u64 control;
|
__le64 control;
|
||||||
u64 buffer;
|
__le64 buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* descriptor ring for free buffers contains page-sized buffers. the index
|
/* descriptor ring for free buffers contains page-sized buffers. the index
|
||||||
@ -4131,8 +4131,8 @@ struct cas_tx_desc {
|
|||||||
* the completion ring.
|
* the completion ring.
|
||||||
*/
|
*/
|
||||||
struct cas_rx_desc {
|
struct cas_rx_desc {
|
||||||
u64 index;
|
__le64 index;
|
||||||
u64 buffer;
|
__le64 buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* received packets are put on the completion ring. */
|
/* received packets are put on the completion ring. */
|
||||||
@ -4210,10 +4210,10 @@ struct cas_rx_desc {
|
|||||||
#define RX_INDEX_RELEASE 0x0000000000002000ULL
|
#define RX_INDEX_RELEASE 0x0000000000002000ULL
|
||||||
|
|
||||||
struct cas_rx_comp {
|
struct cas_rx_comp {
|
||||||
u64 word1;
|
__le64 word1;
|
||||||
u64 word2;
|
__le64 word2;
|
||||||
u64 word3;
|
__le64 word3;
|
||||||
u64 word4;
|
__le64 word4;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum link_state {
|
enum link_state {
|
||||||
@ -4252,7 +4252,7 @@ struct cas_init_block {
|
|||||||
struct cas_rx_comp rxcs[N_RX_COMP_RINGS][INIT_BLOCK_RX_COMP];
|
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_rx_desc rxds[N_RX_DESC_RINGS][INIT_BLOCK_RX_DESC];
|
||||||
struct cas_tx_desc txds[N_TX_RINGS][INIT_BLOCK_TX];
|
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
|
/* tiny buffers to deal with target abort issue. we allocate a bit
|
||||||
|
Loading…
Reference in New Issue
Block a user