diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/virtio_net.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 103 |
1 files changed, 46 insertions, 57 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4598e9d2608f..f6853247a620 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -446,6 +446,20 @@ static void skb_recv_done(struct virtqueue *rvq) | |||
446 | } | 446 | } |
447 | } | 447 | } |
448 | 448 | ||
449 | static void virtnet_napi_enable(struct virtnet_info *vi) | ||
450 | { | ||
451 | napi_enable(&vi->napi); | ||
452 | |||
453 | /* If all buffers were filled by other side before we napi_enabled, we | ||
454 | * won't get another interrupt, so process any outstanding packets | ||
455 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
456 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
457 | if (napi_schedule_prep(&vi->napi)) { | ||
458 | virtqueue_disable_cb(vi->rvq); | ||
459 | __napi_schedule(&vi->napi); | ||
460 | } | ||
461 | } | ||
462 | |||
449 | static void refill_work(struct work_struct *work) | 463 | static void refill_work(struct work_struct *work) |
450 | { | 464 | { |
451 | struct virtnet_info *vi; | 465 | struct virtnet_info *vi; |
@@ -454,7 +468,7 @@ static void refill_work(struct work_struct *work) | |||
454 | vi = container_of(work, struct virtnet_info, refill.work); | 468 | vi = container_of(work, struct virtnet_info, refill.work); |
455 | napi_disable(&vi->napi); | 469 | napi_disable(&vi->napi); |
456 | still_empty = !try_fill_recv(vi, GFP_KERNEL); | 470 | still_empty = !try_fill_recv(vi, GFP_KERNEL); |
457 | napi_enable(&vi->napi); | 471 | virtnet_napi_enable(vi); |
458 | 472 | ||
459 | /* In theory, this can happen: if we don't get any buffers in | 473 | /* In theory, this can happen: if we don't get any buffers in |
460 | * we will *never* try to fill again. */ | 474 | * we will *never* try to fill again. */ |
@@ -519,7 +533,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | |||
519 | 533 | ||
520 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 534 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
521 | hdr->hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; | 535 | hdr->hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; |
522 | hdr->hdr.csum_start = skb->csum_start - skb_headroom(skb); | 536 | hdr->hdr.csum_start = skb_checksum_start_offset(skb); |
523 | hdr->hdr.csum_offset = skb->csum_offset; | 537 | hdr->hdr.csum_offset = skb->csum_offset; |
524 | } else { | 538 | } else { |
525 | hdr->hdr.flags = 0; | 539 | hdr->hdr.flags = 0; |
@@ -595,7 +609,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
595 | * before it gets out of hand. Naturally, this wastes entries. */ | 609 | * before it gets out of hand. Naturally, this wastes entries. */ |
596 | if (capacity < 2+MAX_SKB_FRAGS) { | 610 | if (capacity < 2+MAX_SKB_FRAGS) { |
597 | netif_stop_queue(dev); | 611 | netif_stop_queue(dev); |
598 | if (unlikely(!virtqueue_enable_cb(vi->svq))) { | 612 | if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) { |
599 | /* More just got used, free them then recheck. */ | 613 | /* More just got used, free them then recheck. */ |
600 | capacity += free_old_xmit_skbs(vi); | 614 | capacity += free_old_xmit_skbs(vi); |
601 | if (capacity >= 2+MAX_SKB_FRAGS) { | 615 | if (capacity >= 2+MAX_SKB_FRAGS) { |
@@ -638,16 +652,7 @@ static int virtnet_open(struct net_device *dev) | |||
638 | { | 652 | { |
639 | struct virtnet_info *vi = netdev_priv(dev); | 653 | struct virtnet_info *vi = netdev_priv(dev); |
640 | 654 | ||
641 | napi_enable(&vi->napi); | 655 | virtnet_napi_enable(vi); |
642 | |||
643 | /* If all buffers were filled by other side before we napi_enabled, we | ||
644 | * won't get another interrupt, so process any outstanding packets | ||
645 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
646 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
647 | if (napi_schedule_prep(&vi->napi)) { | ||
648 | virtqueue_disable_cb(vi->rvq); | ||
649 | __napi_schedule(&vi->napi); | ||
650 | } | ||
651 | return 0; | 656 | return 0; |
652 | } | 657 | } |
653 | 658 | ||
@@ -705,30 +710,6 @@ static int virtnet_close(struct net_device *dev) | |||
705 | return 0; | 710 | return 0; |
706 | } | 711 | } |
707 | 712 | ||
708 | static void virtnet_get_drvinfo(struct net_device *dev, | ||
709 | struct ethtool_drvinfo *drvinfo) | ||
710 | { | ||
711 | struct virtnet_info *vi = netdev_priv(dev); | ||
712 | struct virtio_device *vdev = vi->vdev; | ||
713 | |||
714 | strncpy(drvinfo->driver, KBUILD_MODNAME, ARRAY_SIZE(drvinfo->driver)); | ||
715 | strncpy(drvinfo->version, "N/A", ARRAY_SIZE(drvinfo->version)); | ||
716 | strncpy(drvinfo->fw_version, "N/A", ARRAY_SIZE(drvinfo->fw_version)); | ||
717 | strncpy(drvinfo->bus_info, dev_name(&vdev->dev), | ||
718 | ARRAY_SIZE(drvinfo->bus_info)); | ||
719 | } | ||
720 | |||
721 | static int virtnet_set_tx_csum(struct net_device *dev, u32 data) | ||
722 | { | ||
723 | struct virtnet_info *vi = netdev_priv(dev); | ||
724 | struct virtio_device *vdev = vi->vdev; | ||
725 | |||
726 | if (data && !virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) | ||
727 | return -ENOSYS; | ||
728 | |||
729 | return ethtool_op_set_tx_hw_csum(dev, data); | ||
730 | } | ||
731 | |||
732 | static void virtnet_set_rx_mode(struct net_device *dev) | 713 | static void virtnet_set_rx_mode(struct net_device *dev) |
733 | { | 714 | { |
734 | struct virtnet_info *vi = netdev_priv(dev); | 715 | struct virtnet_info *vi = netdev_priv(dev); |
@@ -830,11 +811,6 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) | |||
830 | } | 811 | } |
831 | 812 | ||
832 | static const struct ethtool_ops virtnet_ethtool_ops = { | 813 | static const struct ethtool_ops virtnet_ethtool_ops = { |
833 | .get_drvinfo = virtnet_get_drvinfo, | ||
834 | .set_tx_csum = virtnet_set_tx_csum, | ||
835 | .set_sg = ethtool_op_set_sg, | ||
836 | .set_tso = ethtool_op_set_tso, | ||
837 | .set_ufo = ethtool_op_set_ufo, | ||
838 | .get_link = ethtool_op_get_link, | 814 | .get_link = ethtool_op_get_link, |
839 | }; | 815 | }; |
840 | 816 | ||
@@ -921,22 +897,29 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
921 | SET_NETDEV_DEV(dev, &vdev->dev); | 897 | SET_NETDEV_DEV(dev, &vdev->dev); |
922 | 898 | ||
923 | /* Do we support "hardware" checksums? */ | 899 | /* Do we support "hardware" checksums? */ |
924 | if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { | 900 | if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { |
925 | /* This opens up the world of extra features. */ | 901 | /* This opens up the world of extra features. */ |
926 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; | 902 | dev->hw_features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; |
927 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { | 903 | if (csum) |
928 | dev->features |= NETIF_F_TSO | NETIF_F_UFO | 904 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; |
905 | |||
906 | if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { | ||
907 | dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO | ||
929 | | NETIF_F_TSO_ECN | NETIF_F_TSO6; | 908 | | NETIF_F_TSO_ECN | NETIF_F_TSO6; |
930 | } | 909 | } |
931 | /* Individual feature bits: what can host handle? */ | 910 | /* Individual feature bits: what can host handle? */ |
932 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) | 911 | if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) |
933 | dev->features |= NETIF_F_TSO; | 912 | dev->hw_features |= NETIF_F_TSO; |
934 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) | 913 | if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) |
935 | dev->features |= NETIF_F_TSO6; | 914 | dev->hw_features |= NETIF_F_TSO6; |
936 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) | 915 | if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) |
937 | dev->features |= NETIF_F_TSO_ECN; | 916 | dev->hw_features |= NETIF_F_TSO_ECN; |
938 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) | 917 | if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) |
939 | dev->features |= NETIF_F_UFO; | 918 | dev->hw_features |= NETIF_F_UFO; |
919 | |||
920 | if (gso) | ||
921 | dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO); | ||
922 | /* (!csum && gso) case will be fixed by register_netdev() */ | ||
940 | } | 923 | } |
941 | 924 | ||
942 | /* Configuration may specify what MAC to use. Otherwise random. */ | 925 | /* Configuration may specify what MAC to use. Otherwise random. */ |
@@ -1000,9 +983,15 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1000 | goto unregister; | 983 | goto unregister; |
1001 | } | 984 | } |
1002 | 985 | ||
1003 | vi->status = VIRTIO_NET_S_LINK_UP; | 986 | /* Assume link up if device can't report link status, |
1004 | virtnet_update_status(vi); | 987 | otherwise get link status from config. */ |
1005 | netif_carrier_on(dev); | 988 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { |
989 | netif_carrier_off(dev); | ||
990 | virtnet_update_status(vi); | ||
991 | } else { | ||
992 | vi->status = VIRTIO_NET_S_LINK_UP; | ||
993 | netif_carrier_on(dev); | ||
994 | } | ||
1006 | 995 | ||
1007 | pr_debug("virtnet: registered device %s\n", dev->name); | 996 | pr_debug("virtnet: registered device %s\n", dev->name); |
1008 | return 0; | 997 | return 0; |