]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/8021q/vlan_dev.c
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mv-sheeva.git] / net / 8021q / vlan_dev.c
index 71193a6b10e6bb8ec67d3d1bb09bd1fd9be6bf31..1b34135cf9902e737b91475b7a02c018fc6568f5 100644 (file)
@@ -546,6 +546,18 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return err;
 }
 
+static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa)
+{
+       struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+       const struct net_device_ops *ops = real_dev->netdev_ops;
+       int err = 0;
+
+       if (netif_device_present(real_dev) && ops->ndo_neigh_setup)
+               err = ops->ndo_neigh_setup(real_dev, pa);
+
+       return err;
+}
+
 static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
 {
        struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
@@ -593,6 +605,8 @@ static const struct header_ops vlan_header_ops = {
        .parse   = eth_header_parse,
 };
 
+static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops;
+
 static int vlan_dev_init(struct net_device *dev)
 {
        struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
@@ -619,12 +633,13 @@ static int vlan_dev_init(struct net_device *dev)
        if (real_dev->features & NETIF_F_HW_VLAN_TX) {
                dev->header_ops      = real_dev->header_ops;
                dev->hard_header_len = real_dev->hard_header_len;
-               dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
+               dev->netdev_ops         = &vlan_netdev_accel_ops;
        } else {
                dev->header_ops      = &vlan_header_ops;
                dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
-               dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+               dev->netdev_ops         = &vlan_netdev_ops;
        }
+       netdev_resync_ops(dev);
 
        if (is_vlan_dev(real_dev))
                subclass = 1;
@@ -704,12 +719,30 @@ static const struct net_device_ops vlan_netdev_ops = {
        .ndo_uninit             = vlan_dev_uninit,
        .ndo_open               = vlan_dev_open,
        .ndo_stop               = vlan_dev_stop,
+       .ndo_start_xmit =  vlan_dev_hard_start_xmit,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = vlan_dev_set_mac_address,
+       .ndo_set_rx_mode        = vlan_dev_set_rx_mode,
+       .ndo_set_multicast_list = vlan_dev_set_rx_mode,
+       .ndo_change_rx_flags    = vlan_dev_change_rx_flags,
+       .ndo_do_ioctl           = vlan_dev_ioctl,
+       .ndo_neigh_setup        = vlan_dev_neigh_setup,
+};
+
+static const struct net_device_ops vlan_netdev_accel_ops = {
+       .ndo_change_mtu         = vlan_dev_change_mtu,
+       .ndo_init               = vlan_dev_init,
+       .ndo_uninit             = vlan_dev_uninit,
+       .ndo_open               = vlan_dev_open,
+       .ndo_stop               = vlan_dev_stop,
+       .ndo_start_xmit =  vlan_dev_hwaccel_hard_start_xmit,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = vlan_dev_set_mac_address,
        .ndo_set_rx_mode        = vlan_dev_set_rx_mode,
        .ndo_set_multicast_list = vlan_dev_set_rx_mode,
        .ndo_change_rx_flags    = vlan_dev_change_rx_flags,
        .ndo_do_ioctl           = vlan_dev_ioctl,
+       .ndo_neigh_setup        = vlan_dev_neigh_setup,
 };
 
 void vlan_setup(struct net_device *dev)