ntb_if.m revision 304380
1#-
2# Copyright (c) 2016 Alexander Motin <mav@FreeBSD.org>
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8# 1. Redistributions of source code must retain the above copyright
9#    notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24# SUCH DAMAGE.
25#
26# $FreeBSD: stable/10/sys/dev/ntb/ntb_if.m 304380 2016-08-18 10:39:00Z mav $
27#
28
29#include <sys/bus.h>
30#include <machine/bus.h>
31
32INTERFACE ntb;
33
34HEADER {
35	enum ntb_speed {
36		NTB_SPEED_AUTO = -1,
37		NTB_SPEED_NONE = 0,
38		NTB_SPEED_GEN1 = 1,
39		NTB_SPEED_GEN2 = 2,
40		NTB_SPEED_GEN3 = 3,
41	};
42
43	enum ntb_width {
44		NTB_WIDTH_AUTO = -1,
45		NTB_WIDTH_NONE = 0,
46		NTB_WIDTH_1 = 1,
47		NTB_WIDTH_2 = 2,
48		NTB_WIDTH_4 = 4,
49		NTB_WIDTH_8 = 8,
50		NTB_WIDTH_12 = 12,
51		NTB_WIDTH_16 = 16,
52		NTB_WIDTH_32 = 32,
53	};
54
55	typedef void (*ntb_db_callback)(void *data, uint32_t vector);
56	typedef void (*ntb_event_callback)(void *data);
57	struct ntb_ctx_ops {
58		ntb_event_callback	link_event;
59		ntb_db_callback		db_event;
60	};
61};
62
63#
64# ntb_link_is_up() - get the current ntb link state
65# @ntb:        NTB device context
66# @speed:      OUT - The link speed expressed as PCIe generation number
67# @width:      OUT - The link width expressed as the number of PCIe lanes
68#
69# RETURNS: true or false based on the hardware link state
70#
71METHOD bool link_is_up {
72	device_t	 ntb;
73	enum ntb_speed	*speed;
74	enum ntb_width	*width;
75};
76
77#
78# ntb_link_enable() - enable the link on the secondary side of the ntb
79# @ntb:        NTB device context
80# @max_speed:  The maximum link speed expressed as PCIe generation number[0]
81# @max_width:  The maximum link width expressed as the number of PCIe lanes[0]
82#
83# Enable the link on the secondary side of the ntb.  This can only be done
84# from the primary side of the ntb in primary or b2b topology.  The ntb device
85# should train the link to its maximum speed and width, or the requested speed
86# and width, whichever is smaller, if supported.
87#
88# Return: Zero on success, otherwise an error number.
89#
90# [0]: Only NTB_SPEED_AUTO and NTB_WIDTH_AUTO are valid inputs; other speed
91#      and width input will be ignored.
92#/
93METHOD int link_enable {
94	device_t	 ntb;
95	enum ntb_speed	 speed;
96	enum ntb_width	 width;
97};
98
99#
100# ntb_link_disable() - disable the link on the secondary side of the ntb
101# @ntb:        NTB device context
102#
103# Disable the link on the secondary side of the ntb.  This can only be done
104# from the primary side of the ntb in primary or b2b topology.  The ntb device
105# should disable the link.  Returning from this call must indicate that a
106# barrier has passed, though with no more writes may pass in either direction
107# across the link, except if this call returns an error number.
108#
109# Return: Zero on success, otherwise an error number.
110#
111METHOD int link_disable {
112	device_t	 ntb;
113};
114
115#
116# get enable status of the link on the secondary side of the ntb
117#
118METHOD bool link_enabled {
119	device_t	 ntb;
120};
121
122#
123# ntb_set_ctx() - associate a driver context with an ntb device
124# @ntb:        NTB device context
125# @ctx:        Driver context
126# @ctx_ops:    Driver context operations
127#
128# Associate a driver context and operations with a ntb device.  The context is
129# provided by the client driver, and the driver may associate a different
130# context with each ntb device.
131#
132# Return: Zero if the context is associated, otherwise an error number.
133#
134METHOD int set_ctx {
135	device_t	 ntb;
136	void		*ctx;
137	const struct ntb_ctx_ops *ctx_ops;
138};
139
140#
141# ntb_set_ctx() - get a driver context associated with an ntb device
142# @ntb:        NTB device context
143# @ctx_ops:    Driver context operations
144#
145# Get a driver context and operations associated with a ntb device.
146#
147METHOD void * get_ctx {
148	device_t	 ntb;
149	const struct ntb_ctx_ops **ctx_ops;
150};
151
152#
153# ntb_clear_ctx() - disassociate any driver context from an ntb device
154# @ntb:        NTB device context
155#
156# Clear any association that may exist between a driver context and the ntb
157# device.
158#
159METHOD void clear_ctx {
160	device_t	 ntb;
161};
162
163#
164# ntb_mw_count() - Get the number of memory windows available for KPI
165# consumers.
166#
167# (Excludes any MW wholly reserved for register access.)
168#
169METHOD uint8_t mw_count {
170	device_t	 ntb;
171};
172
173#
174# ntb_mw_get_range() - get the range of a memory window
175# @ntb:        NTB device context
176# @idx:        Memory window number
177# @base:       OUT - the base address for mapping the memory window
178# @size:       OUT - the size for mapping the memory window
179# @align:      OUT - the base alignment for translating the memory window
180# @align_size: OUT - the size alignment for translating the memory window
181#
182# Get the range of a memory window.  NULL may be given for any output
183# parameter if the value is not needed.  The base and size may be used for
184# mapping the memory window, to access the peer memory.  The alignment and
185# size may be used for translating the memory window, for the peer to access
186# memory on the local system.
187#
188# Return: Zero on success, otherwise an error number.
189#
190METHOD int mw_get_range {
191	device_t	 ntb;
192	unsigned	 mw_idx;
193	vm_paddr_t	*base;
194	caddr_t		*vbase;
195	size_t		*size;
196	size_t		*align;
197	size_t		*align_size;
198	bus_addr_t	*plimit;
199};
200
201#
202# ntb_mw_set_trans() - set the translation of a memory window
203# @ntb:        NTB device context
204# @idx:        Memory window number
205# @addr:       The dma address local memory to expose to the peer
206# @size:       The size of the local memory to expose to the peer
207#
208# Set the translation of a memory window.  The peer may access local memory
209# through the window starting at the address, up to the size.  The address
210# must be aligned to the alignment specified by ntb_mw_get_range().  The size
211# must be aligned to the size alignment specified by ntb_mw_get_range().  The
212# address must be below the plimit specified by ntb_mw_get_range() (i.e. for
213# 32-bit BARs).
214#
215# Return: Zero on success, otherwise an error number.
216#
217METHOD int mw_set_trans {
218	device_t	 ntb;
219	unsigned	 mw_idx;
220	bus_addr_t	 addr;
221	size_t		 size;
222};
223
224#
225# ntb_mw_clear_trans() - clear the translation of a memory window
226# @ntb:	NTB device context
227# @idx:	Memory window number
228#
229# Clear the translation of a memory window.  The peer may no longer access
230# local memory through the window.
231#
232# Return: Zero on success, otherwise an error number.
233#
234METHOD int mw_clear_trans {
235	device_t	 ntb;
236	unsigned	 mw_idx;
237};
238
239#
240# ntb_mw_get_wc - Get the write-combine status of a memory window
241#
242# Returns:  Zero on success, setting *wc; otherwise an error number (e.g. if
243# idx is an invalid memory window).
244#
245# Mode is a VM_MEMATTR_* type.
246#
247METHOD int mw_get_wc {
248	device_t	 ntb;
249	unsigned	 mw_idx;
250	vm_memattr_t	*mode;
251};
252
253#
254# ntb_mw_set_wc - Set the write-combine status of a memory window
255#
256# If 'mode' matches the current status, this does nothing and succeeds.  Mode
257# is a VM_MEMATTR_* type.
258#
259# Returns:  Zero on success, setting the caching attribute on the virtual
260# mapping of the BAR; otherwise an error number (e.g. if idx is an invalid
261# memory window, or if changing the caching attribute fails).
262#
263METHOD int mw_set_wc {
264	device_t	 ntb;
265	unsigned	 mw_idx;
266	vm_memattr_t	 mode;
267};
268
269#
270# ntb_spad_count() - get the total scratch regs usable
271# @ntb: pointer to ntb_softc instance
272#
273# This function returns the max 32bit scratchpad registers usable by the
274# upper layer.
275#
276# RETURNS: total number of scratch pad registers available
277#
278METHOD uint8_t spad_count {
279	device_t	 ntb;
280};
281
282#
283# ntb_get_max_spads() - zero local scratch registers
284# @ntb: pointer to ntb_softc instance
285#
286# This functions overwrites all local scratchpad registers with zeroes.
287#
288METHOD void spad_clear {
289	device_t	 ntb;
290};
291
292#
293# ntb_spad_write() - write to the secondary scratchpad register
294# @ntb: pointer to ntb_softc instance
295# @idx: index to the scratchpad register, 0 based
296# @val: the data value to put into the register
297#
298# This function allows writing of a 32bit value to the indexed scratchpad
299# register. The register resides on the secondary (external) side.
300#
301# RETURNS: An appropriate ERRNO error value on error, or zero for success.
302#
303METHOD int spad_write {
304	device_t	 ntb;
305	unsigned int	 idx;
306	uint32_t	 val;
307};
308
309#
310# ntb_spad_read() - read from the primary scratchpad register
311# @ntb: pointer to ntb_softc instance
312# @idx: index to scratchpad register, 0 based
313# @val: pointer to 32bit integer for storing the register value
314#
315# This function allows reading of the 32bit scratchpad register on
316# the primary (internal) side.
317#
318# RETURNS: An appropriate ERRNO error value on error, or zero for success.
319#
320METHOD int spad_read {
321	device_t	 ntb;
322	unsigned int	 idx;
323	uint32_t	 *val;
324};
325
326#
327# ntb_peer_spad_write() - write to the secondary scratchpad register
328# @ntb: pointer to ntb_softc instance
329# @idx: index to the scratchpad register, 0 based
330# @val: the data value to put into the register
331#
332# This function allows writing of a 32bit value to the indexed scratchpad
333# register. The register resides on the secondary (external) side.
334#
335# RETURNS: An appropriate ERRNO error value on error, or zero for success.
336#
337METHOD int peer_spad_write {
338	device_t	 ntb;
339	unsigned int	 idx;
340	uint32_t	 val;
341};
342
343#
344# ntb_peer_spad_read() - read from the primary scratchpad register
345# @ntb: pointer to ntb_softc instance
346# @idx: index to scratchpad register, 0 based
347# @val: pointer to 32bit integer for storing the register value
348#
349# This function allows reading of the 32bit scratchpad register on
350# the primary (internal) side.
351#
352# RETURNS: An appropriate ERRNO error value on error, or zero for success.
353#
354METHOD int peer_spad_read {
355	device_t	 ntb;
356	unsigned int	 idx;
357	uint32_t	*val;
358};
359
360#
361# ntb_db_valid_mask() - get a mask of doorbell bits supported by the ntb
362# @ntb:	NTB device context
363#
364# Hardware may support different number or arrangement of doorbell bits.
365#
366# Return: A mask of doorbell bits supported by the ntb.
367#
368METHOD uint64_t db_valid_mask {
369	device_t	 ntb;
370};
371
372#
373# ntb_db_vector_count() - get the number of doorbell interrupt vectors
374# @ntb:	NTB device context.
375#
376# Hardware may support different number of interrupt vectors.
377#
378# Return: The number of doorbell interrupt vectors.
379#
380METHOD int db_vector_count {
381	device_t	 ntb;
382};
383
384#
385# ntb_db_vector_mask() - get a mask of doorbell bits serviced by a vector
386# @ntb:	NTB device context
387# @vector:	Doorbell vector number
388#
389# Each interrupt vector may have a different number or arrangement of bits.
390#
391# Return: A mask of doorbell bits serviced by a vector.
392#
393METHOD uint64_t db_vector_mask {
394	device_t	 ntb;
395	uint32_t	 vector;
396};
397
398#
399# ntb_peer_db_addr() - address and size of the peer doorbell register
400# @ntb:	NTB device context.
401# @db_addr:	OUT - The address of the peer doorbell register.
402# @db_size:	OUT - The number of bytes to write the peer doorbell register.
403#
404# Return the address of the peer doorbell register.  This may be used, for
405# example, by drivers that offload memory copy operations to a dma engine.
406# The drivers may wish to ring the peer doorbell at the completion of memory
407# copy operations.  For efficiency, and to simplify ordering of operations
408# between the dma memory copies and the ringing doorbell, the driver may
409# append one additional dma memory copy with the doorbell register as the
410# destination, after the memory copy operations.
411#
412# Return: Zero on success, otherwise an error number.
413#
414# Note that writing the peer doorbell via a memory window will *not* generate
415# an interrupt on the remote host; that must be done separately.
416#
417METHOD int peer_db_addr {
418	device_t	 ntb;
419	bus_addr_t	*db_addr;
420	vm_size_t	*db_size;
421};
422
423#
424# ntb_db_clear() - clear bits in the local doorbell register
425# @ntb:	NTB device context.
426# @db_bits:	Doorbell bits to clear.
427#
428# Clear bits in the local doorbell register, arming the bits for the next
429# doorbell.
430#
431# Return: Zero on success, otherwise an error number.
432#
433METHOD void db_clear {
434	device_t	 ntb;
435	uint64_t	 bits;
436};
437
438#
439# ntb_db_clear_mask() - clear bits in the local doorbell mask
440# @ntb:	NTB device context.
441# @db_bits:	Doorbell bits to clear.
442#
443# Clear bits in the local doorbell mask register, allowing doorbell interrupts
444# from being generated for those doorbell bits.  If a doorbell bit is already
445# set at the time the mask is cleared, and the corresponding mask bit is
446# changed from set to clear, then the ntb driver must ensure that
447# ntb_db_event() is called.  If the hardware does not generate the interrupt
448# on clearing the mask bit, then the driver must call ntb_db_event() anyway.
449#
450# Return: Zero on success, otherwise an error number.
451#
452METHOD void db_clear_mask {
453	device_t	 ntb;
454	uint64_t	 bits;
455};
456
457#
458# ntb_db_read() - read the local doorbell register
459# @ntb:	NTB device context.
460#
461# Read the local doorbell register, and return the bits that are set.
462#
463# Return: The bits currently set in the local doorbell register.
464#
465METHOD uint64_t db_read {
466	device_t	 ntb;
467};
468
469#
470# ntb_db_set_mask() - set bits in the local doorbell mask
471# @ntb:	NTB device context.
472# @db_bits:	Doorbell mask bits to set.
473#
474# Set bits in the local doorbell mask register, preventing doorbell interrupts
475# from being generated for those doorbell bits.  Bits that were already set
476# must remain set.
477#
478# Return: Zero on success, otherwise an error number.
479#
480METHOD void db_set_mask {
481	device_t	 ntb;
482	uint64_t	 bits;
483};
484
485#
486# ntb_peer_db_set() - Set the doorbell on the secondary/external side
487# @ntb: pointer to ntb_softc instance
488# @bit: doorbell bits to ring
489#
490# This function allows triggering of a doorbell on the secondary/external
491# side that will initiate an interrupt on the remote host
492#
493METHOD void peer_db_set {
494	device_t	 ntb;
495	uint64_t	 bits;
496};
497
498