diff --git a/virtio_net.c b/virtio_net.c index b0577dd..6516934 100644 --- a/virtio_net.c +++ b/virtio_net.c @@ -64,6 +64,10 @@ struct virtnet_info struct page *pages; }; +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) +#include +#endif + struct skb_vnet_hdr { union { struct virtio_net_hdr hdr; @@ -121,6 +125,10 @@ static void skb_xmit_done(struct virtqueue *svq) /* Suppress further interrupts. */ svq->vq_ops->disable_cb(svq); +#ifdef DEV_NETMAP + if (netmap_tx_irq(vi->dev, 0)) + return; +#endif /* We were probably waiting for more output buffers. */ netif_wake_queue(vi->dev); } @@ -470,7 +478,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget) struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi); void *buf; unsigned int len, received = 0; +#ifdef DEV_NETMAP + int work_done = 0; + if (netmap_rx_irq(vi->dev, 0, &work_done)) { + napi_complete(napi); + ND("called netmap_rx_irq"); + + return 1; + } +#endif again: while (received < budget && (buf = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) { @@ -638,6 +655,10 @@ static int virtnet_open(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); +#ifdef DEV_NETMAP + virtio_netmap_init_buffers(vi); + netmap_enable_all_rings(dev); +#endif napi_enable(&vi->napi); /* If all buffers were filled by other side before we napi_enabled, we @@ -700,6 +721,9 @@ static int virtnet_close(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); +#ifdef DEV_NETMAP + netmap_disable_all_rings(dev); +#endif napi_disable(&vi->napi); return 0; @@ -985,6 +1009,10 @@ static int virtnet_probe(struct virtio_device *vdev) goto unregister; } +#ifdef DEV_NETMAP + virtio_netmap_attach(vi); +#endif + vi->status = VIRTIO_NET_S_LINK_UP; virtnet_update_status(vi); netif_carrier_on(dev); @@ -1028,6 +1056,9 @@ static void __devexit virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv; +#ifdef DEV_NETMAP + netmap_detach(vi->dev); +#endif /* Stop all the virtqueues. */ vdev->config->reset(vdev);