0100f80ff9a0989dcc1dbb631921f6f7376e33fd
[dpdk.git] / drivers / bus / vmbus / rte_bus_vmbus.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2018, Microsoft Corporation.
3  * All Rights Reserved.
4  */
5
6 #ifndef _VMBUS_H_
7 #define _VMBUS_H_
8
9 /**
10  * @file
11  *
12  * VMBUS Interface
13  */
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <limits.h>
21 #include <stdbool.h>
22 #include <errno.h>
23 #include <sys/queue.h>
24 #include <stdint.h>
25 #include <inttypes.h>
26
27 #include <rte_compat.h>
28 #include <rte_uuid.h>
29 #include <rte_debug.h>
30 #include <rte_interrupts.h>
31 #include <rte_dev.h>
32 #include <rte_vmbus_reg.h>
33
34 /* Forward declarations */
35 struct rte_vmbus_device;
36 struct rte_vmbus_driver;
37 struct rte_vmbus_bus;
38 struct vmbus_channel;
39 struct vmbus_mon_page;
40
41 TAILQ_HEAD(rte_vmbus_device_list, rte_vmbus_device);
42 TAILQ_HEAD(rte_vmbus_driver_list, rte_vmbus_driver);
43
44 /* VMBus iterators */
45 #define FOREACH_DEVICE_ON_VMBUS(p)      \
46         TAILQ_FOREACH(p, &(rte_vmbus_bus.device_list), next)
47
48 #define FOREACH_DRIVER_ON_VMBUS(p)      \
49         TAILQ_FOREACH(p, &(rte_vmbus_bus.driver_list), next)
50
51 /** Maximum number of VMBUS resources. */
52 enum hv_uio_map {
53         HV_TXRX_RING_MAP = 0,
54         HV_INT_PAGE_MAP,
55         HV_MON_PAGE_MAP,
56         HV_RECV_BUF_MAP,
57         HV_SEND_BUF_MAP
58 };
59 #define VMBUS_MAX_RESOURCE 5
60
61 /**
62  * A structure describing a VMBUS device.
63  */
64 struct rte_vmbus_device {
65         TAILQ_ENTRY(rte_vmbus_device) next;    /**< Next probed VMBUS device */
66         const struct rte_vmbus_driver *driver; /**< Associated driver */
67         struct rte_device device;              /**< Inherit core device */
68         rte_uuid_t device_id;                  /**< VMBUS device id */
69         rte_uuid_t class_id;                   /**< VMBUS device type */
70         uint32_t relid;                        /**< id for primary */
71         uint8_t monitor_id;                    /**< monitor page */
72         int uio_num;                           /**< UIO device number */
73         uint32_t *int_page;                    /**< VMBUS interrupt page */
74         struct vmbus_channel *primary;         /**< VMBUS primary channel */
75         struct vmbus_mon_page *monitor_page;   /**< VMBUS monitor page */
76
77         struct rte_intr_handle intr_handle;    /**< Interrupt handle */
78         struct rte_mem_resource resource[VMBUS_MAX_RESOURCE];
79 };
80
81 /**
82  * Initialization function for the driver called during VMBUS probing.
83  */
84 typedef int (vmbus_probe_t)(struct rte_vmbus_driver *,
85                             struct rte_vmbus_device *);
86
87 /**
88  * Initialization function for the driver called during hot plugging.
89  */
90 typedef int (vmbus_remove_t)(struct rte_vmbus_device *);
91
92 /**
93  * A structure describing a VMBUS driver.
94  */
95 struct rte_vmbus_driver {
96         TAILQ_ENTRY(rte_vmbus_driver) next; /**< Next in list. */
97         struct rte_driver driver;
98         struct rte_vmbus_bus *bus;          /**< VM bus reference. */
99         vmbus_probe_t *probe;               /**< Device Probe function. */
100         vmbus_remove_t *remove;             /**< Device Remove function. */
101
102         const rte_uuid_t *id_table;         /**< ID table. */
103 };
104
105
106 /**
107  * Structure describing the VM bus
108  */
109 struct rte_vmbus_bus {
110         struct rte_bus bus;               /**< Inherit the generic class */
111         struct rte_vmbus_device_list device_list;  /**< List of devices */
112         struct rte_vmbus_driver_list driver_list;  /**< List of drivers */
113 };
114
115 /**
116  * Scan the content of the VMBUS bus, and the devices in the devices
117  * list
118  *
119  * @return
120  *  0 on success, negative on error
121  */
122 int rte_vmbus_scan(void);
123
124 /**
125  * Probe the VMBUS bus
126  *
127  * @return
128  *   - 0 on success.
129  *   - !0 on error.
130  */
131 int rte_vmbus_probe(void);
132
133 /**
134  * Map the VMBUS device resources in user space virtual memory address
135  *
136  * @param dev
137  *   A pointer to a rte_vmbus_device structure describing the device
138  *   to use
139  *
140  * @return
141  *   0 on success, negative on error and positive if no driver
142  *   is found for the device.
143  */
144 int rte_vmbus_map_device(struct rte_vmbus_device *dev);
145
146 /**
147  * Unmap this device
148  *
149  * @param dev
150  *   A pointer to a rte_vmbus_device structure describing the device
151  *   to use
152  */
153 void rte_vmbus_unmap_device(struct rte_vmbus_device *dev);
154
155 /**
156  * Get connection to primary VMBUS channel
157  *
158  * @param device
159  *   A pointer to a rte_vmbus_device structure describing the device
160  * @param chan
161  *   A pointer to a VMBUS channel pointer that will be filled.
162  * @return
163  *   - 0 Success; channel opened.
164  *   - -ENOMEM: Not enough memory available.
165  *   - -EINVAL: Regions could not be mapped.
166  */
167 int rte_vmbus_chan_open(struct rte_vmbus_device *device,
168                         struct vmbus_channel **chan);
169
170 /**
171  * Free connection to VMBUS channel
172  *
173  * @param chan
174  *    VMBUS channel
175  */
176 void rte_vmbus_chan_close(struct vmbus_channel *chan);
177
178 /**
179  * Gets the maximum number of channels supported on device
180  *
181  * @param device
182  *   A pointer to a rte_vmbus_device structure describing the device
183  * @return
184  *   Number of channels available.
185  */
186 int rte_vmbus_max_channels(const struct rte_vmbus_device *device);
187
188 /**
189  * Get a connection to new secondary vmbus channel
190  *
191  * @param primary
192  *   A pointer to primary VMBUS channel
193  * @param chan
194  *   A pointer to a secondary VMBUS channel pointer that will be filled.
195  * @return
196  *   - 0 Success; channel opened.
197  *   - -ENOMEM: Not enough memory available.
198  *   - -EINVAL: Regions could not be mapped.
199  */
200 int rte_vmbus_subchan_open(struct vmbus_channel *primary,
201                            struct vmbus_channel **new_chan);
202
203 /**
204  * Disable IRQ for device
205  *
206  * @param device
207  *    VMBUS device
208  */
209 void rte_vmbus_irq_mask(struct rte_vmbus_device *device);
210
211 /**
212  * Enable IRQ for device
213  *
214  * @param device
215  *    VMBUS device
216  */
217 void rte_vmbus_irq_unmask(struct rte_vmbus_device *device);
218
219 /**
220  * Read (and wait) for IRQ
221  *
222  * @param device
223  *    VMBUS device
224  */
225 int rte_vmbus_irq_read(struct rte_vmbus_device *device);
226
227 /**
228  * Test if channel is empty
229  *
230  * @param channel
231  *      Pointer to vmbus_channel structure.
232  * @return
233  *      Return true if no data present in incoming ring.
234  */
235 bool rte_vmbus_chan_rx_empty(const struct vmbus_channel *channel);
236
237 /**
238  * Send the specified buffer on the given channel
239  *
240  * @param channel
241  *      Pointer to vmbus_channel structure.
242  * @param type
243  *      Type of packet that is being send e.g. negotiate, time
244  *      packet etc.
245  * @param data
246  *      Pointer to the buffer to send
247  * @param dlen
248  *      Number of bytes of data to send
249  * @param xact
250  *      Identifier of the request
251  * @param flags
252  *      Message type inband, rxbuf, gpa
253  * @param need_sig
254  *      Is host signal tx is required (optional)
255  *
256  * Sends data in buffer directly to hyper-v via the vmbus
257  */
258 int rte_vmbus_chan_send(struct vmbus_channel *channel, uint16_t type,
259                         void *data, uint32_t dlen,
260                         uint64_t xact, uint32_t flags, bool *need_sig);
261
262 /**
263  * Explicitly signal host that data is available
264  *
265  * @param
266  *      Pointer to vmbus_channel structure.
267  *
268  * Used when batching multiple sends and only signaling host
269  * after the last send.
270  */
271 void rte_vmbus_chan_signal_tx(const struct vmbus_channel *channel);
272
273 /* Structure for scatter/gather I/O */
274 struct iova_list {
275         rte_iova_t      addr;
276         uint32_t        len;
277 };
278 #define MAX_PAGE_BUFFER_COUNT           32
279
280 /**
281  * Send a scattered buffer on the given channel
282  *
283  * @param channel
284  *      Pointer to vmbus_channel structure.
285  * @param type
286  *      Type of packet that is being send e.g. negotiate, time
287  *      packet etc.
288  * @param gpa
289  *      Array of buffers to send
290  * @param gpacnt
291  *      Number of elements in iov
292  * @param data
293  *      Pointer to the buffer additional data to send
294  * @param dlen
295  *       Maximum size of what the the buffer will hold
296  * @param xact
297  *      Identifier of the request
298  * @param flags
299  *      Message type inband, rxbuf, gpa
300  * @param need_sig
301  *      Is host signal tx is required (optional)
302  *
303  * Sends data in buffer directly to hyper-v via the vmbus
304  */
305 int rte_vmbus_chan_send_sglist(struct vmbus_channel *channel,
306                                struct vmbus_gpa gpa[], uint32_t gpacnt,
307                                void *data, uint32_t dlen,
308                                uint64_t xact, bool *need_sig);
309 /**
310  * Receive response to request on the given channel
311  * skips the channel header.
312  *
313  * @param channel
314  *      Pointer to vmbus_channel structure.
315  * @param data
316  *      Pointer to the buffer you want to receive the data into.
317  * @param len
318  *      Pointer to size of receive buffer (in/out)
319  * @param
320  *      Pointer to received transaction_id
321  * @return
322  *   On success, returns 0
323  *   On failure, returns negative errno.
324  */
325 int rte_vmbus_chan_recv(struct vmbus_channel *chan,
326                         void *data, uint32_t *len,
327                         uint64_t *request_id);
328
329 /**
330  * Receive response to request on the given channel
331  * includes the channel header.
332  *
333  * @param channel
334  *      Pointer to vmbus_channel structure.
335  * @param data
336  *      Pointer to the buffer you want to receive the data into.
337  * @param len
338  *      Pointer to size of receive buffer (in/out)
339  * @return
340  *   On success, returns 0
341  *   On failure, returns negative errno.
342  */
343 int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan,
344                             void *data, uint32_t *len);
345
346 /**
347  * Determine sub channel index of the given channel
348  *
349  * @param channel
350  *      Pointer to vmbus_channel structure.
351  * @return
352  *   Sub channel index (0 for primary)
353  */
354 uint16_t rte_vmbus_sub_channel_index(const struct vmbus_channel *chan);
355
356 /**
357  * Register a VMBUS driver.
358  *
359  * @param driver
360  *   A pointer to a rte_vmbus_driver structure describing the driver
361  *   to be registered.
362  */
363 void rte_vmbus_register(struct rte_vmbus_driver *driver);
364
365 /**
366  * For debug dump contents of ring buffer.
367  *
368  * @param channel
369  *      Pointer to vmbus_channel structure.
370  */
371 void rte_vmbus_chan_dump(FILE *f, const struct vmbus_channel *chan);
372
373 /**
374  * Unregister a VMBUS driver.
375  *
376  * @param driver
377  *   A pointer to a rte_vmbus_driver structure describing the driver
378  *   to be unregistered.
379  */
380 void rte_vmbus_unregister(struct rte_vmbus_driver *driver);
381
382 /** Helper for VMBUS device registration from driver instance */
383 #define RTE_PMD_REGISTER_VMBUS(nm, vmbus_drv)           \
384         RTE_INIT(vmbusinitfn_ ##nm);                    \
385         static void vmbusinitfn_ ##nm(void)             \
386         {                                               \
387                 (vmbus_drv).driver.name = RTE_STR(nm);  \
388                 rte_vmbus_register(&vmbus_drv);         \
389         }                                               \
390         RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
391
392 #ifdef __cplusplus
393 }
394 #endif
395
396 #endif /* _VMBUS_H_ */