diff options
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 107 |
1 files changed, 95 insertions, 12 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 96bad8f233e2..4198ec5c8abc 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -288,10 +288,14 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
288 | return rc; | 288 | return rc; |
289 | } | 289 | } |
290 | 290 | ||
291 | static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | 291 | static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, |
292 | struct net_device *dev) | ||
292 | { | 293 | { |
293 | struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); | 294 | int i = skb_get_queue_mapping(skb); |
295 | struct netdev_queue *txq = netdev_get_tx_queue(dev, i); | ||
294 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); | 296 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); |
297 | unsigned int len; | ||
298 | int ret; | ||
295 | 299 | ||
296 | /* Handle non-VLAN frames if they are sent to us, for example by DHCP. | 300 | /* Handle non-VLAN frames if they are sent to us, for example by DHCP. |
297 | * | 301 | * |
@@ -317,29 +321,43 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
317 | vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; | 321 | vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; |
318 | } | 322 | } |
319 | 323 | ||
320 | txq->tx_packets++; | ||
321 | txq->tx_bytes += skb->len; | ||
322 | 324 | ||
323 | skb->dev = vlan_dev_info(dev)->real_dev; | 325 | skb->dev = vlan_dev_info(dev)->real_dev; |
324 | dev_queue_xmit(skb); | 326 | len = skb->len; |
327 | ret = dev_queue_xmit(skb); | ||
328 | |||
329 | if (likely(ret == NET_XMIT_SUCCESS)) { | ||
330 | txq->tx_packets++; | ||
331 | txq->tx_bytes += len; | ||
332 | } else | ||
333 | txq->tx_dropped++; | ||
334 | |||
325 | return NETDEV_TX_OK; | 335 | return NETDEV_TX_OK; |
326 | } | 336 | } |
327 | 337 | ||
328 | static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, | 338 | static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, |
329 | struct net_device *dev) | 339 | struct net_device *dev) |
330 | { | 340 | { |
331 | struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); | 341 | int i = skb_get_queue_mapping(skb); |
342 | struct netdev_queue *txq = netdev_get_tx_queue(dev, i); | ||
332 | u16 vlan_tci; | 343 | u16 vlan_tci; |
344 | unsigned int len; | ||
345 | int ret; | ||
333 | 346 | ||
334 | vlan_tci = vlan_dev_info(dev)->vlan_id; | 347 | vlan_tci = vlan_dev_info(dev)->vlan_id; |
335 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); | 348 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); |
336 | skb = __vlan_hwaccel_put_tag(skb, vlan_tci); | 349 | skb = __vlan_hwaccel_put_tag(skb, vlan_tci); |
337 | 350 | ||
338 | txq->tx_packets++; | ||
339 | txq->tx_bytes += skb->len; | ||
340 | |||
341 | skb->dev = vlan_dev_info(dev)->real_dev; | 351 | skb->dev = vlan_dev_info(dev)->real_dev; |
342 | dev_queue_xmit(skb); | 352 | len = skb->len; |
353 | ret = dev_queue_xmit(skb); | ||
354 | |||
355 | if (likely(ret == NET_XMIT_SUCCESS)) { | ||
356 | txq->tx_packets++; | ||
357 | txq->tx_bytes += len; | ||
358 | } else | ||
359 | txq->tx_dropped++; | ||
360 | |||
343 | return NETDEV_TX_OK; | 361 | return NETDEV_TX_OK; |
344 | } | 362 | } |
345 | 363 | ||
@@ -561,6 +579,55 @@ static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa) | |||
561 | return err; | 579 | return err; |
562 | } | 580 | } |
563 | 581 | ||
582 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
583 | static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, | ||
584 | struct scatterlist *sgl, unsigned int sgc) | ||
585 | { | ||
586 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | ||
587 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
588 | int rc = 0; | ||
589 | |||
590 | if (ops->ndo_fcoe_ddp_setup) | ||
591 | rc = ops->ndo_fcoe_ddp_setup(real_dev, xid, sgl, sgc); | ||
592 | |||
593 | return rc; | ||
594 | } | ||
595 | |||
596 | static int vlan_dev_fcoe_ddp_done(struct net_device *dev, u16 xid) | ||
597 | { | ||
598 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | ||
599 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
600 | int len = 0; | ||
601 | |||
602 | if (ops->ndo_fcoe_ddp_done) | ||
603 | len = ops->ndo_fcoe_ddp_done(real_dev, xid); | ||
604 | |||
605 | return len; | ||
606 | } | ||
607 | |||
608 | static int vlan_dev_fcoe_enable(struct net_device *dev) | ||
609 | { | ||
610 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | ||
611 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
612 | int rc = -EINVAL; | ||
613 | |||
614 | if (ops->ndo_fcoe_enable) | ||
615 | rc = ops->ndo_fcoe_enable(real_dev); | ||
616 | return rc; | ||
617 | } | ||
618 | |||
619 | static int vlan_dev_fcoe_disable(struct net_device *dev) | ||
620 | { | ||
621 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | ||
622 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
623 | int rc = -EINVAL; | ||
624 | |||
625 | if (ops->ndo_fcoe_disable) | ||
626 | rc = ops->ndo_fcoe_disable(real_dev); | ||
627 | return rc; | ||
628 | } | ||
629 | #endif | ||
630 | |||
564 | static void vlan_dev_change_rx_flags(struct net_device *dev, int change) | 631 | static void vlan_dev_change_rx_flags(struct net_device *dev, int change) |
565 | { | 632 | { |
566 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | 633 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
@@ -635,6 +702,10 @@ static int vlan_dev_init(struct net_device *dev) | |||
635 | if (is_zero_ether_addr(dev->broadcast)) | 702 | if (is_zero_ether_addr(dev->broadcast)) |
636 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); | 703 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); |
637 | 704 | ||
705 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
706 | dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid; | ||
707 | #endif | ||
708 | |||
638 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | 709 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { |
639 | dev->header_ops = real_dev->header_ops; | 710 | dev->header_ops = real_dev->header_ops; |
640 | dev->hard_header_len = real_dev->hard_header_len; | 711 | dev->hard_header_len = real_dev->hard_header_len; |
@@ -715,6 +786,12 @@ static const struct net_device_ops vlan_netdev_ops = { | |||
715 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | 786 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, |
716 | .ndo_do_ioctl = vlan_dev_ioctl, | 787 | .ndo_do_ioctl = vlan_dev_ioctl, |
717 | .ndo_neigh_setup = vlan_dev_neigh_setup, | 788 | .ndo_neigh_setup = vlan_dev_neigh_setup, |
789 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
790 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | ||
791 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | ||
792 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | ||
793 | .ndo_fcoe_disable = vlan_dev_fcoe_disable, | ||
794 | #endif | ||
718 | }; | 795 | }; |
719 | 796 | ||
720 | static const struct net_device_ops vlan_netdev_accel_ops = { | 797 | static const struct net_device_ops vlan_netdev_accel_ops = { |
@@ -731,6 +808,12 @@ static const struct net_device_ops vlan_netdev_accel_ops = { | |||
731 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | 808 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, |
732 | .ndo_do_ioctl = vlan_dev_ioctl, | 809 | .ndo_do_ioctl = vlan_dev_ioctl, |
733 | .ndo_neigh_setup = vlan_dev_neigh_setup, | 810 | .ndo_neigh_setup = vlan_dev_neigh_setup, |
811 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
812 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | ||
813 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | ||
814 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | ||
815 | .ndo_fcoe_disable = vlan_dev_fcoe_disable, | ||
816 | #endif | ||
734 | }; | 817 | }; |
735 | 818 | ||
736 | void vlan_setup(struct net_device *dev) | 819 | void vlan_setup(struct net_device *dev) |