diff options
Diffstat (limited to 'drivers/net/macvlan.c')
| -rw-r--r-- | drivers/net/macvlan.c | 72 |
1 files changed, 36 insertions, 36 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 725f4b4afc6d..0da3d36b283b 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
| @@ -532,10 +532,10 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 532 | return NET_XMIT_SUCCESS; | 532 | return NET_XMIT_SUCCESS; |
| 533 | } | 533 | } |
| 534 | } | 534 | } |
| 535 | |||
| 536 | xmit_world: | 535 | xmit_world: |
| 537 | skb->dev = vlan->lowerdev; | 536 | skb->dev = vlan->lowerdev; |
| 538 | return dev_queue_xmit(skb); | 537 | return dev_queue_xmit_accel(skb, |
| 538 | netdev_get_sb_channel(dev) ? dev : NULL); | ||
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | static inline netdev_tx_t macvlan_netpoll_send_skb(struct macvlan_dev *vlan, struct sk_buff *skb) | 541 | static inline netdev_tx_t macvlan_netpoll_send_skb(struct macvlan_dev *vlan, struct sk_buff *skb) |
| @@ -552,19 +552,14 @@ static inline netdev_tx_t macvlan_netpoll_send_skb(struct macvlan_dev *vlan, str | |||
| 552 | static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, | 552 | static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, |
| 553 | struct net_device *dev) | 553 | struct net_device *dev) |
| 554 | { | 554 | { |
| 555 | struct macvlan_dev *vlan = netdev_priv(dev); | ||
| 555 | unsigned int len = skb->len; | 556 | unsigned int len = skb->len; |
| 556 | int ret; | 557 | int ret; |
| 557 | struct macvlan_dev *vlan = netdev_priv(dev); | ||
| 558 | 558 | ||
| 559 | if (unlikely(netpoll_tx_running(dev))) | 559 | if (unlikely(netpoll_tx_running(dev))) |
| 560 | return macvlan_netpoll_send_skb(vlan, skb); | 560 | return macvlan_netpoll_send_skb(vlan, skb); |
| 561 | 561 | ||
| 562 | if (vlan->fwd_priv) { | 562 | ret = macvlan_queue_xmit(skb, dev); |
| 563 | skb->dev = vlan->lowerdev; | ||
| 564 | ret = dev_queue_xmit_accel(skb, vlan->fwd_priv); | ||
| 565 | } else { | ||
| 566 | ret = macvlan_queue_xmit(skb, dev); | ||
| 567 | } | ||
| 568 | 563 | ||
| 569 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { | 564 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { |
| 570 | struct vlan_pcpu_stats *pcpu_stats; | 565 | struct vlan_pcpu_stats *pcpu_stats; |
| @@ -613,26 +608,27 @@ static int macvlan_open(struct net_device *dev) | |||
| 613 | goto hash_add; | 608 | goto hash_add; |
| 614 | } | 609 | } |
| 615 | 610 | ||
| 616 | if (lowerdev->features & NETIF_F_HW_L2FW_DOFFLOAD) { | 611 | err = -EADDRINUSE; |
| 617 | vlan->fwd_priv = | 612 | if (macvlan_addr_busy(vlan->port, dev->dev_addr)) |
| 613 | goto out; | ||
| 614 | |||
| 615 | /* Attempt to populate accel_priv which is used to offload the L2 | ||
| 616 | * forwarding requests for unicast packets. | ||
| 617 | */ | ||
| 618 | if (lowerdev->features & NETIF_F_HW_L2FW_DOFFLOAD) | ||
| 619 | vlan->accel_priv = | ||
| 618 | lowerdev->netdev_ops->ndo_dfwd_add_station(lowerdev, dev); | 620 | lowerdev->netdev_ops->ndo_dfwd_add_station(lowerdev, dev); |
| 619 | 621 | ||
| 620 | /* If we get a NULL pointer back, or if we get an error | 622 | /* If earlier attempt to offload failed, or accel_priv is not |
| 621 | * then we should just fall through to the non accelerated path | 623 | * populated we must add the unicast address to the lower device. |
| 622 | */ | 624 | */ |
| 623 | if (IS_ERR_OR_NULL(vlan->fwd_priv)) { | 625 | if (IS_ERR_OR_NULL(vlan->accel_priv)) { |
| 624 | vlan->fwd_priv = NULL; | 626 | vlan->accel_priv = NULL; |
| 625 | } else | 627 | err = dev_uc_add(lowerdev, dev->dev_addr); |
| 626 | return 0; | 628 | if (err < 0) |
| 629 | goto out; | ||
| 627 | } | 630 | } |
| 628 | 631 | ||
| 629 | err = -EBUSY; | ||
| 630 | if (macvlan_addr_busy(vlan->port, dev->dev_addr)) | ||
| 631 | goto out; | ||
| 632 | |||
| 633 | err = dev_uc_add(lowerdev, dev->dev_addr); | ||
| 634 | if (err < 0) | ||
| 635 | goto out; | ||
| 636 | if (dev->flags & IFF_ALLMULTI) { | 632 | if (dev->flags & IFF_ALLMULTI) { |
| 637 | err = dev_set_allmulti(lowerdev, 1); | 633 | err = dev_set_allmulti(lowerdev, 1); |
| 638 | if (err < 0) | 634 | if (err < 0) |
| @@ -653,13 +649,14 @@ clear_multi: | |||
| 653 | if (dev->flags & IFF_ALLMULTI) | 649 | if (dev->flags & IFF_ALLMULTI) |
| 654 | dev_set_allmulti(lowerdev, -1); | 650 | dev_set_allmulti(lowerdev, -1); |
| 655 | del_unicast: | 651 | del_unicast: |
| 656 | dev_uc_del(lowerdev, dev->dev_addr); | 652 | if (vlan->accel_priv) { |
| 657 | out: | ||
| 658 | if (vlan->fwd_priv) { | ||
| 659 | lowerdev->netdev_ops->ndo_dfwd_del_station(lowerdev, | 653 | lowerdev->netdev_ops->ndo_dfwd_del_station(lowerdev, |
| 660 | vlan->fwd_priv); | 654 | vlan->accel_priv); |
| 661 | vlan->fwd_priv = NULL; | 655 | vlan->accel_priv = NULL; |
| 656 | } else { | ||
| 657 | dev_uc_del(lowerdev, dev->dev_addr); | ||
| 662 | } | 658 | } |
| 659 | out: | ||
| 663 | return err; | 660 | return err; |
| 664 | } | 661 | } |
| 665 | 662 | ||
| @@ -668,11 +665,10 @@ static int macvlan_stop(struct net_device *dev) | |||
| 668 | struct macvlan_dev *vlan = netdev_priv(dev); | 665 | struct macvlan_dev *vlan = netdev_priv(dev); |
| 669 | struct net_device *lowerdev = vlan->lowerdev; | 666 | struct net_device *lowerdev = vlan->lowerdev; |
| 670 | 667 | ||
| 671 | if (vlan->fwd_priv) { | 668 | if (vlan->accel_priv) { |
| 672 | lowerdev->netdev_ops->ndo_dfwd_del_station(lowerdev, | 669 | lowerdev->netdev_ops->ndo_dfwd_del_station(lowerdev, |
| 673 | vlan->fwd_priv); | 670 | vlan->accel_priv); |
| 674 | vlan->fwd_priv = NULL; | 671 | vlan->accel_priv = NULL; |
| 675 | return 0; | ||
| 676 | } | 672 | } |
| 677 | 673 | ||
| 678 | dev_uc_unsync(lowerdev, dev); | 674 | dev_uc_unsync(lowerdev, dev); |
| @@ -710,7 +706,7 @@ static int macvlan_sync_address(struct net_device *dev, unsigned char *addr) | |||
| 710 | } else { | 706 | } else { |
| 711 | /* Rehash and update the device filters */ | 707 | /* Rehash and update the device filters */ |
| 712 | if (macvlan_addr_busy(vlan->port, addr)) | 708 | if (macvlan_addr_busy(vlan->port, addr)) |
| 713 | return -EBUSY; | 709 | return -EADDRINUSE; |
| 714 | 710 | ||
| 715 | if (!macvlan_passthru(port)) { | 711 | if (!macvlan_passthru(port)) { |
| 716 | err = dev_uc_add(lowerdev, addr); | 712 | err = dev_uc_add(lowerdev, addr); |
| @@ -751,6 +747,9 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p) | |||
| 751 | return dev_set_mac_address(vlan->lowerdev, addr); | 747 | return dev_set_mac_address(vlan->lowerdev, addr); |
| 752 | } | 748 | } |
| 753 | 749 | ||
| 750 | if (macvlan_addr_busy(vlan->port, addr->sa_data)) | ||
| 751 | return -EADDRINUSE; | ||
| 752 | |||
| 754 | return macvlan_sync_address(dev, addr->sa_data); | 753 | return macvlan_sync_address(dev, addr->sa_data); |
| 755 | } | 754 | } |
| 756 | 755 | ||
| @@ -1081,7 +1080,7 @@ static void macvlan_dev_netpoll_cleanup(struct net_device *dev) | |||
| 1081 | 1080 | ||
| 1082 | vlan->netpoll = NULL; | 1081 | vlan->netpoll = NULL; |
| 1083 | 1082 | ||
| 1084 | __netpoll_free_async(netpoll); | 1083 | __netpoll_free(netpoll); |
| 1085 | } | 1084 | } |
| 1086 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | 1085 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
| 1087 | 1086 | ||
| @@ -1645,6 +1644,7 @@ static int macvlan_device_event(struct notifier_block *unused, | |||
| 1645 | 1644 | ||
| 1646 | switch (event) { | 1645 | switch (event) { |
| 1647 | case NETDEV_UP: | 1646 | case NETDEV_UP: |
| 1647 | case NETDEV_DOWN: | ||
| 1648 | case NETDEV_CHANGE: | 1648 | case NETDEV_CHANGE: |
| 1649 | list_for_each_entry(vlan, &port->vlans, list) | 1649 | list_for_each_entry(vlan, &port->vlans, list) |
| 1650 | netif_stacked_transfer_operstate(vlan->lowerdev, | 1650 | netif_stacked_transfer_operstate(vlan->lowerdev, |
