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 | ||
