nbd: tell the block layer that it is not a rotational device
[safe/jmp/linux-2.6] / net / 8021q / vlan_dev.c
index c667860..89a3bbd 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/in.h>
-#include <linux/init.h>
-#include <asm/uaccess.h> /* for copy_from_user */
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
-#include <net/datalink.h>
-#include <net/p8022.h>
 #include <net/arp.h>
 
 #include "vlan.h"
 #include "vlanproc.h"
 #include <linux/if_vlan.h>
-#include <net/ip.h>
 
 /*
  *     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;