aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gallatin <gallatin@myri.com>2012-11-30 03:31:59 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-30 13:44:04 -0500
commit1b4c44e6369dbbafd113f1e00b406f1eda5ab5b2 (patch)
tree179d178b8ebddf77d377e93103048fbbc6bc6fad
parent4ca3221fe4b6c4c6c77352672942e8afa57d55e5 (diff)
myri10ge: Add vlan rx for better GRO perf.
Unlike LRO, GRO requires that vlan tags be removed before aggregation can occur. Since the myri10ge NIC does not support hardware vlan tag offload, we must remove the tag in the driver to achieve performance comparable to LRO for vlan tagged frames. Thanks to Eric Duzamet for his help simplifying the original patch. Signed-off-by: Andrew Gallatin <gallatin@myri.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 84207c04530f..2fc984a03771 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -1264,6 +1264,42 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
1264 } 1264 }
1265} 1265}
1266 1266
1267/*
1268 * GRO does not support acceleration of tagged vlan frames, and
1269 * this NIC does not support vlan tag offload, so we must pop
1270 * the tag ourselves to be able to achieve GRO performance that
1271 * is comparable to LRO.
1272 */
1273
1274static inline void
1275myri10ge_vlan_rx(struct net_device *dev, void *addr, struct sk_buff *skb)
1276{
1277 u8 *va;
1278 struct vlan_ethhdr *veh;
1279 struct skb_frag_struct *frag;
1280 __wsum vsum;
1281
1282 va = addr;
1283 va += MXGEFW_PAD;
1284 veh = (struct vlan_ethhdr *)va;
1285 if ((dev->features & NETIF_F_HW_VLAN_RX) == NETIF_F_HW_VLAN_RX &&
1286 veh->h_vlan_proto == ntohs(ETH_P_8021Q)) {
1287 /* fixup csum if needed */
1288 if (skb->ip_summed == CHECKSUM_COMPLETE) {
1289 vsum = csum_partial(va + ETH_HLEN, VLAN_HLEN, 0);
1290 skb->csum = csum_sub(skb->csum, vsum);
1291 }
1292 /* pop tag */
1293 __vlan_hwaccel_put_tag(skb, ntohs(veh->h_vlan_TCI));
1294 memmove(va + VLAN_HLEN, va, 2 * ETH_ALEN);
1295 skb->len -= VLAN_HLEN;
1296 skb->data_len -= VLAN_HLEN;
1297 frag = skb_shinfo(skb)->frags;
1298 frag->page_offset += VLAN_HLEN;
1299 skb_frag_size_set(frag, skb_frag_size(frag) - VLAN_HLEN);
1300 }
1301}
1302
1267static inline int 1303static inline int
1268myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum) 1304myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum)
1269{ 1305{
@@ -1326,6 +1362,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum)
1326 skb->ip_summed = CHECKSUM_COMPLETE; 1362 skb->ip_summed = CHECKSUM_COMPLETE;
1327 skb->csum = csum; 1363 skb->csum = csum;
1328 } 1364 }
1365 myri10ge_vlan_rx(mgp->dev, va, skb);
1329 skb_record_rx_queue(skb, ss - &mgp->ss[0]); 1366 skb_record_rx_queue(skb, ss - &mgp->ss[0]);
1330 1367
1331 napi_gro_frags(&ss->napi); 1368 napi_gro_frags(&ss->napi);
@@ -3851,6 +3888,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3851 netdev->netdev_ops = &myri10ge_netdev_ops; 3888 netdev->netdev_ops = &myri10ge_netdev_ops;
3852 netdev->mtu = myri10ge_initial_mtu; 3889 netdev->mtu = myri10ge_initial_mtu;
3853 netdev->hw_features = mgp->features | NETIF_F_RXCSUM; 3890 netdev->hw_features = mgp->features | NETIF_F_RXCSUM;
3891
3892 /* fake NETIF_F_HW_VLAN_RX for good GRO performance */
3893 netdev->hw_features |= NETIF_F_HW_VLAN_RX;
3894
3854 netdev->features = netdev->hw_features; 3895 netdev->features = netdev->hw_features;
3855 3896
3856 if (dac_enabled) 3897 if (dac_enabled)