diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 29 | ||||
-rw-r--r-- | drivers/net/mv643xx_eth.h | 4 |
2 files changed, 21 insertions, 12 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 0405e1f0d3df..fb6b232069d6 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -1157,16 +1157,20 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1157 | if (!skb_shinfo(skb)->nr_frags) { | 1157 | if (!skb_shinfo(skb)->nr_frags) { |
1158 | linear: | 1158 | linear: |
1159 | if (skb->ip_summed != CHECKSUM_HW) { | 1159 | if (skb->ip_summed != CHECKSUM_HW) { |
1160 | /* Errata BTS #50, IHL must be 5 if no HW checksum */ | ||
1160 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | | 1161 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | |
1161 | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; | 1162 | ETH_TX_FIRST_DESC | |
1163 | ETH_TX_LAST_DESC | | ||
1164 | 5 << ETH_TX_IHL_SHIFT; | ||
1162 | pkt_info.l4i_chk = 0; | 1165 | pkt_info.l4i_chk = 0; |
1163 | } else { | 1166 | } else { |
1164 | u32 ipheader = skb->nh.iph->ihl << 11; | ||
1165 | 1167 | ||
1166 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | | 1168 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | |
1167 | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC | | 1169 | ETH_TX_FIRST_DESC | |
1168 | ETH_GEN_TCP_UDP_CHECKSUM | | 1170 | ETH_TX_LAST_DESC | |
1169 | ETH_GEN_IP_V_4_CHECKSUM | ipheader; | 1171 | ETH_GEN_TCP_UDP_CHECKSUM | |
1172 | ETH_GEN_IP_V_4_CHECKSUM | | ||
1173 | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; | ||
1170 | /* CPU already calculated pseudo header checksum. */ | 1174 | /* CPU already calculated pseudo header checksum. */ |
1171 | if (skb->nh.iph->protocol == IPPROTO_UDP) { | 1175 | if (skb->nh.iph->protocol == IPPROTO_UDP) { |
1172 | pkt_info.cmd_sts |= ETH_UDP_FRAME; | 1176 | pkt_info.cmd_sts |= ETH_UDP_FRAME; |
@@ -1193,7 +1197,6 @@ linear: | |||
1193 | stats->tx_bytes += pkt_info.byte_cnt; | 1197 | stats->tx_bytes += pkt_info.byte_cnt; |
1194 | } else { | 1198 | } else { |
1195 | unsigned int frag; | 1199 | unsigned int frag; |
1196 | u32 ipheader; | ||
1197 | 1200 | ||
1198 | /* Since hardware can't handle unaligned fragments smaller | 1201 | /* Since hardware can't handle unaligned fragments smaller |
1199 | * than 9 bytes, if we find any, we linearize the skb | 1202 | * than 9 bytes, if we find any, we linearize the skb |
@@ -1222,12 +1225,16 @@ linear: | |||
1222 | DMA_TO_DEVICE); | 1225 | DMA_TO_DEVICE); |
1223 | pkt_info.l4i_chk = 0; | 1226 | pkt_info.l4i_chk = 0; |
1224 | pkt_info.return_info = 0; | 1227 | pkt_info.return_info = 0; |
1225 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC; | ||
1226 | 1228 | ||
1227 | if (skb->ip_summed == CHECKSUM_HW) { | 1229 | if (skb->ip_summed != CHECKSUM_HW) |
1228 | ipheader = skb->nh.iph->ihl << 11; | 1230 | /* Errata BTS #50, IHL must be 5 if no HW checksum */ |
1229 | pkt_info.cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | | 1231 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC | |
1230 | ETH_GEN_IP_V_4_CHECKSUM | ipheader; | 1232 | 5 << ETH_TX_IHL_SHIFT; |
1233 | else { | ||
1234 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC | | ||
1235 | ETH_GEN_TCP_UDP_CHECKSUM | | ||
1236 | ETH_GEN_IP_V_4_CHECKSUM | | ||
1237 | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; | ||
1231 | /* CPU already calculated pseudo header checksum. */ | 1238 | /* CPU already calculated pseudo header checksum. */ |
1232 | if (skb->nh.iph->protocol == IPPROTO_UDP) { | 1239 | if (skb->nh.iph->protocol == IPPROTO_UDP) { |
1233 | pkt_info.cmd_sts |= ETH_UDP_FRAME; | 1240 | pkt_info.cmd_sts |= ETH_UDP_FRAME; |
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h index 57c4f8fbfdb6..7678b59c2952 100644 --- a/drivers/net/mv643xx_eth.h +++ b/drivers/net/mv643xx_eth.h | |||
@@ -49,7 +49,7 @@ | |||
49 | /* Checksum offload for Tx works for most packets, but | 49 | /* Checksum offload for Tx works for most packets, but |
50 | * fails if previous packet sent did not use hw csum | 50 | * fails if previous packet sent did not use hw csum |
51 | */ | 51 | */ |
52 | #undef MV643XX_CHECKSUM_OFFLOAD_TX | 52 | #define MV643XX_CHECKSUM_OFFLOAD_TX |
53 | #define MV643XX_NAPI | 53 | #define MV643XX_NAPI |
54 | #define MV643XX_TX_FAST_REFILL | 54 | #define MV643XX_TX_FAST_REFILL |
55 | #undef MV643XX_RX_QUEUE_FILL_ON_TASK /* Does not work, yet */ | 55 | #undef MV643XX_RX_QUEUE_FILL_ON_TASK /* Does not work, yet */ |
@@ -217,6 +217,8 @@ | |||
217 | #define ETH_TX_ENABLE_INTERRUPT (BIT23) | 217 | #define ETH_TX_ENABLE_INTERRUPT (BIT23) |
218 | #define ETH_AUTO_MODE (BIT30) | 218 | #define ETH_AUTO_MODE (BIT30) |
219 | 219 | ||
220 | #define ETH_TX_IHL_SHIFT 11 | ||
221 | |||
220 | /* typedefs */ | 222 | /* typedefs */ |
221 | 223 | ||
222 | typedef enum _eth_func_ret_status { | 224 | typedef enum _eth_func_ret_status { |