]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/8021q/vlan_dev.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / net / 8021q / vlan_dev.c
index 14e3d1fa07a0f70df457515f3aede2d31e77c9cb..be737539f34d1be9849a142c2ed176e48c537298 100644 (file)
@@ -141,7 +141,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
                  struct packet_type *ptype, struct net_device *orig_dev)
 {
        struct vlan_hdr *vhdr;
-       struct vlan_rx_stats *rx_stats;
+       struct vlan_pcpu_stats *rx_stats;
        struct net_device *vlan_dev;
        u16 vlan_id;
        u16 vlan_tci;
@@ -177,7 +177,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
        } else {
                skb->dev = vlan_dev;
 
-               rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats);
+               rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats);
 
                u64_stats_update_begin(&rx_stats->syncp);
                rx_stats->rx_packets++;
@@ -274,9 +274,6 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
        u16 vlan_tci = 0;
        int rc;
 
-       if (WARN_ON(skb_headroom(skb) < dev->hard_header_len))
-               return -ENOSPC;
-
        if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) {
                vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN);
 
@@ -313,8 +310,6 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
                                            struct net_device *dev)
 {
-       int i = skb_get_queue_mapping(skb);
-       struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
        unsigned int len;
        int ret;
@@ -326,71 +321,31 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
         */
        if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
            vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) {
-               unsigned int orig_headroom = skb_headroom(skb);
                u16 vlan_tci;
-
-               vlan_dev_info(dev)->cnt_encap_on_xmit++;
-
                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) {
-                       txq->tx_dropped++;
-                       return NETDEV_TX_OK;
-               }
-
-               if (orig_headroom < VLAN_HLEN)
-                       vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
+               skb = __vlan_hwaccel_put_tag(skb, vlan_tci);
        }
 
-
        skb_set_dev(skb, vlan_dev_info(dev)->real_dev);
        len = skb->len;
        ret = dev_queue_xmit(skb);
 
        if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
-               txq->tx_packets++;
-               txq->tx_bytes += len;
-       } else
-               txq->tx_dropped++;
+               struct vlan_pcpu_stats *stats;
 
-       return ret;
-}
-
-static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
-                                                   struct net_device *dev)
-{
-       int i = skb_get_queue_mapping(skb);
-       struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
-       u16 vlan_tci;
-       unsigned int len;
-       int ret;
-
-       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);
-
-       skb->dev = vlan_dev_info(dev)->real_dev;
-       len = skb->len;
-       ret = dev_queue_xmit(skb);
-
-       if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
-               txq->tx_packets++;
-               txq->tx_bytes += len;
-       } else
-               txq->tx_dropped++;
+               stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats);
+               u64_stats_update_begin(&stats->syncp);
+               stats->tx_packets++;
+               stats->tx_bytes += len;
+               u64_stats_update_begin(&stats->syncp);
+       } else {
+               this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped);
+       }
 
        return ret;
 }
 
-static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb)
-{
-       struct net_device *rdev = vlan_dev_info(dev)->real_dev;
-       const struct net_device_ops *ops = rdev->netdev_ops;
-
-       return ops->ndo_select_queue(rdev, skb);
-}
-
 static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
 {
        /* TODO: gotta make sure the underlying layer can handle it,
@@ -719,8 +674,7 @@ 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,
-                   vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq;
+static const struct net_device_ops vlan_netdev_ops;
 
 static int vlan_dev_init(struct net_device *dev)
 {
@@ -738,6 +692,7 @@ static int vlan_dev_init(struct net_device *dev)
                      (1<<__LINK_STATE_PRESENT);
 
        dev->features |= real_dev->features & real_dev->vlan_features;
+       dev->features |= NETIF_F_LLTX;
        dev->gso_max_size = real_dev->gso_max_size;
 
        /* ipv6 shared card related stuff */
@@ -755,26 +710,20 @@ 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;
-               if (real_dev->netdev_ops->ndo_select_queue)
-                       dev->netdev_ops = &vlan_netdev_accel_ops_sq;
-               else
-                       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;
-               if (real_dev->netdev_ops->ndo_select_queue)
-                       dev->netdev_ops = &vlan_netdev_ops_sq;
-               else
-                       dev->netdev_ops = &vlan_netdev_ops;
        }
 
+       dev->netdev_ops = &vlan_netdev_ops;
+
        if (is_vlan_dev(real_dev))
                subclass = 1;
 
        vlan_dev_set_lockdep_class(dev, subclass);
 
-       vlan_dev_info(dev)->vlan_rx_stats = alloc_percpu(struct vlan_rx_stats);
-       if (!vlan_dev_info(dev)->vlan_rx_stats)
+       vlan_dev_info(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats);
+       if (!vlan_dev_info(dev)->vlan_pcpu_stats)
                return -ENOMEM;
 
        return 0;
