diff options
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 76 |
1 files changed, 60 insertions, 16 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 8883e9c8a223..89a3bbdfca3f 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -163,8 +163,6 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
163 | goto err_unlock; | 163 | goto err_unlock; |
164 | } | 164 | } |
165 | 165 | ||
166 | skb->dev->last_rx = jiffies; | ||
167 | |||
168 | stats = &skb->dev->stats; | 166 | stats = &skb->dev->stats; |
169 | stats->rx_packets++; | 167 | stats->rx_packets++; |
170 | stats->rx_bytes += skb->len; | 168 | stats->rx_bytes += skb->len; |
@@ -526,6 +524,7 @@ out: | |||
526 | static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 524 | static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
527 | { | 525 | { |
528 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | 526 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
527 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
529 | struct ifreq ifrr; | 528 | struct ifreq ifrr; |
530 | int err = -EOPNOTSUPP; | 529 | int err = -EOPNOTSUPP; |
531 | 530 | ||
@@ -536,8 +535,8 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
536 | case SIOCGMIIPHY: | 535 | case SIOCGMIIPHY: |
537 | case SIOCGMIIREG: | 536 | case SIOCGMIIREG: |
538 | case SIOCSMIIREG: | 537 | case SIOCSMIIREG: |
539 | if (real_dev->do_ioctl && netif_device_present(real_dev)) | 538 | if (netif_device_present(real_dev) && ops->ndo_do_ioctl) |
540 | err = real_dev->do_ioctl(real_dev, &ifrr, cmd); | 539 | err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd); |
541 | break; | 540 | break; |
542 | } | 541 | } |
543 | 542 | ||
@@ -594,6 +593,8 @@ static const struct header_ops vlan_header_ops = { | |||
594 | .parse = eth_header_parse, | 593 | .parse = eth_header_parse, |
595 | }; | 594 | }; |
596 | 595 | ||
596 | static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops; | ||
597 | |||
597 | static int vlan_dev_init(struct net_device *dev) | 598 | static int vlan_dev_init(struct net_device *dev) |
598 | { | 599 | { |
599 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | 600 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
@@ -620,11 +621,11 @@ static int vlan_dev_init(struct net_device *dev) | |||
620 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | 621 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { |
621 | dev->header_ops = real_dev->header_ops; | 622 | dev->header_ops = real_dev->header_ops; |
622 | dev->hard_header_len = real_dev->hard_header_len; | 623 | dev->hard_header_len = real_dev->hard_header_len; |
623 | dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; | 624 | dev->netdev_ops = &vlan_netdev_accel_ops; |
624 | } else { | 625 | } else { |
625 | dev->header_ops = &vlan_header_ops; | 626 | dev->header_ops = &vlan_header_ops; |
626 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; | 627 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; |
627 | dev->hard_start_xmit = vlan_dev_hard_start_xmit; | 628 | dev->netdev_ops = &vlan_netdev_ops; |
628 | } | 629 | } |
629 | 630 | ||
630 | if (is_vlan_dev(real_dev)) | 631 | if (is_vlan_dev(real_dev)) |
@@ -648,6 +649,26 @@ static void vlan_dev_uninit(struct net_device *dev) | |||
648 | } | 649 | } |
649 | } | 650 | } |
650 | 651 | ||
652 | static int vlan_ethtool_get_settings(struct net_device *dev, | ||
653 | struct ethtool_cmd *cmd) | ||
654 | { | ||
655 | const struct vlan_dev_info *vlan = vlan_dev_info(dev); | ||
656 | struct net_device *real_dev = vlan->real_dev; | ||
657 | |||
658 | if (!real_dev->ethtool_ops->get_settings) | ||
659 | return -EOPNOTSUPP; | ||
660 | |||
661 | return real_dev->ethtool_ops->get_settings(real_dev, cmd); | ||
662 | } | ||
663 | |||
664 | static void vlan_ethtool_get_drvinfo(struct net_device *dev, | ||
665 | struct ethtool_drvinfo *info) | ||
666 | { | ||
667 | strcpy(info->driver, vlan_fullname); | ||
668 | strcpy(info->version, vlan_version); | ||
669 | strcpy(info->fw_version, "N/A"); | ||
670 | } | ||
671 | |||
651 | static u32 vlan_ethtool_get_rx_csum(struct net_device *dev) | 672 | static u32 vlan_ethtool_get_rx_csum(struct net_device *dev) |
652 | { | 673 | { |
653 | const struct vlan_dev_info *vlan = vlan_dev_info(dev); | 674 | const struct vlan_dev_info *vlan = vlan_dev_info(dev); |
@@ -672,11 +693,43 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev) | |||
672 | } | 693 | } |
673 | 694 | ||
674 | static const struct ethtool_ops vlan_ethtool_ops = { | 695 | static const struct ethtool_ops vlan_ethtool_ops = { |
696 | .get_settings = vlan_ethtool_get_settings, | ||
697 | .get_drvinfo = vlan_ethtool_get_drvinfo, | ||
675 | .get_link = ethtool_op_get_link, | 698 | .get_link = ethtool_op_get_link, |
676 | .get_rx_csum = vlan_ethtool_get_rx_csum, | 699 | .get_rx_csum = vlan_ethtool_get_rx_csum, |
677 | .get_flags = vlan_ethtool_get_flags, | 700 | .get_flags = vlan_ethtool_get_flags, |
678 | }; | 701 | }; |
679 | 702 | ||
703 | static const struct net_device_ops vlan_netdev_ops = { | ||
704 | .ndo_change_mtu = vlan_dev_change_mtu, | ||
705 | .ndo_init = vlan_dev_init, | ||
706 | .ndo_uninit = vlan_dev_uninit, | ||
707 | .ndo_open = vlan_dev_open, | ||
708 | .ndo_stop = vlan_dev_stop, | ||
709 | .ndo_start_xmit = vlan_dev_hard_start_xmit, | ||
710 | .ndo_validate_addr = eth_validate_addr, | ||
711 | .ndo_set_mac_address = vlan_dev_set_mac_address, | ||
712 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, | ||
713 | .ndo_set_multicast_list = vlan_dev_set_rx_mode, | ||
714 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | ||
715 | .ndo_do_ioctl = vlan_dev_ioctl, | ||
716 | }; | ||
717 | |||
718 | static const struct net_device_ops vlan_netdev_accel_ops = { | ||
719 | .ndo_change_mtu = vlan_dev_change_mtu, | ||
720 | .ndo_init = vlan_dev_init, | ||
721 | .ndo_uninit = vlan_dev_uninit, | ||
722 | .ndo_open = vlan_dev_open, | ||
723 | .ndo_stop = vlan_dev_stop, | ||
724 | .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, | ||
725 | .ndo_validate_addr = eth_validate_addr, | ||
726 | .ndo_set_mac_address = vlan_dev_set_mac_address, | ||
727 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, | ||
728 | .ndo_set_multicast_list = vlan_dev_set_rx_mode, | ||
729 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | ||
730 | .ndo_do_ioctl = vlan_dev_ioctl, | ||
731 | }; | ||
732 | |||
680 | void vlan_setup(struct net_device *dev) | 733 | void vlan_setup(struct net_device *dev) |
681 | { | 734 | { |
682 | ether_setup(dev); | 735 | ether_setup(dev); |
@@ -684,16 +737,7 @@ void vlan_setup(struct net_device *dev) | |||
684 | dev->priv_flags |= IFF_802_1Q_VLAN; | 737 | dev->priv_flags |= IFF_802_1Q_VLAN; |
685 | dev->tx_queue_len = 0; | 738 | dev->tx_queue_len = 0; |
686 | 739 | ||
687 | dev->change_mtu = vlan_dev_change_mtu; | 740 | dev->netdev_ops = &vlan_netdev_ops; |
688 | dev->init = vlan_dev_init; | ||
689 | dev->uninit = vlan_dev_uninit; | ||
690 | dev->open = vlan_dev_open; | ||
691 | dev->stop = vlan_dev_stop; | ||
692 | dev->set_mac_address = vlan_dev_set_mac_address; | ||
693 | dev->set_rx_mode = vlan_dev_set_rx_mode; | ||
694 | dev->set_multicast_list = vlan_dev_set_rx_mode; | ||
695 | dev->change_rx_flags = vlan_dev_change_rx_flags; | ||
696 | dev->do_ioctl = vlan_dev_ioctl; | ||
697 | dev->destructor = free_netdev; | 741 | dev->destructor = free_netdev; |
698 | dev->ethtool_ops = &vlan_ethtool_ops; | 742 | dev->ethtool_ops = &vlan_ethtool_ops; |
699 | 743 | ||