diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ibmveth.c | 44 | ||||
-rw-r--r-- | drivers/net/ibmveth.h | 1 |
2 files changed, 30 insertions, 15 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index aea1598b2253..987bcba01889 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -621,12 +621,18 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
621 | unsigned long lpar_rc; | 621 | unsigned long lpar_rc; |
622 | int nfrags = 0, curfrag; | 622 | int nfrags = 0, curfrag; |
623 | unsigned long correlator; | 623 | unsigned long correlator; |
624 | unsigned long flags; | ||
624 | unsigned int retry_count; | 625 | unsigned int retry_count; |
626 | unsigned int tx_dropped = 0; | ||
627 | unsigned int tx_bytes = 0; | ||
628 | unsigned int tx_packets = 0; | ||
629 | unsigned int tx_send_failed = 0; | ||
630 | unsigned int tx_map_failed = 0; | ||
631 | |||
625 | 632 | ||
626 | if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) { | 633 | if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) { |
627 | adapter->stats.tx_dropped++; | 634 | tx_dropped++; |
628 | dev_kfree_skb(skb); | 635 | goto out; |
629 | return 0; | ||
630 | } | 636 | } |
631 | 637 | ||
632 | memset(&desc, 0, sizeof(desc)); | 638 | memset(&desc, 0, sizeof(desc)); |
@@ -645,10 +651,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
645 | 651 | ||
646 | if(dma_mapping_error(desc[0].fields.address)) { | 652 | if(dma_mapping_error(desc[0].fields.address)) { |
647 | ibmveth_error_printk("tx: unable to map initial fragment\n"); | 653 | ibmveth_error_printk("tx: unable to map initial fragment\n"); |
648 | adapter->tx_map_failed++; | 654 | tx_map_failed++; |
649 | adapter->stats.tx_dropped++; | 655 | tx_dropped++; |
650 | dev_kfree_skb(skb); | 656 | goto out; |
651 | return 0; | ||
652 | } | 657 | } |
653 | 658 | ||
654 | curfrag = nfrags; | 659 | curfrag = nfrags; |
@@ -665,8 +670,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
665 | 670 | ||
666 | if(dma_mapping_error(desc[curfrag+1].fields.address)) { | 671 | if(dma_mapping_error(desc[curfrag+1].fields.address)) { |
667 | ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag); | 672 | ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag); |
668 | adapter->tx_map_failed++; | 673 | tx_map_failed++; |
669 | adapter->stats.tx_dropped++; | 674 | tx_dropped++; |
670 | /* Free all the mappings we just created */ | 675 | /* Free all the mappings we just created */ |
671 | while(curfrag < nfrags) { | 676 | while(curfrag < nfrags) { |
672 | dma_unmap_single(&adapter->vdev->dev, | 677 | dma_unmap_single(&adapter->vdev->dev, |
@@ -675,8 +680,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
675 | DMA_TO_DEVICE); | 680 | DMA_TO_DEVICE); |
676 | curfrag++; | 681 | curfrag++; |
677 | } | 682 | } |
678 | dev_kfree_skb(skb); | 683 | goto out; |
679 | return 0; | ||
680 | } | 684 | } |
681 | } | 685 | } |
682 | 686 | ||
@@ -701,11 +705,11 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
701 | ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i, | 705 | ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i, |
702 | desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address); | 706 | desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address); |
703 | } | 707 | } |
704 | adapter->tx_send_failed++; | 708 | tx_send_failed++; |
705 | adapter->stats.tx_dropped++; | 709 | tx_dropped++; |
706 | } else { | 710 | } else { |
707 | adapter->stats.tx_packets++; | 711 | tx_packets++; |
708 | adapter->stats.tx_bytes += skb->len; | 712 | tx_bytes += skb->len; |
709 | netdev->trans_start = jiffies; | 713 | netdev->trans_start = jiffies; |
710 | } | 714 | } |
711 | 715 | ||
@@ -715,6 +719,14 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
715 | desc[nfrags].fields.length, DMA_TO_DEVICE); | 719 | desc[nfrags].fields.length, DMA_TO_DEVICE); |
716 | } while(--nfrags >= 0); | 720 | } while(--nfrags >= 0); |
717 | 721 | ||
722 | out: spin_lock_irqsave(&adapter->stats_lock, flags); | ||
723 | adapter->stats.tx_dropped += tx_dropped; | ||
724 | adapter->stats.tx_bytes += tx_bytes; | ||
725 | adapter->stats.tx_packets += tx_packets; | ||
726 | adapter->tx_send_failed += tx_send_failed; | ||
727 | adapter->tx_map_failed += tx_map_failed; | ||
728 | spin_unlock_irqrestore(&adapter->stats_lock, flags); | ||
729 | |||
718 | dev_kfree_skb(skb); | 730 | dev_kfree_skb(skb); |
719 | return 0; | 731 | return 0; |
720 | } | 732 | } |
@@ -980,6 +992,8 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ | |||
980 | netdev->ethtool_ops = &netdev_ethtool_ops; | 992 | netdev->ethtool_ops = &netdev_ethtool_ops; |
981 | netdev->change_mtu = ibmveth_change_mtu; | 993 | netdev->change_mtu = ibmveth_change_mtu; |
982 | SET_NETDEV_DEV(netdev, &dev->dev); | 994 | SET_NETDEV_DEV(netdev, &dev->dev); |
995 | netdev->features |= NETIF_F_LLTX; | ||
996 | spin_lock_init(&adapter->stats_lock); | ||
983 | 997 | ||
984 | memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); | 998 | memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); |
985 | 999 | ||
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index a3ea02937d63..46919a814fca 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h | |||
@@ -131,6 +131,7 @@ struct ibmveth_adapter { | |||
131 | u64 tx_linearize_failed; | 131 | u64 tx_linearize_failed; |
132 | u64 tx_map_failed; | 132 | u64 tx_map_failed; |
133 | u64 tx_send_failed; | 133 | u64 tx_send_failed; |
134 | spinlock_t stats_lock; | ||
134 | }; | 135 | }; |
135 | 136 | ||
136 | struct ibmveth_buf_desc_fields { | 137 | struct ibmveth_buf_desc_fields { |