@@ -786,8 +735,8 @@ static void vlan_dev_uninit(struct net_device *dev)
        struct vlan_dev_info *vlan = vlan_dev_info(dev);
        int i;
 
-       free_percpu(vlan->vlan_rx_stats);
-       vlan->vlan_rx_stats = NULL;
+       free_percpu(vlan->vlan_pcpu_stats);
+       vlan->vlan_pcpu_stats = NULL;
        for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) {
                while ((pm = vlan->egress_priority_map[i]) != NULL) {
                        vlan->egress_priority_map[i] = pm->next;
@@ -825,33 +774,37 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev)
 
 static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
-       dev_txq_stats_fold(dev, stats);
 
-       if (vlan_dev_info(dev)->vlan_rx_stats) {
-               struct vlan_rx_stats *p, accum = {0};
+       if (vlan_dev_info(dev)->vlan_pcpu_stats) {
+               struct vlan_pcpu_stats *p;
+               u32 rx_errors = 0, tx_dropped = 0;
                int i;
 
                for_each_possible_cpu(i) {
-                       u64 rxpackets, rxbytes, rxmulticast;
+                       u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes;
                        unsigned int start;
 
-                       p = per_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats, i);
+                       p = per_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats, i);
                        do {
                                start = u64_stats_fetch_begin_bh(&p->syncp);
                                rxpackets       = p->rx_packets;
                                rxbytes         = p->rx_bytes;
                                rxmulticast     = p->rx_multicast;
+                               txpackets       = p->tx_packets;
+                               txbytes         = p->tx_bytes;
                        } while (u64_stats_fetch_retry_bh(&p->syncp, start));
-                       accum.rx_packets += rxpackets;
-                       accum.rx_bytes   += rxbytes;
-                       accum.rx_multicast += rxmulticast;
-                       /* rx_errors is ulong, not protected by syncp */
-                       accum.rx_errors  += p->rx_errors;
+
+                       stats->rx_packets       += rxpackets;
+                       stats->rx_bytes         += rxbytes;
+                       stats->multicast        += rxmulticast;
+                       stats->tx_packets       += txpackets;
+                       stats->tx_bytes         += txbytes;
+                       /* rx_errors & tx_dropped are u32 */
+                       rx_errors       += p->rx_errors;
+                       tx_dropped      += p->tx_dropped;
                }
-               stats->rx_packets = accum.rx_packets;
-               stats->rx_bytes   = accum.rx_bytes;
-               stats->rx_errors  = accum.rx_errors;
-               stats->multicast  = accum.rx_multicast;
+               stats->rx_errors  = rx_errors;
+               stats->tx_dropped = tx_dropped;
        }
        return stats;
 }
@@ -908,80 +861,6 @@ static const struct net_device_ops vlan_netdev_ops = {
 #endif
 };
 
-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,
-       .ndo_get_stats64        = vlan_dev_get_stats64,
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-       .ndo_fcoe_ddp_setup     = vlan_dev_fcoe_ddp_setup,
-       .ndo_fcoe_ddp_done      = vlan_dev_fcoe_ddp_done,
-       .ndo_fcoe_enable        = vlan_dev_fcoe_enable,
-       .ndo_fcoe_disable       = vlan_dev_fcoe_disable,
-       .ndo_fcoe_get_wwn       = vlan_dev_fcoe_get_wwn,
-#endif
-};
-
-static const struct net_device_ops vlan_netdev_ops_sq = {
-       .ndo_select_queue       = vlan_dev_select_queue,
-       .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,
-       .ndo_neigh_setup        = vlan_dev_neigh_setup,
-       .ndo_get_stats64        = vlan_dev_get_stats64,
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-       .ndo_fcoe_ddp_setup     = vlan_dev_fcoe_ddp_setup,
-       .ndo_fcoe_ddp_done      = vlan_dev_fcoe_ddp_done,
-       .ndo_fcoe_enable        = vlan_dev_fcoe_enable,
-       .ndo_fcoe_disable       = vlan_dev_fcoe_disable,
-       .ndo_fcoe_get_wwn       = vlan_dev_fcoe_get_wwn,
-#endif
-};
-
-static const struct net_device_ops vlan_netdev_accel_ops_sq = {
-       .ndo_select_queue       = vlan_dev_select_queue,
-       .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,
-       .ndo_get_stats64        = vlan_dev_get_stats64,
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-       .ndo_fcoe_ddp_setup     = vlan_dev_fcoe_ddp_setup,
-       .ndo_fcoe_ddp_done      = vlan_dev_fcoe_ddp_done,
-       .ndo_fcoe_enable        = vlan_dev_fcoe_enable,
-       .ndo_fcoe_disable       = vlan_dev_fcoe_disable,
-       .ndo_fcoe_get_wwn       = vlan_dev_fcoe_get_wwn,
-#endif
-};
-
 void vlan_setup(struct net_device *dev)
 {
        ether_setup(dev);