]> Pileus Git - ~andy/linux/blobdiff - drivers/net/virtio_net.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[~andy/linux] / drivers / net / virtio_net.c
index 916241d16c6764c117f80fa7109bdbff7dfdb714..7b172408cff02b72b8c5eb90307b63dec164f8c2 100644 (file)
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 //#define DEBUG
 #include <linux/netdevice.h>
@@ -426,10 +425,10 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
        if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
                pr_debug("%s: short packet %i\n", dev->name, len);
                dev->stats.rx_length_errors++;
-               if (vi->big_packets)
-                       give_pages(rq, buf);
-               else if (vi->mergeable_rx_bufs)
+               if (vi->mergeable_rx_bufs)
                        put_page(virt_to_head_page(buf));
+               else if (vi->big_packets)
+                       give_pages(rq, buf);
                else
                        dev_kfree_skb(buf);
                return;
@@ -874,16 +873,15 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
 /*
  * Send command via the control virtqueue and check status.  Commands
  * supported by the hypervisor, as indicated by feature bits, should
- * never fail unless improperly formated.
+ * never fail unless improperly formatted.
  */
 static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
-                                struct scatterlist *out,
-                                struct scatterlist *in)
+                                struct scatterlist *out)
 {
        struct scatterlist *sgs[4], hdr, stat;
        struct virtio_net_ctrl_hdr ctrl;
        virtio_net_ctrl_ack status = ~0;
-       unsigned out_num = 0, in_num = 0, tmp;
+       unsigned out_num = 0, tmp;
 
        /* Caller should know better */
        BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
@@ -896,16 +894,13 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
 
        if (out)
                sgs[out_num++] = out;
-       if (in)
-               sgs[out_num + in_num++] = in;
 
        /* Add return status. */
        sg_init_one(&stat, &status, sizeof(status));
-       sgs[out_num + in_num++] = &stat;
+       sgs[out_num] = &stat;
 
-       BUG_ON(out_num + in_num > ARRAY_SIZE(sgs));
-       BUG_ON(virtqueue_add_sgs(vi->cvq, sgs, out_num, in_num, vi, GFP_ATOMIC)
-              < 0);
+       BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
+       BUG_ON(virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC) < 0);
 
        if (unlikely(!virtqueue_kick(vi->cvq)))
                return status == VIRTIO_NET_OK;
@@ -935,8 +930,7 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
        if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
                sg_init_one(&sg, addr->sa_data, dev->addr_len);
                if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
-                                         VIRTIO_NET_CTRL_MAC_ADDR_SET,
-                                         &sg, NULL)) {
+                                         VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) {
                        dev_warn(&vdev->dev,
                                 "Failed to set mac address by vq command.\n");
                        return -EINVAL;
@@ -1009,7 +1003,7 @@ static void virtnet_ack_link_announce(struct virtnet_info *vi)
 {
        rtnl_lock();
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_ANNOUNCE,
-                                 VIRTIO_NET_CTRL_ANNOUNCE_ACK, NULL, NULL))
+                                 VIRTIO_NET_CTRL_ANNOUNCE_ACK, NULL))
                dev_warn(&vi->dev->dev, "Failed to ack link announce.\n");
        rtnl_unlock();
 }
@@ -1027,7 +1021,7 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
        sg_init_one(&sg, &s, sizeof(s));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
-                                 VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg, NULL)) {
+                                 VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg)) {
                dev_warn(&dev->dev, "Fail to set num of queue pairs to %d\n",
                         queue_pairs);
                return -EINVAL;
@@ -1067,7 +1061,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
        void *buf;
        int i;
 
-       /* We can't dynamicaly set ndo_set_rx_mode, so return gracefully */
+       /* We can't dynamically set ndo_set_rx_mode, so return gracefully */
        if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
                return;
 
@@ -1077,16 +1071,14 @@ static void virtnet_set_rx_mode(struct net_device *dev)
        sg_init_one(sg, &promisc, sizeof(promisc));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
-                                 VIRTIO_NET_CTRL_RX_PROMISC,
-                                 sg, NULL))
+                                 VIRTIO_NET_CTRL_RX_PROMISC, sg))
                dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
                         promisc ? "en" : "dis");
 
        sg_init_one(sg, &allmulti, sizeof(allmulti));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
-                                 VIRTIO_NET_CTRL_RX_ALLMULTI,
-                                 sg, NULL))
+                                 VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
                dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
                         allmulti ? "en" : "dis");
 
@@ -1122,8 +1114,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
                   sizeof(mac_data->entries) + (mc_count * ETH_ALEN));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
-                                 VIRTIO_NET_CTRL_MAC_TABLE_SET,
-                                 sg, NULL))
+                                 VIRTIO_NET_CTRL_MAC_TABLE_SET, sg))
                dev_warn(&dev->dev, "Failed to set MAC filter table.\n");
 
        kfree(buf);
@@ -1138,7 +1129,7 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev,
        sg_init_one(&sg, &vid, sizeof(vid));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
-                                 VIRTIO_NET_CTRL_VLAN_ADD, &sg, NULL))
+                                 VIRTIO_NET_CTRL_VLAN_ADD, &sg))
                dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid);
        return 0;
 }
@@ -1152,7 +1143,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev,
        sg_init_one(&sg, &vid, sizeof(vid));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
-                                 VIRTIO_NET_CTRL_VLAN_DEL, &sg, NULL))
+                                 VIRTIO_NET_CTRL_VLAN_DEL, &sg))
                dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid);
        return 0;
 }
@@ -1367,6 +1358,11 @@ static void virtnet_config_changed(struct virtio_device *vdev)
 
 static void virtnet_free_queues(struct virtnet_info *vi)
 {
+       int i;
+
+       for (i = 0; i < vi->max_queue_pairs; i++)
+               netif_napi_del(&vi->rq[i].napi);
+
        kfree(vi->rq);
        kfree(vi->sq);
 }
@@ -1396,10 +1392,10 @@ static void free_unused_bufs(struct virtnet_info *vi)
                struct virtqueue *vq = vi->rq[i].vq;
 
                while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
-                       if (vi->big_packets)
-                               give_pages(&vi->rq[i], buf);
-                       else if (vi->mergeable_rx_bufs)
+                       if (vi->mergeable_rx_bufs)
                                put_page(virt_to_head_page(buf));
+                       else if (vi->big_packets)
+                               give_pages(&vi->rq[i], buf);
                        else
                                dev_kfree_skb(buf);
                        --vi->rq[i].num;
@@ -1792,16 +1788,17 @@ static int virtnet_restore(struct virtio_device *vdev)
        if (err)
                return err;
 
-       if (netif_running(vi->dev))
+       if (netif_running(vi->dev)) {
+               for (i = 0; i < vi->curr_queue_pairs; i++)
+                       if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
+                               schedule_delayed_work(&vi->refill, 0);
+
                for (i = 0; i < vi->max_queue_pairs; i++)
                        virtnet_napi_enable(&vi->rq[i]);
+       }
 
        netif_device_attach(vi->dev);
 
-       for (i = 0; i < vi->curr_queue_pairs; i++)
-               if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
-                       schedule_delayed_work(&vi->refill, 0);
-
        mutex_lock(&vi->config_lock);
        vi->config_enable = true;
        mutex_unlock(&vi->config_lock);