diff options
Diffstat (limited to 'drivers/net/loopback.c')
-rw-r--r-- | drivers/net/loopback.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 1f61f0cc95d8..690a1aae0b34 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -68,6 +68,7 @@ static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); | |||
68 | * of largesending device modulo TCP checksum, which is ignored for loopback. | 68 | * of largesending device modulo TCP checksum, which is ignored for loopback. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | #ifdef LOOPBACK_TSO | ||
71 | static void emulate_large_send_offload(struct sk_buff *skb) | 72 | static void emulate_large_send_offload(struct sk_buff *skb) |
72 | { | 73 | { |
73 | struct iphdr *iph = skb->nh.iph; | 74 | struct iphdr *iph = skb->nh.iph; |
@@ -119,6 +120,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) | |||
119 | 120 | ||
120 | dev_kfree_skb(skb); | 121 | dev_kfree_skb(skb); |
121 | } | 122 | } |
123 | #endif /* LOOPBACK_TSO */ | ||
122 | 124 | ||
123 | /* | 125 | /* |
124 | * The higher levels take care of making this non-reentrant (it's | 126 | * The higher levels take care of making this non-reentrant (it's |
@@ -130,12 +132,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
130 | 132 | ||
131 | skb_orphan(skb); | 133 | skb_orphan(skb); |
132 | 134 | ||
133 | skb->protocol=eth_type_trans(skb,dev); | 135 | skb->protocol = eth_type_trans(skb,dev); |
134 | skb->dev=dev; | 136 | skb->dev = dev; |
135 | #ifndef LOOPBACK_MUST_CHECKSUM | 137 | #ifndef LOOPBACK_MUST_CHECKSUM |
136 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 138 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
137 | #endif | 139 | #endif |
138 | 140 | ||
141 | #ifdef LOOPBACK_TSO | ||
139 | if (skb_shinfo(skb)->tso_size) { | 142 | if (skb_shinfo(skb)->tso_size) { |
140 | BUG_ON(skb->protocol != htons(ETH_P_IP)); | 143 | BUG_ON(skb->protocol != htons(ETH_P_IP)); |
141 | BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); | 144 | BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); |
@@ -143,14 +146,14 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
143 | emulate_large_send_offload(skb); | 146 | emulate_large_send_offload(skb); |
144 | return 0; | 147 | return 0; |
145 | } | 148 | } |
146 | 149 | #endif | |
147 | dev->last_rx = jiffies; | 150 | dev->last_rx = jiffies; |
148 | 151 | ||
149 | lb_stats = &per_cpu(loopback_stats, get_cpu()); | 152 | lb_stats = &per_cpu(loopback_stats, get_cpu()); |
150 | lb_stats->rx_bytes += skb->len; | 153 | lb_stats->rx_bytes += skb->len; |
151 | lb_stats->tx_bytes += skb->len; | 154 | lb_stats->tx_bytes = lb_stats->rx_bytes; |
152 | lb_stats->rx_packets++; | 155 | lb_stats->rx_packets++; |
153 | lb_stats->tx_packets++; | 156 | lb_stats->tx_packets = lb_stats->rx_packets; |
154 | put_cpu(); | 157 | put_cpu(); |
155 | 158 | ||
156 | netif_rx(skb); | 159 | netif_rx(skb); |
@@ -208,9 +211,12 @@ struct net_device loopback_dev = { | |||
208 | .type = ARPHRD_LOOPBACK, /* 0x0001*/ | 211 | .type = ARPHRD_LOOPBACK, /* 0x0001*/ |
209 | .rebuild_header = eth_rebuild_header, | 212 | .rebuild_header = eth_rebuild_header, |
210 | .flags = IFF_LOOPBACK, | 213 | .flags = IFF_LOOPBACK, |
211 | .features = NETIF_F_SG|NETIF_F_FRAGLIST | 214 | .features = NETIF_F_SG | NETIF_F_FRAGLIST |
212 | |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA | 215 | #ifdef LOOPBACK_TSO |
213 | |NETIF_F_LLTX, | 216 | | NETIF_F_TSO |
217 | #endif | ||
218 | | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | ||
219 | | NETIF_F_LLTX, | ||
214 | .ethtool_ops = &loopback_ethtool_ops, | 220 | .ethtool_ops = &loopback_ethtool_ops, |
215 | }; | 221 | }; |
216 | 222 | ||