aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorAmos Kong <akong@redhat.com>2013-01-20 20:17:23 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-21 14:07:44 -0500
commit7e58d5aea8abb993983a3f3088fd4a3f06180a1c (patch)
tree26b31fbcf0995c22b073394946717eba0151fbe5 /drivers/net/virtio_net.c
parentfa0879e37b59e8e3f130a30a9e6fa515717c5bdd (diff)
virtio-net: introduce a new control to set macaddr
Currently we write MAC address to pci config space byte by byte, this means that we have an intermediate step where mac is wrong. This patch introduced a new control command to set MAC address, it's atomic. VIRTIO_NET_F_CTRL_MAC_ADDR is a new feature bit for compatibility. Signed-off-by: Amos Kong <akong@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 395ab4ff3e64..701408a1ded6 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -802,14 +802,28 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
802 struct virtnet_info *vi = netdev_priv(dev); 802 struct virtnet_info *vi = netdev_priv(dev);
803 struct virtio_device *vdev = vi->vdev; 803 struct virtio_device *vdev = vi->vdev;
804 int ret; 804 int ret;
805 struct sockaddr *addr = p;
806 struct scatterlist sg;
805 807
806 ret = eth_mac_addr(dev, p); 808 ret = eth_prepare_mac_addr_change(dev, p);
807 if (ret) 809 if (ret)
808 return ret; 810 return ret;
809 811
810 if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) 812 if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
813 sg_init_one(&sg, addr->sa_data, dev->addr_len);
814 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
815 VIRTIO_NET_CTRL_MAC_ADDR_SET,
816 &sg, 1, 0)) {
817 dev_warn(&vdev->dev,
818 "Failed to set mac address by vq command.\n");
819 return -EINVAL;
820 }
821 } else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
811 vdev->config->set(vdev, offsetof(struct virtio_net_config, mac), 822 vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
812 dev->dev_addr, dev->addr_len); 823 addr->sa_data, dev->addr_len);
824 }
825
826 eth_commit_mac_addr_change(dev, p);
813 827
814 return 0; 828 return 0;
815} 829}
@@ -1627,6 +1641,7 @@ static unsigned int features[] = {
1627 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, 1641 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
1628 VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, 1642 VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
1629 VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, 1643 VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
1644 VIRTIO_NET_F_CTRL_MAC_ADDR,
1630}; 1645};
1631 1646
1632static struct virtio_driver virtio_net_driver = { 1647static struct virtio_driver virtio_net_driver = {