diff options
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r-- | drivers/net/macvlan.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index acf93798dc67..bc8faaec33f5 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -299,7 +299,7 @@ netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, | |||
299 | 299 | ||
300 | if (vlan->fwd_priv) { | 300 | if (vlan->fwd_priv) { |
301 | skb->dev = vlan->lowerdev; | 301 | skb->dev = vlan->lowerdev; |
302 | ret = dev_hard_start_xmit(skb, skb->dev, NULL, vlan->fwd_priv); | 302 | ret = dev_queue_xmit_accel(skb, vlan->fwd_priv); |
303 | } else { | 303 | } else { |
304 | ret = macvlan_queue_xmit(skb, dev); | 304 | ret = macvlan_queue_xmit(skb, dev); |
305 | } | 305 | } |
@@ -338,6 +338,8 @@ static const struct header_ops macvlan_hard_header_ops = { | |||
338 | .cache_update = eth_header_cache_update, | 338 | .cache_update = eth_header_cache_update, |
339 | }; | 339 | }; |
340 | 340 | ||
341 | static struct rtnl_link_ops macvlan_link_ops; | ||
342 | |||
341 | static int macvlan_open(struct net_device *dev) | 343 | static int macvlan_open(struct net_device *dev) |
342 | { | 344 | { |
343 | struct macvlan_dev *vlan = netdev_priv(dev); | 345 | struct macvlan_dev *vlan = netdev_priv(dev); |
@@ -353,7 +355,8 @@ static int macvlan_open(struct net_device *dev) | |||
353 | goto hash_add; | 355 | goto hash_add; |
354 | } | 356 | } |
355 | 357 | ||
356 | if (lowerdev->features & NETIF_F_HW_L2FW_DOFFLOAD) { | 358 | if (lowerdev->features & NETIF_F_HW_L2FW_DOFFLOAD && |
359 | dev->rtnl_link_ops == &macvlan_link_ops) { | ||
357 | vlan->fwd_priv = | 360 | vlan->fwd_priv = |
358 | lowerdev->netdev_ops->ndo_dfwd_add_station(lowerdev, dev); | 361 | lowerdev->netdev_ops->ndo_dfwd_add_station(lowerdev, dev); |
359 | 362 | ||
@@ -362,10 +365,8 @@ static int macvlan_open(struct net_device *dev) | |||
362 | */ | 365 | */ |
363 | if (IS_ERR_OR_NULL(vlan->fwd_priv)) { | 366 | if (IS_ERR_OR_NULL(vlan->fwd_priv)) { |
364 | vlan->fwd_priv = NULL; | 367 | vlan->fwd_priv = NULL; |
365 | } else { | 368 | } else |
366 | dev->features &= ~NETIF_F_LLTX; | ||
367 | return 0; | 369 | return 0; |
368 | } | ||
369 | } | 370 | } |
370 | 371 | ||
371 | err = -EBUSY; | 372 | err = -EBUSY; |
@@ -690,8 +691,18 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev, | |||
690 | netdev_features_t features) | 691 | netdev_features_t features) |
691 | { | 692 | { |
692 | struct macvlan_dev *vlan = netdev_priv(dev); | 693 | struct macvlan_dev *vlan = netdev_priv(dev); |
694 | netdev_features_t mask; | ||
695 | |||
696 | features |= NETIF_F_ALL_FOR_ALL; | ||
697 | features &= (vlan->set_features | ~MACVLAN_FEATURES); | ||
698 | mask = features; | ||
699 | |||
700 | features = netdev_increment_features(vlan->lowerdev->features, | ||
701 | features, | ||
702 | mask); | ||
703 | features |= NETIF_F_LLTX; | ||
693 | 704 | ||
694 | return features & (vlan->set_features | ~MACVLAN_FEATURES); | 705 | return features; |
695 | } | 706 | } |
696 | 707 | ||
697 | static const struct ethtool_ops macvlan_ethtool_ops = { | 708 | static const struct ethtool_ops macvlan_ethtool_ops = { |
@@ -1019,9 +1030,8 @@ static int macvlan_device_event(struct notifier_block *unused, | |||
1019 | break; | 1030 | break; |
1020 | case NETDEV_FEAT_CHANGE: | 1031 | case NETDEV_FEAT_CHANGE: |
1021 | list_for_each_entry(vlan, &port->vlans, list) { | 1032 | list_for_each_entry(vlan, &port->vlans, list) { |
1022 | vlan->dev->features = dev->features & MACVLAN_FEATURES; | ||
1023 | vlan->dev->gso_max_size = dev->gso_max_size; | 1033 | vlan->dev->gso_max_size = dev->gso_max_size; |
1024 | netdev_features_change(vlan->dev); | 1034 | netdev_update_features(vlan->dev); |
1025 | } | 1035 | } |
1026 | break; | 1036 | break; |
1027 | case NETDEV_UNREGISTER: | 1037 | case NETDEV_UNREGISTER: |