xref: /freebsd/sys/dev/virtio/virtqueue.h (revision ccb576a83cc959070de59454d4dcd6395f7ae91a)
110b59a9bSPeter Grehan /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
4abd6790cSBryan Venteicher  * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
510b59a9bSPeter Grehan  * All rights reserved.
610b59a9bSPeter Grehan  *
710b59a9bSPeter Grehan  * Redistribution and use in source and binary forms, with or without
810b59a9bSPeter Grehan  * modification, are permitted provided that the following conditions
910b59a9bSPeter Grehan  * are met:
1010b59a9bSPeter Grehan  * 1. Redistributions of source code must retain the above copyright
1110b59a9bSPeter Grehan  *    notice unmodified, this list of conditions, and the following
1210b59a9bSPeter Grehan  *    disclaimer.
1310b59a9bSPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
1410b59a9bSPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
1510b59a9bSPeter Grehan  *    documentation and/or other materials provided with the distribution.
1610b59a9bSPeter Grehan  *
1710b59a9bSPeter Grehan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1810b59a9bSPeter Grehan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1910b59a9bSPeter Grehan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2010b59a9bSPeter Grehan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2110b59a9bSPeter Grehan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2210b59a9bSPeter Grehan  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310b59a9bSPeter Grehan  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2410b59a9bSPeter Grehan  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2510b59a9bSPeter Grehan  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2610b59a9bSPeter Grehan  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710b59a9bSPeter Grehan  */
2810b59a9bSPeter Grehan 
2910b59a9bSPeter Grehan #ifndef _VIRTIO_VIRTQUEUE_H
3010b59a9bSPeter Grehan #define _VIRTIO_VIRTQUEUE_H
3110b59a9bSPeter Grehan 
3210b59a9bSPeter Grehan struct virtqueue;
3310b59a9bSPeter Grehan struct sglist;
3410b59a9bSPeter Grehan 
3510b59a9bSPeter Grehan /* Device callback for a virtqueue interrupt. */
366632efe4SBryan Venteicher typedef void virtqueue_intr_t(void *);
3710b59a9bSPeter Grehan 
38b619f40aSBryan Venteicher /*
39b619f40aSBryan Venteicher  * Hint on how long the next interrupt should be postponed. This is
40b619f40aSBryan Venteicher  * only used when the EVENT_IDX feature is negotiated.
41b619f40aSBryan Venteicher  */
42b619f40aSBryan Venteicher typedef enum {
43b619f40aSBryan Venteicher 	VQ_POSTPONE_SHORT,
44b619f40aSBryan Venteicher 	VQ_POSTPONE_LONG,
45b619f40aSBryan Venteicher 	VQ_POSTPONE_EMPTIED	/* Until all available desc are used. */
46b619f40aSBryan Venteicher } vq_postpone_t;
47b619f40aSBryan Venteicher 
4810b59a9bSPeter Grehan #define VIRTQUEUE_MAX_NAME_SZ	32
4910b59a9bSPeter Grehan 
5010b59a9bSPeter Grehan /* One for each virtqueue the device wishes to allocate. */
5110b59a9bSPeter Grehan struct vq_alloc_info {
5210b59a9bSPeter Grehan 	char		   vqai_name[VIRTQUEUE_MAX_NAME_SZ];
5310b59a9bSPeter Grehan 	int		   vqai_maxindirsz;
5410b59a9bSPeter Grehan 	virtqueue_intr_t  *vqai_intr;
5510b59a9bSPeter Grehan 	void		  *vqai_intr_arg;
5610b59a9bSPeter Grehan 	struct virtqueue **vqai_vq;
5710b59a9bSPeter Grehan };
5810b59a9bSPeter Grehan 
5910b59a9bSPeter Grehan #define VQ_ALLOC_INFO_INIT(_i,_nsegs,_intr,_arg,_vqp,_str,...) do {	\
6010b59a9bSPeter Grehan 	snprintf((_i)->vqai_name, VIRTQUEUE_MAX_NAME_SZ, _str,		\
6110b59a9bSPeter Grehan 	    ##__VA_ARGS__);						\
6210b59a9bSPeter Grehan 	(_i)->vqai_maxindirsz = (_nsegs);				\
6310b59a9bSPeter Grehan 	(_i)->vqai_intr = (_intr);					\
6410b59a9bSPeter Grehan 	(_i)->vqai_intr_arg = (_arg);					\
6510b59a9bSPeter Grehan 	(_i)->vqai_vq = (_vqp);						\
6610b59a9bSPeter Grehan } while (0)
6710b59a9bSPeter Grehan 
6810b59a9bSPeter Grehan int	 virtqueue_alloc(device_t dev, uint16_t queue, uint16_t size,
699da9560cSBryan Venteicher 	     bus_size_t notify_offset, int align, vm_paddr_t highaddr,
709da9560cSBryan Venteicher 	     struct vq_alloc_info *info, struct virtqueue **vqp);
7110b59a9bSPeter Grehan void	*virtqueue_drain(struct virtqueue *vq, int *last);
7210b59a9bSPeter Grehan void	 virtqueue_free(struct virtqueue *vq);
7310b59a9bSPeter Grehan int	 virtqueue_reinit(struct virtqueue *vq, uint16_t size);
7410b59a9bSPeter Grehan 
756632efe4SBryan Venteicher int	 virtqueue_intr_filter(struct virtqueue *vq);
766632efe4SBryan Venteicher void	 virtqueue_intr(struct virtqueue *vq);
7710b59a9bSPeter Grehan int	 virtqueue_enable_intr(struct virtqueue *vq);
78b619f40aSBryan Venteicher int	 virtqueue_postpone_intr(struct virtqueue *vq, vq_postpone_t hint);
7910b59a9bSPeter Grehan void	 virtqueue_disable_intr(struct virtqueue *vq);
8010b59a9bSPeter Grehan 
8110b59a9bSPeter Grehan /* Get physical address of the virtqueue ring. */
8210b59a9bSPeter Grehan vm_paddr_t virtqueue_paddr(struct virtqueue *vq);
8388126356SBryan Venteicher vm_paddr_t virtqueue_desc_paddr(struct virtqueue *vq);
8488126356SBryan Venteicher vm_paddr_t virtqueue_avail_paddr(struct virtqueue *vq);
8588126356SBryan Venteicher vm_paddr_t virtqueue_used_paddr(struct virtqueue *vq);
8610b59a9bSPeter Grehan 
8788126356SBryan Venteicher uint16_t virtqueue_index(struct virtqueue *vq);
88*ccb576a8SMina Galić bool	 virtqueue_full(struct virtqueue *vq);
89*ccb576a8SMina Galić bool	 virtqueue_empty(struct virtqueue *vq);
9010b59a9bSPeter Grehan int	 virtqueue_size(struct virtqueue *vq);
914b59668fSBryan Venteicher int	 virtqueue_nfree(struct virtqueue *vq);
9210b59a9bSPeter Grehan int	 virtqueue_nused(struct virtqueue *vq);
9310b59a9bSPeter Grehan void	 virtqueue_notify(struct virtqueue *vq);
9410b59a9bSPeter Grehan void	 virtqueue_dump(struct virtqueue *vq);
9510b59a9bSPeter Grehan 
9610b59a9bSPeter Grehan int	 virtqueue_enqueue(struct virtqueue *vq, void *cookie,
9710b59a9bSPeter Grehan 	     struct sglist *sg, int readable, int writable);
9810b59a9bSPeter Grehan void	*virtqueue_dequeue(struct virtqueue *vq, uint32_t *len);
9910b59a9bSPeter Grehan void	*virtqueue_poll(struct virtqueue *vq, uint32_t *len);
10010b59a9bSPeter Grehan 
10110b59a9bSPeter Grehan #endif /* _VIRTIO_VIRTQUEUE_H */
102