92 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			92 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | diff --git a/virtio_net.c b/virtio_net.c | ||
|  | index 3d2a90a..ae899a4 100644 | ||
|  | --- a/virtio_net.c | ||
|  | +++ b/virtio_net.c | ||
|  | @@ -131,6 +131,10 @@ struct virtnet_info { | ||
|  |  	struct notifier_block nb; | ||
|  |  }; | ||
|  |   | ||
|  | +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) | ||
|  | +#include <virtio_netmap.h> | ||
|  | +#endif | ||
|  | + | ||
|  |  struct skb_vnet_hdr { | ||
|  |  	union { | ||
|  |  		struct virtio_net_hdr hdr; | ||
|  | @@ -210,6 +214,10 @@ static void skb_xmit_done(struct virtqueue *vq) | ||
|  |  	/* Suppress further interrupts. */ | ||
|  |  	virtqueue_disable_cb(vq); | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +        if (netmap_tx_irq(vi->dev, vq2txq(vq))) | ||
|  | +		return; | ||
|  | +#endif | ||
|  |  	/* We were probably waiting for more output buffers. */ | ||
|  |  	netif_wake_subqueue(vi->dev, vq2txq(vq)); | ||
|  |  } | ||
|  | @@ -603,7 +611,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget) | ||
|  |  	struct virtnet_info *vi = rq->vq->vdev->priv; | ||
|  |  	void *buf; | ||
|  |  	unsigned int r, len, received = 0; | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +        int work_done = 0; | ||
|  |   | ||
|  | +        if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) { | ||
|  | +		napi_complete(napi); | ||
|  | +		ND("called netmap_rx_irq"); | ||
|  | + | ||
|  | +                return 1; | ||
|  | +        } | ||
|  | +#endif | ||
|  |  again: | ||
|  |  	while (received < budget && | ||
|  |  	       (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { | ||
|  | @@ -636,6 +653,16 @@ static int virtnet_open(struct net_device *dev) | ||
|  |  { | ||
|  |  	struct virtnet_info *vi = netdev_priv(dev); | ||
|  |  	int i; | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +        int ok = virtio_netmap_init_buffers(vi); | ||
|  | + | ||
|  | +        netmap_enable_all_rings(dev); | ||
|  | +        if (ok) { | ||
|  | +            for (i = 0; i < vi->max_queue_pairs; i++) | ||
|  | +		virtnet_napi_enable(&vi->rq[i]); | ||
|  | +            return 0; | ||
|  | +        } | ||
|  | +#endif | ||
|  |   | ||
|  |  	for (i = 0; i < vi->max_queue_pairs; i++) { | ||
|  |  		if (i < vi->curr_queue_pairs) | ||
|  | @@ -927,6 +954,9 @@ static int virtnet_close(struct net_device *dev) | ||
|  |  	struct virtnet_info *vi = netdev_priv(dev); | ||
|  |  	int i; | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +        netmap_disable_all_rings(dev); | ||
|  | +#endif | ||
|  |  	/* Make sure refill_work doesn't re-enable napi! */ | ||
|  |  	cancel_delayed_work_sync(&vi->refill); | ||
|  |   | ||
|  | @@ -1592,6 +1622,10 @@ static int virtnet_probe(struct virtio_device *vdev) | ||
|  |  		goto free_recv_bufs; | ||
|  |  	} | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +        virtio_netmap_attach(vi); | ||
|  | +#endif | ||
|  | + | ||
|  |  	/* Assume link up if device can't report link status, | ||
|  |  	   otherwise get link status from config. */ | ||
|  |  	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { | ||
|  | @@ -1638,6 +1672,9 @@ static void virtnet_remove(struct virtio_device *vdev) | ||
|  |  { | ||
|  |  	struct virtnet_info *vi = vdev->priv; | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +        netmap_detach(vi->dev); | ||
|  | +#endif | ||
|  |  	unregister_hotcpu_notifier(&vi->nb); | ||
|  |   | ||
|  |  	/* Prevent config work handler from accessing the device. */ |