Skip to content

Commit

Permalink
virtio-net: introduce a new control to set macaddr
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Amos Kong authored and David S. Miller committed Jan 21, 2013
1 parent fa0879e commit 7e58d5a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
21 changes: 18 additions & 3 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,14 +802,28 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
struct virtnet_info *vi = netdev_priv(dev);
struct virtio_device *vdev = vi->vdev;
int ret;
struct sockaddr *addr = p;
struct scatterlist sg;

ret = eth_mac_addr(dev, p);
ret = eth_prepare_mac_addr_change(dev, p);
if (ret)
return ret;

if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
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, 1, 0)) {
dev_warn(&vdev->dev,
"Failed to set mac address by vq command.\n");
return -EINVAL;
}
} else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
dev->dev_addr, dev->addr_len);
addr->sa_data, dev->addr_len);
}

eth_commit_mac_addr_change(dev, p);

return 0;
}
Expand Down Expand Up @@ -1627,6 +1641,7 @@ static unsigned int features[] = {
VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
VIRTIO_NET_F_CTRL_MAC_ADDR,
};

static struct virtio_driver virtio_net_driver = {
Expand Down
8 changes: 7 additions & 1 deletion include/uapi/linux/virtio_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
* network */
#define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
* Steering */
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */

#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */
#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */
Expand Down Expand Up @@ -127,7 +128,7 @@ typedef __u8 virtio_net_ctrl_ack;
#define VIRTIO_NET_CTRL_RX_NOBCAST 5

/*
* Control the MAC filter table.
* Control the MAC
*
* The MAC filter table is managed by the hypervisor, the guest should
* assume the size is infinite. Filtering should be considered
Expand All @@ -140,6 +141,10 @@ typedef __u8 virtio_net_ctrl_ack;
* first sg list contains unicast addresses, the second is for multicast.
* This functionality is present if the VIRTIO_NET_F_CTRL_RX feature
* is available.
*
* The ADDR_SET command requests one out scatterlist, it contains a
* 6 bytes MAC address. This functionality is present if the
* VIRTIO_NET_F_CTRL_MAC_ADDR feature is available.
*/
struct virtio_net_ctrl_mac {
__u32 entries;
Expand All @@ -148,6 +153,7 @@ struct virtio_net_ctrl_mac {

#define VIRTIO_NET_CTRL_MAC 1
#define VIRTIO_NET_CTRL_MAC_TABLE_SET 0
#define VIRTIO_NET_CTRL_MAC_ADDR_SET 1

/*
* Control VLAN filtering
Expand Down

0 comments on commit 7e58d5a

Please sign in to comment.