blob: e3eee4e26f5b3a54a720df645f9b0fd634e8042b [file] [log] [blame]
#ifndef KERNEL_VNPLUG_H
#define KERNEL_VNPLUG_H
/* Enhanced supports */
#define VNPLUG_CTRL /* enables the control interface over virtio */
#define VNPLUG_MULTI_IRQ /* enables support for multiple interrupts in userspace */
#ifdef __KERNEL__
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/kobject.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <asm/io.h>
#define VNPLUG_DEVICE_NAME "vnplug"
#define PCI_VENDOR_ID_SILICOM 0x1374
#define PCI_DEVICE_ID_VNPLUG_DEV 0x00ff
#define VNPLUG_REG_REGION_SIZE PAGE_SIZE
#else /* __KERNEL__ */
#include <stdint.h> /* uint32_t, etc. */
#define VNPLUG_REG_REGION_SIZE 4096
/* Note: no VNPLUG_X_MM_REGION_SIZE, it is dynamic! */
#endif /* __KERNEL__ */
/*
* Region bar_id=0
* | device id (4) | doorbell (4) | region bar_id=2 size (4) | region bar_id=3 size (4) | ... |
*
* Region bar_id=1
* | MSI-X (4K) |
*
* Region bar_id=2..5
* | mapped memory (2^n) |
*/
#define VNPLUG_REG_OFF_ID 0x00
#define VNPLUG_REG_OFF_DOORBELL 0x04
#define VNPLUG_REG_OFF_BASE_MM_SIZE 0x08
#define VNPLUG_REG_REGION_ID 0
#define VNPLUG_BASE_MM_REGION_ID 1
#ifdef __KERNEL__
#define VNPLUG_PCI_REG_BAR_ID 0
#define VNPLUG_PCI_MSI_BAR_ID 1
#define VNPLUG_PCI_BASE_MM_BAR_ID 2
#define VNPLUG_MAX_MM_BARS 4
/* mmap regions: MM BARSs + registers BAR */
#define VNPLUG_MAX_REGIONS VNPLUG_MAX_MM_BARS + 1
#define VNPLUG_MAX_MSI_VECTORS 16
struct vnplug_device {
struct device *dev;
int minor;
atomic_t event;
wait_queue_head_t wait;
#ifdef VNPLUG_MULTI_IRQ
atomic_t *event_s;
wait_queue_head_t *wait_s;
#endif /* VNPLUG_MULTI_IRQ */
struct vnplug_info *info;
};
struct vnplug_mem {
unsigned long addr;
unsigned long size;
void __iomem *internal_addr;
};
struct vnplug_info {
struct pci_dev *dev;
char (*msix_names)[16]; /* 16 chars for a name should be enough */
struct msix_entry *msix_entries;
int nvectors;
struct vnplug_device *vnplug_dev;
struct vnplug_mem mem[VNPLUG_MAX_REGIONS];
};
struct vnplug_listener {
struct vnplug_device *dev;
s32 event_count;
#ifdef VNPLUG_MULTI_IRQ
s32 *event_count_s;
#endif /* VNPLUG_MULTI_IRQ */
};
#endif /* __KERNEL__ */
#ifdef VNPLUG_CTRL
#ifdef __KERNEL__
#include <linux/module.h>
#include <linux/virtio.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/virtio_config.h>
#define VNPLUG_CTRL_DEVICE_NAME "vnplug_ctrl"
/* Macros and data structures taken from 'hw/vnplug-ctrl.h' (host side): */
#define PCI_DEVICE_ID_VNPLUG_CTRL 0x100f
#define VIRTIO_ID_VNPLUG_CTRL 15
/* The feature bitmap for vnplug-ctrl over virtio */
#define VNPLUG_CTRL_STATUS 0 /* vnplug_ctrl_status available */
struct vnplug_ctrl_virtio_config
{
/* See VNPLUG_CTRL_STATUS feature bit */
#define VNPLUG_CTRL_STATUS_UP 1
uint16_t status;
uint16_t padding; //I'm an alignment maniac :D
}; //__attribute__((packed));
/* guest mod -> host */
struct vnplug_ctrl_msg_hdr {
/* g2h message type */
#define VNPLUG_CTRL_MSG_FORWARD 0 /* Forward the message to the client identified by id */
uint32_t type;
/* client id */
uint32_t id;
/* payload size is not required with current implementation (iov's len)*/
}; //__attribute__((packed));
struct vnplug_ctrl_info
{
struct device *dev;
struct virtio_device *vdev;
struct virtqueue *g2h_vq;
unsigned int status;
};
#endif /* __KERNEL__ */
/* return values */
#define VNPLUG_CTRL_MSG_RET_SUCCESS 0
#define VNPLUG_CTRL_MSG_RET_CLIENT_NOT_FOUND -1
#define VNPLUG_CTRL_MSG_RET_CLIENT_ERROR -2
/* guest lib -> guest mod */
struct vnplug_ctrl_msg {
uint32_t id; /* client id */
uint32_t payload_len;
uint32_t ret_payload_len; /* return value lenght */
char payload[0];
/* ret_payload is at the and of payload */
};
#endif /* VNPLUG_CTRL */
#endif /* KERNEL_VNPLUG_H */