diff options
author | Vladislav Zolotarov <vladz@broadcom.com> | 2011-04-23 03:44:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-23 18:13:17 -0400 |
commit | e39aece7d41119c3d63f390420e00ab4d2a526a9 (patch) | |
tree | 4b81a22a533a4cc3ae2730305b9aea30cd635961 /drivers/net | |
parent | 13f172ff26563995049abe73f6eeba828de3c09d (diff) |
bnx2x: fix UDP csum offload
Fixed packets parameters for FW in UDP checksum offload flow.
Do not dereference TCP headers on non TCP frames.
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index e83ac6dd6fc0..16581df5ee4e 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
@@ -2019,15 +2019,23 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, | |||
2019 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, | 2019 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, |
2020 | u32 *parsing_data, u32 xmit_type) | 2020 | u32 *parsing_data, u32 xmit_type) |
2021 | { | 2021 | { |
2022 | *parsing_data |= ((tcp_hdrlen(skb)/4) << | 2022 | *parsing_data |= |
2023 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & | 2023 | ((((u8 *)skb_transport_header(skb) - skb->data) >> 1) << |
2024 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; | 2024 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & |
2025 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; | ||
2025 | 2026 | ||
2026 | *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << | 2027 | if (xmit_type & XMIT_CSUM_TCP) { |
2027 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & | 2028 | *parsing_data |= ((tcp_hdrlen(skb) / 4) << |
2028 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; | 2029 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & |
2030 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; | ||
2029 | 2031 | ||
2030 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; | 2032 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; |
2033 | } else | ||
2034 | /* We support checksum offload for TCP and UDP only. | ||
2035 | * No need to pass the UDP header length - it's a constant. | ||
2036 | */ | ||
2037 | return skb_transport_header(skb) + | ||
2038 | sizeof(struct udphdr) - skb->data; | ||
2031 | } | 2039 | } |
2032 | 2040 | ||
2033 | /** | 2041 | /** |
@@ -2043,7 +2051,7 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, | |||
2043 | struct eth_tx_parse_bd_e1x *pbd, | 2051 | struct eth_tx_parse_bd_e1x *pbd, |
2044 | u32 xmit_type) | 2052 | u32 xmit_type) |
2045 | { | 2053 | { |
2046 | u8 hlen = (skb_network_header(skb) - skb->data) / 2; | 2054 | u8 hlen = (skb_network_header(skb) - skb->data) >> 1; |
2047 | 2055 | ||
2048 | /* for now NS flag is not used in Linux */ | 2056 | /* for now NS flag is not used in Linux */ |
2049 | pbd->global_data = | 2057 | pbd->global_data = |
@@ -2051,9 +2059,15 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, | |||
2051 | ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); | 2059 | ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); |
2052 | 2060 | ||
2053 | pbd->ip_hlen_w = (skb_transport_header(skb) - | 2061 | pbd->ip_hlen_w = (skb_transport_header(skb) - |
2054 | skb_network_header(skb)) / 2; | 2062 | skb_network_header(skb)) >> 1; |
2055 | 2063 | ||
2056 | hlen += pbd->ip_hlen_w + tcp_hdrlen(skb) / 2; | 2064 | hlen += pbd->ip_hlen_w; |
2065 | |||
2066 | /* We support checksum offload for TCP and UDP only */ | ||
2067 | if (xmit_type & XMIT_CSUM_TCP) | ||
2068 | hlen += tcp_hdrlen(skb) / 2; | ||
2069 | else | ||
2070 | hlen += sizeof(struct udphdr) / 2; | ||
2057 | 2071 | ||
2058 | pbd->total_hlen_w = cpu_to_le16(hlen); | 2072 | pbd->total_hlen_w = cpu_to_le16(hlen); |
2059 | hlen = hlen*2; | 2073 | hlen = hlen*2; |