vi->duplex = DUPLEX_UNKNOWN;
 }
 
+static void virtnet_update_settings(struct virtnet_info *vi)
+{
+       u32 speed;
+       u8 duplex;
+
+       if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX))
+               return;
+
+       speed = virtio_cread32(vi->vdev, offsetof(struct virtio_net_config,
+                                                 speed));
+       if (ethtool_validate_speed(speed))
+               vi->speed = speed;
+       duplex = virtio_cread8(vi->vdev, offsetof(struct virtio_net_config,
+                                                 duplex));
+       if (ethtool_validate_duplex(duplex))
+               vi->duplex = duplex;
+}
+
 static const struct ethtool_ops virtnet_ethtool_ops = {
        .get_drvinfo = virtnet_get_drvinfo,
        .get_link = ethtool_op_get_link,
        vi->status = v;
 
        if (vi->status & VIRTIO_NET_S_LINK_UP) {
+               virtnet_update_settings(vi);
                netif_carrier_on(vi->dev);
                netif_tx_wake_all_queues(vi->dev);
        } else {
                schedule_work(&vi->config_work);
        } else {
                vi->status = VIRTIO_NET_S_LINK_UP;
+               virtnet_update_settings(vi);
                netif_carrier_on(dev);
        }
 
        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, \
-       VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
+       VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
+       VIRTIO_NET_F_SPEED_DUPLEX
 
 static unsigned int features[] = {
        VIRTNET_FEATURES,
 
                                         * Steering */
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23  /* Set MAC address */
 
+#define VIRTIO_NET_F_SPEED_DUPLEX 63   /* Device set linkspeed and duplex */
+
 #ifndef VIRTIO_NET_NO_LEGACY
 #define VIRTIO_NET_F_GSO       6       /* Host handles pkts w/ any GSO type */
 #endif /* VIRTIO_NET_NO_LEGACY */
        __u16 max_virtqueue_pairs;
        /* Default maximum transmit unit advice */
        __u16 mtu;
+       /*
+        * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+        * Any other value stands for unknown.
+        */
+       __u32 speed;
+       /*
+        * 0x00 - half duplex
+        * 0x01 - full duplex
+        * Any other value stands for unknown.
+        */
+       __u8 duplex;
 } __attribute__((packed));
 
 /*