X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2F8021q%2Fvlan_dev.c;h=89a3bbdfca3fe96e786044ed8ea8b5022ab4e5b1;hb=31dcfab0ae6eb0340d456931df4d478e17efc65d;hp=c6678605fc0359e0a4b9a44ca16b8798d1c69589;hpb=1349fe9a6bc580fb80e1a43a93b68c15d674ed0a;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index c667860..89a3bbd 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -21,22 +21,15 @@ */ #include -#include -#include -#include -#include /* for copy_from_user */ #include #include #include #include -#include -#include #include #include "vlan.h" #include "vlanproc.h" #include -#include /* * Rebuild the Ethernet MAC header. This is called after an ARP @@ -55,7 +48,7 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb) switch (veth->h_vlan_encapsulated_proto) { #ifdef CONFIG_INET - case __constant_htons(ETH_P_IP): + case htons(ETH_P_IP): /* TODO: Confirm this will work with VLAN headers... */ return arp_find(veth->h_dest, skb); @@ -170,8 +163,6 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, goto err_unlock; } - skb->dev->last_rx = jiffies; - stats = &skb->dev->stats; stats->rx_packets++; stats->rx_bytes += skb->len; @@ -307,53 +298,31 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ - if (veth->h_vlan_proto != htons(ETH_P_8021Q) || - vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { - int orig_headroom = skb_headroom(skb); + vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { + unsigned int orig_headroom = skb_headroom(skb); u16 vlan_tci; - /* This is not a VLAN frame...but we can fix that! */ vlan_dev_info(dev)->cnt_encap_on_xmit++; - pr_debug("%s: proto to encap: 0x%hx\n", - __func__, ntohs(veth->h_vlan_proto)); - /* Construct the second two bytes. This field looks something - * like: - * usr_priority: 3 bits (high bits) - * CFI 1 bit - * VLAN ID 12 bits (low bits) - */ vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); - skb = __vlan_put_tag(skb, vlan_tci); if (!skb) { stats->tx_dropped++; - return 0; + return NETDEV_TX_OK; } if (orig_headroom < VLAN_HLEN) vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; } - pr_debug("%s: about to send skb: %p to dev: %s\n", - __func__, skb, skb->dev->name); - pr_debug(" " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n", - veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], - veth->h_dest[3], veth->h_dest[4], veth->h_dest[5], - veth->h_source[0], veth->h_source[1], veth->h_source[2], - veth->h_source[3], veth->h_source[4], veth->h_source[5], - veth->h_vlan_proto, veth->h_vlan_TCI, - veth->h_vlan_encapsulated_proto); - - stats->tx_packets++; /* for statics only */ + stats->tx_packets++; stats->tx_bytes += skb->len; skb->dev = vlan_dev_info(dev)->real_dev; dev_queue_xmit(skb); - - return 0; + return NETDEV_TX_OK; } static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, @@ -362,12 +331,6 @@ static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device_stats *stats = &dev->stats; u16 vlan_tci; - /* Construct the second two bytes. This field looks something - * like: - * usr_priority: 3 bits (high bits) - * CFI 1 bit - * VLAN ID 12 bits (low bits) - */ vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_hwaccel_put_tag(skb, vlan_tci); @@ -377,8 +340,7 @@ static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, skb->dev = vlan_dev_info(dev)->real_dev; dev_queue_xmit(skb); - - return 0; + return NETDEV_TX_OK; } static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) @@ -562,6 +524,7 @@ out: static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct net_device *real_dev = vlan_dev_info(dev)->real_dev; + const struct net_device_ops *ops = real_dev->netdev_ops; struct ifreq ifrr; int err = -EOPNOTSUPP; @@ -572,8 +535,8 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIPHY: case SIOCGMIIREG: case SIOCSMIIREG: - if (real_dev->do_ioctl && netif_device_present(real_dev)) - err = real_dev->do_ioctl(real_dev, &ifrr, cmd); + if (netif_device_present(real_dev) && ops->ndo_do_ioctl) + err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd); break; } @@ -605,17 +568,23 @@ static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) * separate class since they always nest. */ static struct lock_class_key vlan_netdev_xmit_lock_key; +static struct lock_class_key vlan_netdev_addr_lock_key; -static void vlan_dev_set_lockdep_one(struct netdev_queue *txq, - int subclass) +static void vlan_dev_set_lockdep_one(struct net_device *dev, + struct netdev_queue *txq, + void *_subclass) { lockdep_set_class_and_subclass(&txq->_xmit_lock, - &vlan_netdev_xmit_lock_key, subclass); + &vlan_netdev_xmit_lock_key, + *(int *)_subclass); } static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass) { - vlan_dev_set_lockdep_one(&dev->tx_queue, subclass); + lockdep_set_class_and_subclass(&dev->addr_list_lock, + &vlan_netdev_addr_lock_key, + subclass); + netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass); } static const struct header_ops vlan_header_ops = { @@ -624,6 +593,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; @@ -637,6 +608,7 @@ static int vlan_dev_init(struct net_device *dev) (1<<__LINK_STATE_PRESENT); dev->features |= real_dev->features & real_dev->vlan_features; + dev->gso_max_size = real_dev->gso_max_size; /* ipv6 shared card related stuff */ dev->dev_id = real_dev->dev_id; @@ -649,11 +621,11 @@ 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; } if (is_vlan_dev(real_dev)) @@ -677,6 +649,26 @@ static void vlan_dev_uninit(struct net_device *dev) } } +static int vlan_ethtool_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + const struct vlan_dev_info *vlan = vlan_dev_info(dev); + struct net_device *real_dev = vlan->real_dev; + + if (!real_dev->ethtool_ops->get_settings) + return -EOPNOTSUPP; + + return real_dev->ethtool_ops->get_settings(real_dev, cmd); +} + +static void vlan_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, vlan_fullname); + strcpy(info->version, vlan_version); + strcpy(info->fw_version, "N/A"); +} + static u32 vlan_ethtool_get_rx_csum(struct net_device *dev) { const struct vlan_dev_info *vlan = vlan_dev_info(dev); @@ -701,11 +693,43 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev) } static const struct ethtool_ops vlan_ethtool_ops = { + .get_settings = vlan_ethtool_get_settings, + .get_drvinfo = vlan_ethtool_get_drvinfo, .get_link = ethtool_op_get_link, .get_rx_csum = vlan_ethtool_get_rx_csum, .get_flags = vlan_ethtool_get_flags, }; +static const struct net_device_ops vlan_netdev_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_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, +}; + +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, +}; + void vlan_setup(struct net_device *dev) { ether_setup(dev); @@ -713,16 +737,7 @@ void vlan_setup(struct net_device *dev) dev->priv_flags |= IFF_802_1Q_VLAN; dev->tx_queue_len = 0; - dev->change_mtu = vlan_dev_change_mtu; - dev->init = vlan_dev_init; - dev->uninit = vlan_dev_uninit; - dev->open = vlan_dev_open; - dev->stop = vlan_dev_stop; - dev->set_mac_address = vlan_dev_set_mac_address; - dev->set_rx_mode = vlan_dev_set_rx_mode; - dev->set_multicast_list = vlan_dev_set_rx_mode; - dev->change_rx_flags = vlan_dev_change_rx_flags; - dev->do_ioctl = vlan_dev_ioctl; + dev->netdev_ops = &vlan_netdev_ops; dev->destructor = free_netdev; dev->ethtool_ops = &vlan_ethtool_ops;