aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-05-03 17:07:43 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-03 17:07:43 -0400
commitd252a5e7b73026b3ba3c49940724292099e634f0 (patch)
treec151797f0daecf457ef7a4bad027ecfdd8d79ad6 /drivers/net/virtio_net.c
parentf0a3a1538d57dfb51c73d012cbb72f985cd419aa (diff)
parent1824a9897473fda5e5e42f991ddc674c175e3a09 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 071855871524..6cc5bcd34fb0 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -616,10 +616,11 @@ static int virtnet_open(struct net_device *dev)
616static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, 616static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
617 struct scatterlist *data, int out, int in) 617 struct scatterlist *data, int out, int in)
618{ 618{
619 struct scatterlist sg[VIRTNET_SEND_COMMAND_SG_MAX + 2]; 619 struct scatterlist *s, sg[VIRTNET_SEND_COMMAND_SG_MAX + 2];
620 struct virtio_net_ctrl_hdr ctrl; 620 struct virtio_net_ctrl_hdr ctrl;
621 virtio_net_ctrl_ack status = ~0; 621 virtio_net_ctrl_ack status = ~0;
622 unsigned int tmp; 622 unsigned int tmp;
623 int i;
623 624
624 /* Caller should know better */ 625 /* Caller should know better */
625 BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) || 626 BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ||
@@ -634,7 +635,8 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
634 sg_init_table(sg, out + in); 635 sg_init_table(sg, out + in);
635 636
636 sg_set_buf(&sg[0], &ctrl, sizeof(ctrl)); 637 sg_set_buf(&sg[0], &ctrl, sizeof(ctrl));
637 memcpy(&sg[1], data, sizeof(struct scatterlist) * (out + in - 2)); 638 for_each_sg(data, s, out + in - 2, i)
639 sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
638 sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); 640 sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
639 641
640 BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi)); 642 BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi));
@@ -688,7 +690,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
688 promisc = ((dev->flags & IFF_PROMISC) != 0); 690 promisc = ((dev->flags & IFF_PROMISC) != 0);
689 allmulti = ((dev->flags & IFF_ALLMULTI) != 0); 691 allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
690 692
691 sg_set_buf(sg, &promisc, sizeof(promisc)); 693 sg_init_one(sg, &promisc, sizeof(promisc));
692 694
693 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, 695 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
694 VIRTIO_NET_CTRL_RX_PROMISC, 696 VIRTIO_NET_CTRL_RX_PROMISC,
@@ -696,7 +698,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
696 dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", 698 dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
697 promisc ? "en" : "dis"); 699 promisc ? "en" : "dis");
698 700
699 sg_set_buf(sg, &allmulti, sizeof(allmulti)); 701 sg_init_one(sg, &allmulti, sizeof(allmulti));
700 702
701 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, 703 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
702 VIRTIO_NET_CTRL_RX_ALLMULTI, 704 VIRTIO_NET_CTRL_RX_ALLMULTI,
@@ -712,6 +714,8 @@ static void virtnet_set_rx_mode(struct net_device *dev)
712 return; 714 return;
713 } 715 }
714 716
717 sg_init_table(sg, 2);
718
715 /* Store the unicast list and count in the front of the buffer */ 719 /* Store the unicast list and count in the front of the buffer */
716 mac_data->entries = dev->uc_count; 720 mac_data->entries = dev->uc_count;
717 addr = dev->uc_list; 721 addr = dev->uc_list;
@@ -740,24 +744,24 @@ static void virtnet_set_rx_mode(struct net_device *dev)
740 kfree(buf); 744 kfree(buf);
741} 745}
742 746
743static void virnet_vlan_rx_add_vid(struct net_device *dev, u16 vid) 747static void virtnet_vlan_rx_add_vid(struct net_device *dev, u16 vid)
744{ 748{
745 struct virtnet_info *vi = netdev_priv(dev); 749 struct virtnet_info *vi = netdev_priv(dev);
746 struct scatterlist sg; 750 struct scatterlist sg;
747 751
748 sg_set_buf(&sg, &vid, sizeof(vid)); 752 sg_init_one(&sg, &vid, sizeof(vid));
749 753
750 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, 754 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
751 VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0)) 755 VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0))
752 dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid); 756 dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid);
753} 757}
754 758
755static void virnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) 759static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
756{ 760{
757 struct virtnet_info *vi = netdev_priv(dev); 761 struct virtnet_info *vi = netdev_priv(dev);
758 struct scatterlist sg; 762 struct scatterlist sg;
759 763
760 sg_set_buf(&sg, &vid, sizeof(vid)); 764 sg_init_one(&sg, &vid, sizeof(vid));
761 765
762 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, 766 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
763 VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0)) 767 VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0))
@@ -790,8 +794,8 @@ static const struct net_device_ops virtnet_netdev = {
790 .ndo_set_mac_address = virtnet_set_mac_address, 794 .ndo_set_mac_address = virtnet_set_mac_address,
791 .ndo_set_rx_mode = virtnet_set_rx_mode, 795 .ndo_set_rx_mode = virtnet_set_rx_mode,
792 .ndo_change_mtu = virtnet_change_mtu, 796 .ndo_change_mtu = virtnet_change_mtu,
793 .ndo_vlan_rx_add_vid = virnet_vlan_rx_add_vid, 797 .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
794 .ndo_vlan_rx_kill_vid = virnet_vlan_rx_kill_vid, 798 .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
795#ifdef CONFIG_NET_POLL_CONTROLLER 799#ifdef CONFIG_NET_POLL_CONTROLLER
796 .ndo_poll_controller = virtnet_netpoll, 800 .ndo_poll_controller = virtnet_netpoll,
797#endif 801#endif