aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-05-02 22:50:50 -0400
committerRusty Russell <rusty@rustcorp.com.au>2008-05-02 07:50:50 -0400
commitc45a6816c19dee67b8f725e6646d428901a6dc24 (patch)
tree096e3263fd14e140685bcc3082394ff15f5aeddb /drivers/net/virtio_net.c
parent72e61eb40b55dd57031ec5971e810649f82b0259 (diff)
virtio: explicit advertisement of driver features
A recent proposed feature addition to the virtio block driver revealed some flaws in the API: in particular, we assume that feature negotiation is complete once a driver's probe function returns. There is nothing in the API to require this, however, and even I didn't notice when it was violated. So instead, we require the driver to specify what features it supports in a table, we can then move the feature negotiation into the virtio core. The intersection of device and driver features are presented in a new 'features' bitmap in the struct virtio_device. Note that this highlights the difference between Linux unsigned-long bitmaps where each unsigned long is in native endian, and a straight-forward little-endian array of bytes. Drivers can still remove feature bits in their probe routine if they really have to. API changes: - dev->config->feature() no longer gets and acks a feature. - drivers should advertise their features in the 'feature_table' field - use virtio_has_feature() for extra sanity when checking feature bits Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ad43421ab6f1..f926b5ab3d09 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -378,26 +378,26 @@ static int virtnet_probe(struct virtio_device *vdev)
378 SET_NETDEV_DEV(dev, &vdev->dev); 378 SET_NETDEV_DEV(dev, &vdev->dev);
379 379
380 /* Do we support "hardware" checksums? */ 380 /* Do we support "hardware" checksums? */
381 if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { 381 if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
382 /* This opens up the world of extra features. */ 382 /* This opens up the world of extra features. */
383 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; 383 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
384 if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { 384 if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
385 dev->features |= NETIF_F_TSO | NETIF_F_UFO 385 dev->features |= NETIF_F_TSO | NETIF_F_UFO
386 | NETIF_F_TSO_ECN | NETIF_F_TSO6; 386 | NETIF_F_TSO_ECN | NETIF_F_TSO6;
387 } 387 }
388 /* Individual feature bits: what can host handle? */ 388 /* Individual feature bits: what can host handle? */
389 if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_HOST_TSO4)) 389 if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4))
390 dev->features |= NETIF_F_TSO; 390 dev->features |= NETIF_F_TSO;
391 if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_HOST_TSO6)) 391 if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6))
392 dev->features |= NETIF_F_TSO6; 392 dev->features |= NETIF_F_TSO6;
393 if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_HOST_ECN)) 393 if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
394 dev->features |= NETIF_F_TSO_ECN; 394 dev->features |= NETIF_F_TSO_ECN;
395 if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_HOST_UFO)) 395 if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
396 dev->features |= NETIF_F_UFO; 396 dev->features |= NETIF_F_UFO;
397 } 397 }
398 398
399 /* Configuration may specify what MAC to use. Otherwise random. */ 399 /* Configuration may specify what MAC to use. Otherwise random. */
400 if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { 400 if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
401 vdev->config->get(vdev, 401 vdev->config->get(vdev,
402 offsetof(struct virtio_net_config, mac), 402 offsetof(struct virtio_net_config, mac),
403 dev->dev_addr, dev->addr_len); 403 dev->dev_addr, dev->addr_len);
@@ -486,7 +486,15 @@ static struct virtio_device_id id_table[] = {
486 { 0 }, 486 { 0 },
487}; 487};
488 488
489static unsigned int features[] = {
490 VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
491 VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
492 VIRTIO_NET_F_HOST_ECN,
493};
494
489static struct virtio_driver virtio_net = { 495static struct virtio_driver virtio_net = {
496 .feature_table = features,
497 .feature_table_size = ARRAY_SIZE(features),
490 .driver.name = KBUILD_MODNAME, 498 .driver.name = KBUILD_MODNAME,
491 .driver.owner = THIS_MODULE, 499 .driver.owner = THIS_MODULE,
492 .id_table = id_table, 500 .id_table = id_table,