diff options
Diffstat (limited to 'net/8021q/vlan_dev.c')
| -rw-r--r-- | net/8021q/vlan_dev.c | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9e83272fc5b0..29b6348c8d4d 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/slab.h> | ||
| 24 | #include <linux/skbuff.h> | 25 | #include <linux/skbuff.h> |
| 25 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
| 26 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
| @@ -361,6 +362,14 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, | |||
| 361 | return ret; | 362 | return ret; |
| 362 | } | 363 | } |
| 363 | 364 | ||
| 365 | static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
| 366 | { | ||
| 367 | struct net_device *rdev = vlan_dev_info(dev)->real_dev; | ||
| 368 | const struct net_device_ops *ops = rdev->netdev_ops; | ||
| 369 | |||
| 370 | return ops->ndo_select_queue(rdev, skb); | ||
| 371 | } | ||
| 372 | |||
| 364 | static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | 373 | static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) |
| 365 | { | 374 | { |
| 366 | /* TODO: gotta make sure the underlying layer can handle it, | 375 | /* TODO: gotta make sure the underlying layer can handle it, |
| @@ -688,7 +697,8 @@ static const struct header_ops vlan_header_ops = { | |||
| 688 | .parse = eth_header_parse, | 697 | .parse = eth_header_parse, |
| 689 | }; | 698 | }; |
| 690 | 699 | ||
| 691 | static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops; | 700 | static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops, |
| 701 | vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq; | ||
| 692 | 702 | ||
| 693 | static int vlan_dev_init(struct net_device *dev) | 703 | static int vlan_dev_init(struct net_device *dev) |
| 694 | { | 704 | { |
| @@ -722,11 +732,17 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 722 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | 732 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { |
| 723 | dev->header_ops = real_dev->header_ops; | 733 | dev->header_ops = real_dev->header_ops; |
| 724 | dev->hard_header_len = real_dev->hard_header_len; | 734 | dev->hard_header_len = real_dev->hard_header_len; |
| 725 | dev->netdev_ops = &vlan_netdev_accel_ops; | 735 | if (real_dev->netdev_ops->ndo_select_queue) |
| 736 | dev->netdev_ops = &vlan_netdev_accel_ops_sq; | ||
| 737 | else | ||
| 738 | dev->netdev_ops = &vlan_netdev_accel_ops; | ||
| 726 | } else { | 739 | } else { |
| 727 | dev->header_ops = &vlan_header_ops; | 740 | dev->header_ops = &vlan_header_ops; |
| 728 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; | 741 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; |
| 729 | dev->netdev_ops = &vlan_netdev_ops; | 742 | if (real_dev->netdev_ops->ndo_select_queue) |
| 743 | dev->netdev_ops = &vlan_netdev_ops_sq; | ||
| 744 | else | ||
| 745 | dev->netdev_ops = &vlan_netdev_ops; | ||
| 730 | } | 746 | } |
| 731 | 747 | ||
| 732 | if (is_vlan_dev(real_dev)) | 748 | if (is_vlan_dev(real_dev)) |
| @@ -865,6 +881,56 @@ static const struct net_device_ops vlan_netdev_accel_ops = { | |||
| 865 | #endif | 881 | #endif |
| 866 | }; | 882 | }; |
| 867 | 883 | ||
| 884 | static const struct net_device_ops vlan_netdev_ops_sq = { | ||
| 885 | .ndo_select_queue = vlan_dev_select_queue, | ||
| 886 | .ndo_change_mtu = vlan_dev_change_mtu, | ||
| 887 | .ndo_init = vlan_dev_init, | ||
| 888 | .ndo_uninit = vlan_dev_uninit, | ||
| 889 | .ndo_open = vlan_dev_open, | ||
| 890 | .ndo_stop = vlan_dev_stop, | ||
| 891 | .ndo_start_xmit = vlan_dev_hard_start_xmit, | ||
| 892 | .ndo_validate_addr = eth_validate_addr, | ||
| 893 | .ndo_set_mac_address = vlan_dev_set_mac_address, | ||
| 894 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, | ||
| 895 | .ndo_set_multicast_list = vlan_dev_set_rx_mode, | ||
| 896 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | ||
| 897 | .ndo_do_ioctl = vlan_dev_ioctl, | ||
| 898 | .ndo_neigh_setup = vlan_dev_neigh_setup, | ||
| 899 | .ndo_get_stats = vlan_dev_get_stats, | ||
| 900 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
| 901 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | ||
| 902 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | ||
| 903 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | ||
| 904 | .ndo_fcoe_disable = vlan_dev_fcoe_disable, | ||
| 905 | .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, | ||
| 906 | #endif | ||
| 907 | }; | ||
| 908 | |||
| 909 | static const struct net_device_ops vlan_netdev_accel_ops_sq = { | ||
| 910 | .ndo_select_queue = vlan_dev_select_queue, | ||
| 911 | .ndo_change_mtu = vlan_dev_change_mtu, | ||
| 912 | .ndo_init = vlan_dev_init, | ||
| 913 | .ndo_uninit = vlan_dev_uninit, | ||
| 914 | .ndo_open = vlan_dev_open, | ||
| 915 | .ndo_stop = vlan_dev_stop, | ||
| 916 | .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, | ||
| 917 | .ndo_validate_addr = eth_validate_addr, | ||
| 918 | .ndo_set_mac_address = vlan_dev_set_mac_address, | ||
| 919 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, | ||
| 920 | .ndo_set_multicast_list = vlan_dev_set_rx_mode, | ||
| 921 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | ||
| 922 | .ndo_do_ioctl = vlan_dev_ioctl, | ||
| 923 | .ndo_neigh_setup = vlan_dev_neigh_setup, | ||
| 924 | .ndo_get_stats = vlan_dev_get_stats, | ||
| 925 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
| 926 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | ||
| 927 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | ||
| 928 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | ||
| 929 | .ndo_fcoe_disable = vlan_dev_fcoe_disable, | ||
| 930 | .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, | ||
| 931 | #endif | ||
| 932 | }; | ||
| 933 | |||
| 868 | void vlan_setup(struct net_device *dev) | 934 | void vlan_setup(struct net_device *dev) |
| 869 | { | 935 | { |
| 870 | ether_setup(dev); | 936 | ether_setup(dev); |
