virtio-net: Support for setting MAC addresses of the virtio-net interfaces.
Refers to https://docs.oasis-open.org/virtio/virtio/v1.2/cs01/virtio-v1.2-cs01.html#x1-2230004 A driver SHOULD negotiate VIRTIO_NET_F_MAC if the device offers it. If the driver negotiates the VIRTIO_NET_F_MAC feature, the driver MUST set the physical address of the NIC to mac. Otherwise, it SHOULD use a locally-administered MAC address. Signed-off-by: liqinhui <liqinhui@xiaomi.com>
This commit is contained in:
parent
681b84b15d
commit
73ceb049af
@ -39,6 +39,8 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define VIRTIO_NET_F_MAC 5
|
||||
|
||||
/* Virtio net header size and packet buffer size */
|
||||
|
||||
#define VIRTIO_NET_HDRSIZE (sizeof(struct virtio_net_hdr_s))
|
||||
@ -74,6 +76,24 @@ begin_packed_struct struct virtio_net_hdr_s
|
||||
uint16_t csum_offset;
|
||||
} end_packed_struct;
|
||||
|
||||
/* The definition of the struct virtio_net_config refers to the link
|
||||
* https://docs.oasis-open.org/virtio/virtio/v1.2/cs01/
|
||||
* virtio-v1.2-cs01.html#x1-2230004.
|
||||
*/
|
||||
|
||||
begin_packed_struct struct virtio_net_config_s
|
||||
{
|
||||
uint8_t mac[IFHWADDRLEN]; /* VIRTIO_NET_F_MAC */
|
||||
uint16_t status; /* VIRTIO_NET_F_STATUS */
|
||||
uint16_t max_virtqueue_pairs; /* VIRTIO_NET_F_MQ */
|
||||
uint16_t mtu; /* VIRTIO_NET_F_MTU */
|
||||
uint32_t speed; /* VIRTIO_NET_F_SPEED_DUPLEX */
|
||||
uint8_t duplex;
|
||||
uint8_t rss_max_key_size; /* VIRTIO_NET_F_RSS */
|
||||
uint16_t rss_max_indirection_table_length;
|
||||
uint32_t supported_hash_types;
|
||||
} end_packed_struct;
|
||||
|
||||
struct virtio_net_priv_s
|
||||
{
|
||||
/* This holds the information visible to the NuttX network */
|
||||
@ -487,7 +507,7 @@ static int virtio_net_init(FAR struct virtio_net_priv_s *priv,
|
||||
/* Initialize the virtio device */
|
||||
|
||||
virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_DRIVER);
|
||||
virtio_set_features(vdev, 0);
|
||||
virtio_negotiate_features(vdev, 1 << VIRTIO_NET_F_MAC);
|
||||
virtio_set_status(vdev, VIRTIO_CONFIG_FEATURES_OK);
|
||||
|
||||
vqnames[VIRTIO_NET_RX] = "virtio_net_rx";
|
||||
@ -520,6 +540,42 @@ static int virtio_net_init(FAR struct virtio_net_priv_s *priv,
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void virtio_net_set_macaddr(FAR struct virtio_net_priv_s *priv)
|
||||
{
|
||||
FAR struct net_driver_s *dev = &priv->lower.netdev;
|
||||
FAR struct virtio_device *vdev = priv->vdev;
|
||||
FAR uint8_t *mac = dev->d_mac.ether.ether_addr_octet;
|
||||
|
||||
if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
|
||||
{
|
||||
virtio_read_config(vdev, offsetof(struct virtio_net_config_s, mac),
|
||||
mac, IFHWADDRLEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assign a random locally-created MAC address.
|
||||
*
|
||||
* TODO: The generated MAC address should be checked to see if it
|
||||
* conflicts with something else on the network.
|
||||
*/
|
||||
|
||||
srand(time(NULL) +
|
||||
#ifdef CONFIG_NETDEV_IFINDEX
|
||||
dev->d_ifindex
|
||||
#else
|
||||
dev % 256
|
||||
#endif
|
||||
);
|
||||
|
||||
mac[0] = 0x42;
|
||||
mac[1] = rand() % 256;
|
||||
mac[2] = rand() % 256;
|
||||
mac[3] = rand() % 256;
|
||||
mac[4] = rand() % 256;
|
||||
mac[5] = rand() % 256;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_net_probe
|
||||
****************************************************************************/
|
||||
@ -560,6 +616,8 @@ static int virtio_net_probe(FAR struct virtio_device *vdev)
|
||||
goto err_with_virtqueues;
|
||||
}
|
||||
|
||||
virtio_net_set_macaddr(priv);
|
||||
|
||||
return ret;
|
||||
|
||||
err_with_virtqueues:
|
||||
|
Loading…
Reference in New Issue
Block a user