New upstream version 18.08
[deb_dpdk.git] / drivers / bus / vmbus / rte_bus_vmbus.h
diff --git a/drivers/bus/vmbus/rte_bus_vmbus.h b/drivers/bus/vmbus/rte_bus_vmbus.h
new file mode 100644 (file)
index 0000000..4a2c1f6
--- /dev/null
@@ -0,0 +1,407 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2018, Microsoft Corporation.
+ * All Rights Reserved.
+ */
+
+#ifndef _VMBUS_H_
+#define _VMBUS_H_
+
+/**
+ * @file
+ *
+ * VMBUS Interface
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_compat.h>
+#include <rte_uuid.h>
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_vmbus_reg.h>
+
+/* Forward declarations */
+struct rte_vmbus_device;
+struct rte_vmbus_driver;
+struct rte_vmbus_bus;
+struct vmbus_channel;
+struct vmbus_mon_page;
+
+TAILQ_HEAD(rte_vmbus_device_list, rte_vmbus_device);
+TAILQ_HEAD(rte_vmbus_driver_list, rte_vmbus_driver);
+
+/* VMBus iterators */
+#define FOREACH_DEVICE_ON_VMBUS(p)     \
+       TAILQ_FOREACH(p, &(rte_vmbus_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_VMBUS(p)     \
+       TAILQ_FOREACH(p, &(rte_vmbus_bus.driver_list), next)
+
+/** Maximum number of VMBUS resources. */
+enum hv_uio_map {
+       HV_TXRX_RING_MAP = 0,
+       HV_INT_PAGE_MAP,
+       HV_MON_PAGE_MAP,
+       HV_RECV_BUF_MAP,
+       HV_SEND_BUF_MAP
+};
+#define VMBUS_MAX_RESOURCE 5
+
+/**
+ * A structure describing a VMBUS device.
+ */
+struct rte_vmbus_device {
+       TAILQ_ENTRY(rte_vmbus_device) next;    /**< Next probed VMBUS device */
+       const struct rte_vmbus_driver *driver; /**< Associated driver */
+       struct rte_device device;              /**< Inherit core device */
+       rte_uuid_t device_id;                  /**< VMBUS device id */
+       rte_uuid_t class_id;                   /**< VMBUS device type */
+       uint32_t relid;                        /**< id for primary */
+       uint8_t monitor_id;                    /**< monitor page */
+       int uio_num;                           /**< UIO device number */
+       uint32_t *int_page;                    /**< VMBUS interrupt page */
+       struct vmbus_channel *primary;         /**< VMBUS primary channel */
+       struct vmbus_mon_page *monitor_page;   /**< VMBUS monitor page */
+
+       struct rte_intr_handle intr_handle;    /**< Interrupt handle */
+       struct rte_mem_resource resource[VMBUS_MAX_RESOURCE];
+};
+
+/**
+ * Initialization function for the driver called during VMBUS probing.
+ */
+typedef int (vmbus_probe_t)(struct rte_vmbus_driver *,
+                           struct rte_vmbus_device *);
+
+/**
+ * Initialization function for the driver called during hot plugging.
+ */
+typedef int (vmbus_remove_t)(struct rte_vmbus_device *);
+
+/**
+ * A structure describing a VMBUS driver.
+ */
+struct rte_vmbus_driver {
+       TAILQ_ENTRY(rte_vmbus_driver) next; /**< Next in list. */
+       struct rte_driver driver;
+       struct rte_vmbus_bus *bus;          /**< VM bus reference. */
+       vmbus_probe_t *probe;               /**< Device Probe function. */
+       vmbus_remove_t *remove;             /**< Device Remove function. */
+
+       const rte_uuid_t *id_table;         /**< ID table. */
+};
+
+
+/**
+ * Structure describing the VM bus
+ */
+struct rte_vmbus_bus {
+       struct rte_bus bus;               /**< Inherit the generic class */
+       struct rte_vmbus_device_list device_list;  /**< List of devices */
+       struct rte_vmbus_driver_list driver_list;  /**< List of drivers */
+};
+
+/**
+ * Scan the content of the VMBUS bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_vmbus_scan(void);
+
+/**
+ * Probe the VMBUS bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int rte_vmbus_probe(void);
+
+/**
+ * Map the VMBUS device resources in user space virtual memory address
+ *
+ * @param dev
+ *   A pointer to a rte_vmbus_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_vmbus_map_device(struct rte_vmbus_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_vmbus_device structure describing the device
+ *   to use
+ */
+void rte_vmbus_unmap_device(struct rte_vmbus_device *dev);
+
+/**
+ * Get connection to primary VMBUS channel
+ *
+ * @param device
+ *   A pointer to a rte_vmbus_device structure describing the device
+ * @param chan
+ *   A pointer to a VMBUS channel pointer that will be filled.
+ * @return
+ *   - 0 Success; channel opened.
+ *   - -ENOMEM: Not enough memory available.
+ *   - -EINVAL: Regions could not be mapped.
+ */
+int rte_vmbus_chan_open(struct rte_vmbus_device *device,
+                       struct vmbus_channel **chan);
+
+/**
+ * Free connection to VMBUS channel
+ *
+ * @param chan
+ *    VMBUS channel
+ */
+void rte_vmbus_chan_close(struct vmbus_channel *chan);
+
+/**
+ * Gets the maximum number of channels supported on device
+ *
+ * @param device
+ *   A pointer to a rte_vmbus_device structure describing the device
+ * @return
+ *   Number of channels available.
+ */
+int rte_vmbus_max_channels(const struct rte_vmbus_device *device);
+
+/**
+ * Get a connection to new secondary vmbus channel
+ *
+ * @param primary
+ *   A pointer to primary VMBUS channel
+ * @param chan
+ *   A pointer to a secondary VMBUS channel pointer that will be filled.
+ * @return
+ *   - 0 Success; channel opened.
+ *   - -ENOMEM: Not enough memory available.
+ *   - -EINVAL: Regions could not be mapped.
+ */
+int rte_vmbus_subchan_open(struct vmbus_channel *primary,
+                          struct vmbus_channel **new_chan);
+
+/**
+ * Disable IRQ for device
+ *
+ * @param device
+ *    VMBUS device
+ */
+void rte_vmbus_irq_mask(struct rte_vmbus_device *device);
+
+/**
+ * Enable IRQ for device
+ *
+ * @param device
+ *    VMBUS device
+ */
+void rte_vmbus_irq_unmask(struct rte_vmbus_device *device);
+
+/**
+ * Read (and wait) for IRQ
+ *
+ * @param device
+ *    VMBUS device
+ */
+int rte_vmbus_irq_read(struct rte_vmbus_device *device);
+
+/**
+ * Test if channel is empty
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ * @return
+ *     Return true if no data present in incoming ring.
+ */
+bool rte_vmbus_chan_rx_empty(const struct vmbus_channel *channel);
+
+/**
+ * Send the specified buffer on the given channel
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ * @param type
+ *     Type of packet that is being send e.g. negotiate, time
+ *     packet etc.
+ * @param data
+ *     Pointer to the buffer to send
+ * @param dlen
+ *     Number of bytes of data to send
+ * @param xact
+ *     Identifier of the request
+ * @param flags
+ *     Message type inband, rxbuf, gpa
+ * @param need_sig
+ *     Is host signal tx is required (optional)
+ *
+ * Sends data in buffer directly to hyper-v via the vmbus
+ */
+int rte_vmbus_chan_send(struct vmbus_channel *channel, uint16_t type,
+                       void *data, uint32_t dlen,
+                       uint64_t xact, uint32_t flags, bool *need_sig);
+
+/**
+ * Explicitly signal host that data is available
+ *
+ * @param
+ *     Pointer to vmbus_channel structure.
+ *
+ * Used when batching multiple sends and only signaling host
+ * after the last send.
+ */
+void rte_vmbus_chan_signal_tx(const struct vmbus_channel *channel);
+
+/* Structure for scatter/gather I/O */
+struct iova_list {
+       rte_iova_t      addr;
+       uint32_t        len;
+};
+#define MAX_PAGE_BUFFER_COUNT          32
+
+/**
+ * Send a scattered buffer on the given channel
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ * @param type
+ *     Type of packet that is being send e.g. negotiate, time
+ *     packet etc.
+ * @param gpa
+ *     Array of buffers to send
+ * @param gpacnt
+ *     Number of elements in iov
+ * @param data
+ *     Pointer to the buffer additional data to send
+ * @param dlen
+ *      Maximum size of what the the buffer will hold
+ * @param xact
+ *     Identifier of the request
+ * @param flags
+ *     Message type inband, rxbuf, gpa
+ * @param need_sig
+ *     Is host signal tx is required (optional)
+ *
+ * Sends data in buffer directly to hyper-v via the vmbus
+ */
+int rte_vmbus_chan_send_sglist(struct vmbus_channel *channel,
+                              struct vmbus_gpa gpa[], uint32_t gpacnt,
+                              void *data, uint32_t dlen,
+                              uint64_t xact, bool *need_sig);
+/**
+ * Receive response to request on the given channel
+ * skips the channel header.
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ * @param data
+ *     Pointer to the buffer you want to receive the data into.
+ * @param len
+ *     Pointer to size of receive buffer (in/out)
+ * @param
+ *     Pointer to received transaction_id
+ * @return
+ *   On success, returns 0
+ *   On failure, returns negative errno.
+ */
+int rte_vmbus_chan_recv(struct vmbus_channel *chan,
+                       void *data, uint32_t *len,
+                       uint64_t *request_id);
+
+/**
+ * Receive response to request on the given channel
+ * includes the channel header.
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ * @param data
+ *     Pointer to the buffer you want to receive the data into.
+ * @param len
+ *     Pointer to size of receive buffer (in/out)
+ * @return
+ *   On success, returns number of bytes read.
+ *   On failure, returns negative errno.
+ */
+int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan,
+                           void *data, uint32_t *len);
+
+/**
+ * Notify host of bytes read (after recv_raw)
+ * Signals host if required.
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ * @param bytes_read
+ *     Number of bytes read since last signal
+ */
+void rte_vmbus_chan_signal_read(struct vmbus_channel *chan, uint32_t bytes_read);
+
+/**
+ * Determine sub channel index of the given channel
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ * @return
+ *   Sub channel index (0 for primary)
+ */
+uint16_t rte_vmbus_sub_channel_index(const struct vmbus_channel *chan);
+
+/**
+ * Register a VMBUS driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vmbus_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_vmbus_register(struct rte_vmbus_driver *driver);
+
+/**
+ * For debug dump contents of ring buffer.
+ *
+ * @param channel
+ *     Pointer to vmbus_channel structure.
+ */
+void rte_vmbus_chan_dump(FILE *f, const struct vmbus_channel *chan);
+
+/**
+ * Unregister a VMBUS driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vmbus_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_vmbus_unregister(struct rte_vmbus_driver *driver);
+
+/** Helper for VMBUS device registration from driver instance */
+#define RTE_PMD_REGISTER_VMBUS(nm, vmbus_drv)          \
+       RTE_INIT(vmbusinitfn_ ##nm);                    \
+       static void vmbusinitfn_ ##nm(void)             \
+       {                                               \
+               (vmbus_drv).driver.name = RTE_STR(nm);  \
+               rte_vmbus_register(&vmbus_drv);         \
+       }                                               \
+       RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VMBUS_H_ */