ntb_hw.c revision 289265
1/*-
2 * Copyright (C) 2013 Intel Corporation
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
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/ntb/ntb_hw/ntb_hw.c 289265 2015-10-13 20:54:38Z cem $");
29
30#include <sys/param.h>
31#include <sys/kernel.h>
32#include <sys/systm.h>
33#include <sys/bus.h>
34#include <sys/malloc.h>
35#include <sys/module.h>
36#include <sys/queue.h>
37#include <sys/rman.h>
38#include <sys/sysctl.h>
39#include <vm/vm.h>
40#include <vm/pmap.h>
41#include <machine/bus.h>
42#include <machine/pmap.h>
43#include <machine/resource.h>
44#include <dev/pci/pcireg.h>
45#include <dev/pci/pcivar.h>
46
47#include "ntb_regs.h"
48#include "ntb_hw.h"
49
50/*
51 * The Non-Transparent Bridge (NTB) is a device on some Intel processors that
52 * allows you to connect two systems using a PCI-e link.
53 *
54 * This module contains the hardware abstraction layer for the NTB. It allows
55 * you to send and recieve interrupts, map the memory windows and send and
56 * receive messages in the scratch-pad registers.
57 *
58 * NOTE: Much of the code in this module is shared with Linux. Any patches may
59 * be picked up and redistributed in Linux with a dual GPL/BSD license.
60 */
61
62#define NTB_CONFIG_BAR	0
63#define NTB_B2B_BAR_1	1
64#define NTB_B2B_BAR_2	2
65#define NTB_MAX_BARS	3
66#define NTB_MW_TO_BAR(mw) ((mw) + 1)
67
68#define MAX_MSIX_INTERRUPTS MAX(XEON_MAX_DB_BITS, SOC_MAX_DB_BITS)
69
70#define NTB_HB_TIMEOUT	1 /* second */
71#define SOC_LINK_RECOVERY_TIME	500
72
73#define DEVICE2SOFTC(dev) ((struct ntb_softc *) device_get_softc(dev))
74
75enum ntb_device_type {
76	NTB_XEON,
77	NTB_SOC
78};
79
80/* Device features and workarounds */
81#define HAS_FEATURE(feature)	\
82	((ntb->features & (feature)) != 0)
83
84struct ntb_hw_info {
85	uint32_t		device_id;
86	const char		*desc;
87	enum ntb_device_type	type;
88	uint64_t		features;
89};
90
91struct ntb_pci_bar_info {
92	bus_space_tag_t		pci_bus_tag;
93	bus_space_handle_t	pci_bus_handle;
94	int			pci_resource_id;
95	struct resource		*pci_resource;
96	vm_paddr_t		pbase;
97	void			*vbase;
98	u_long			size;
99};
100
101struct ntb_int_info {
102	struct resource	*res;
103	int		rid;
104	void		*tag;
105};
106
107struct ntb_db_cb {
108	ntb_db_callback		callback;
109	unsigned int		db_num;
110	void			*data;
111	struct ntb_softc	*ntb;
112};
113
114struct ntb_softc {
115	device_t		device;
116	enum ntb_device_type	type;
117	uint64_t		features;
118
119	struct ntb_pci_bar_info	bar_info[NTB_MAX_BARS];
120	struct ntb_int_info	int_info[MAX_MSIX_INTERRUPTS];
121	uint32_t		allocated_interrupts;
122
123	struct callout		heartbeat_timer;
124	struct callout		lr_timer;
125
126	void			*ntb_transport;
127	ntb_event_callback	event_cb;
128	struct ntb_db_cb 	*db_cb;
129
130	struct {
131		uint8_t max_spads;
132		uint8_t max_db_bits;
133		uint8_t msix_cnt;
134	} limits;
135	struct {
136		uint32_t ldb;
137		uint32_t ldb_mask;
138		uint32_t rdb;
139		uint32_t bar2_xlat;
140		uint32_t bar4_xlat;
141		uint32_t spad_remote;
142		uint32_t spad_local;
143		uint32_t lnk_cntl;
144		uint32_t lnk_stat;
145		uint32_t spci_cmd;
146	} reg_ofs;
147	uint8_t conn_type;
148	uint8_t dev_type;
149	uint8_t bits_per_vector;
150	uint8_t link_status;
151	uint8_t link_width;
152	uint8_t link_speed;
153};
154
155#ifdef __i386__
156static __inline uint64_t
157bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
158    bus_size_t offset)
159{
160
161	return (bus_space_read_4(tag, handle, offset) |
162	    ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32);
163}
164
165static __inline void
166bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t handle,
167    bus_size_t offset, uint64_t val)
168{
169
170	bus_space_write_4(tag, handle, offset, val);
171	bus_space_write_4(tag, handle, offset + 4, val >> 32);
172}
173#endif
174
175#define ntb_bar_read(SIZE, bar, offset) \
176	    bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
177	    ntb->bar_info[(bar)].pci_bus_handle, (offset))
178#define ntb_bar_write(SIZE, bar, offset, val) \
179	    bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
180	    ntb->bar_info[(bar)].pci_bus_handle, (offset), (val))
181#define ntb_reg_read(SIZE, offset) ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset)
182#define ntb_reg_write(SIZE, offset, val) \
183	    ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val)
184#define ntb_mw_read(SIZE, offset) ntb_bar_read(SIZE, NTB_B2B_BAR_2, offset)
185#define ntb_mw_write(SIZE, offset, val) \
186	    ntb_bar_write(SIZE, NTB_B2B_BAR_2, offset, val)
187
188typedef int (*bar_map_strategy)(struct ntb_softc *ntb,
189    struct ntb_pci_bar_info *bar);
190
191static int ntb_probe(device_t device);
192static int ntb_attach(device_t device);
193static int ntb_detach(device_t device);
194static int ntb_map_pci_bars(struct ntb_softc *ntb);
195static int map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy,
196    struct ntb_pci_bar_info *bar);
197static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar);
198static int map_memory_window_bar(struct ntb_softc *ntb,
199    struct ntb_pci_bar_info *bar);
200static void ntb_unmap_pci_bar(struct ntb_softc *ntb);
201static int ntb_setup_interrupts(struct ntb_softc *ntb);
202static void ntb_teardown_interrupts(struct ntb_softc *ntb);
203static void handle_soc_irq(void *arg);
204static void handle_xeon_irq(void *arg);
205static void handle_xeon_event_irq(void *arg);
206static void ntb_handle_legacy_interrupt(void *arg);
207static int ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors);
208static void ntb_free_callbacks(struct ntb_softc *ntb);
209static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id);
210static int ntb_initialize_hw(struct ntb_softc *ntb);
211static int ntb_setup_xeon(struct ntb_softc *ntb);
212static int ntb_setup_soc(struct ntb_softc *ntb);
213static void configure_soc_secondary_side_bars(struct ntb_softc *ntb);
214static void configure_xeon_secondary_side_bars(struct ntb_softc *ntb);
215static void ntb_handle_heartbeat(void *arg);
216static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state);
217static void recover_soc_link(void *arg);
218static int ntb_check_link_status(struct ntb_softc *ntb);
219static void save_bar_parameters(struct ntb_pci_bar_info *bar);
220
221static struct ntb_hw_info pci_ids[] = {
222	{ 0x0C4E8086, "Atom Processor S1200 NTB Primary B2B", NTB_SOC, 0 },
223
224	/* XXX: PS/SS IDs left out until they are supported. */
225	{ 0x37258086, "JSF Xeon C35xx/C55xx Non-Transparent Bridge B2B",
226		NTB_XEON, NTB_REGS_THRU_MW | NTB_B2BDOORBELL_BIT14 },
227	{ 0x3C0D8086, "SNB Xeon E5/Core i7 Non-Transparent Bridge B2B",
228		NTB_XEON, NTB_REGS_THRU_MW | NTB_B2BDOORBELL_BIT14 },
229	{ 0x0E0D8086, "IVT Xeon E5 V2 Non-Transparent Bridge B2B", NTB_XEON,
230		NTB_REGS_THRU_MW | NTB_B2BDOORBELL_BIT14 | NTB_SB01BASE_LOCKUP
231		    | NTB_BAR_SIZE_4K },
232	{ 0x2F0D8086, "HSX Xeon E5 V3 Non-Transparent Bridge B2B", NTB_XEON,
233		NTB_REGS_THRU_MW | NTB_B2BDOORBELL_BIT14 | NTB_SB01BASE_LOCKUP
234	},
235	{ 0x6F0D8086, "BDX Xeon E5 V4 Non-Transparent Bridge B2B", NTB_XEON,
236		NTB_REGS_THRU_MW | NTB_B2BDOORBELL_BIT14 | NTB_SB01BASE_LOCKUP
237	},
238
239	{ 0x00000000, NULL, NTB_SOC, 0 }
240};
241
242/*
243 * OS <-> Driver interface structures
244 */
245MALLOC_DEFINE(M_NTB, "ntb_hw", "ntb_hw driver memory allocations");
246
247static device_method_t ntb_pci_methods[] = {
248	/* Device interface */
249	DEVMETHOD(device_probe,     ntb_probe),
250	DEVMETHOD(device_attach,    ntb_attach),
251	DEVMETHOD(device_detach,    ntb_detach),
252	DEVMETHOD_END
253};
254
255static driver_t ntb_pci_driver = {
256	"ntb_hw",
257	ntb_pci_methods,
258	sizeof(struct ntb_softc),
259};
260
261static devclass_t ntb_devclass;
262DRIVER_MODULE(ntb_hw, pci, ntb_pci_driver, ntb_devclass, NULL, NULL);
263MODULE_VERSION(ntb_hw, 1);
264
265SYSCTL_NODE(_hw, OID_AUTO, ntb, CTLFLAG_RW, 0, "NTB sysctls");
266
267/*
268 * OS <-> Driver linkage functions
269 */
270static int
271ntb_probe(device_t device)
272{
273	struct ntb_hw_info *p;
274
275	p = ntb_get_device_info(pci_get_devid(device));
276	if (p == NULL)
277		return (ENXIO);
278
279	device_set_desc(device, p->desc);
280	return (0);
281}
282
283static int
284ntb_attach(device_t device)
285{
286	struct ntb_softc *ntb;
287	struct ntb_hw_info *p;
288	int error;
289
290	ntb = DEVICE2SOFTC(device);
291	p = ntb_get_device_info(pci_get_devid(device));
292
293	ntb->device = device;
294	ntb->type = p->type;
295	ntb->features = p->features;
296
297	/* Heartbeat timer for NTB_SOC since there is no link interrupt */
298	callout_init(&ntb->heartbeat_timer, 1);
299	callout_init(&ntb->lr_timer, 1);
300
301	error = ntb_map_pci_bars(ntb);
302	if (error)
303		goto out;
304	error = ntb_initialize_hw(ntb);
305	if (error)
306		goto out;
307	error = ntb_setup_interrupts(ntb);
308	if (error)
309		goto out;
310
311	pci_enable_busmaster(ntb->device);
312
313out:
314	if (error != 0)
315		ntb_detach(device);
316	return (error);
317}
318
319static int
320ntb_detach(device_t device)
321{
322	struct ntb_softc *ntb;
323
324	ntb = DEVICE2SOFTC(device);
325	callout_drain(&ntb->heartbeat_timer);
326	callout_drain(&ntb->lr_timer);
327	ntb_teardown_interrupts(ntb);
328	ntb_unmap_pci_bar(ntb);
329
330	return (0);
331}
332
333static int
334ntb_map_pci_bars(struct ntb_softc *ntb)
335{
336	int rc;
337
338	ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0);
339	rc = map_pci_bar(ntb, map_mmr_bar, &ntb->bar_info[NTB_CONFIG_BAR]);
340	if (rc != 0)
341		return (rc);
342
343	ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2);
344	rc = map_pci_bar(ntb, map_memory_window_bar,
345	    &ntb->bar_info[NTB_B2B_BAR_1]);
346	if (rc != 0)
347		return (rc);
348
349	ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4);
350	if (HAS_FEATURE(NTB_REGS_THRU_MW))
351		rc = map_pci_bar(ntb, map_mmr_bar,
352		    &ntb->bar_info[NTB_B2B_BAR_2]);
353	else
354		rc = map_pci_bar(ntb, map_memory_window_bar,
355		    &ntb->bar_info[NTB_B2B_BAR_2]);
356	return (rc);
357}
358
359static int
360map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy,
361    struct ntb_pci_bar_info *bar)
362{
363	int rc;
364
365	rc = strategy(ntb, bar);
366	if (rc != 0)
367		device_printf(ntb->device,
368		    "unable to allocate pci resource\n");
369	else
370		device_printf(ntb->device,
371		    "Bar size = %lx, v %p, p %p\n",
372		    bar->size, bar->vbase, (void *)(bar->pbase));
373	return (rc);
374}
375
376static int
377map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
378{
379
380	bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
381	    &bar->pci_resource_id, RF_ACTIVE);
382	if (bar->pci_resource == NULL)
383		return (ENXIO);
384
385	save_bar_parameters(bar);
386	return (0);
387}
388
389static int
390map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
391{
392	int rc;
393	uint8_t bar_size_bits = 0;
394
395	bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
396	    &bar->pci_resource_id, RF_ACTIVE);
397
398	if (bar->pci_resource == NULL)
399		return (ENXIO);
400
401	save_bar_parameters(bar);
402	/*
403	 * Ivytown NTB BAR sizes are misreported by the hardware due to a
404	 * hardware issue. To work around this, query the size it should be
405	 * configured to by the device and modify the resource to correspond to
406	 * this new size. The BIOS on systems with this problem is required to
407	 * provide enough address space to allow the driver to make this change
408	 * safely.
409	 *
410	 * Ideally I could have just specified the size when I allocated the
411	 * resource like:
412	 *  bus_alloc_resource(ntb->device,
413	 *	SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul,
414	 *	1ul << bar_size_bits, RF_ACTIVE);
415	 * but the PCI driver does not honor the size in this call, so we have
416	 * to modify it after the fact.
417	 */
418	if (HAS_FEATURE(NTB_BAR_SIZE_4K)) {
419		if (bar->pci_resource_id == PCIR_BAR(2))
420			bar_size_bits = pci_read_config(ntb->device,
421			    XEON_PBAR23SZ_OFFSET, 1);
422		else
423			bar_size_bits = pci_read_config(ntb->device,
424			    XEON_PBAR45SZ_OFFSET, 1);
425
426		rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY,
427		    bar->pci_resource, bar->pbase,
428		    bar->pbase + (1ul << bar_size_bits) - 1);
429		if (rc != 0) {
430			device_printf(ntb->device,
431			    "unable to resize bar\n");
432			return (rc);
433		}
434
435		save_bar_parameters(bar);
436	}
437
438	/* Mark bar region as write combining to improve performance. */
439	rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size,
440	    VM_MEMATTR_WRITE_COMBINING);
441	if (rc != 0) {
442		device_printf(ntb->device,
443		    "unable to mark bar as WRITE_COMBINING\n");
444		return (rc);
445	}
446	return (0);
447}
448
449static void
450ntb_unmap_pci_bar(struct ntb_softc *ntb)
451{
452	struct ntb_pci_bar_info *current_bar;
453	int i;
454
455	for (i = 0; i< NTB_MAX_BARS; i++) {
456		current_bar = &ntb->bar_info[i];
457		if (current_bar->pci_resource != NULL)
458			bus_release_resource(ntb->device, SYS_RES_MEMORY,
459			    current_bar->pci_resource_id,
460			    current_bar->pci_resource);
461	}
462}
463
464static int
465ntb_setup_interrupts(struct ntb_softc *ntb)
466{
467	void (*interrupt_handler)(void *);
468	void *int_arg;
469	bool use_msix = false;
470	uint32_t num_vectors;
471	int i;
472
473	ntb->allocated_interrupts = 0;
474	/*
475	 * On SOC, disable all interrupts.  On XEON, disable all but Link
476	 * Interrupt.  The rest will be unmasked as callbacks are registered.
477	 */
478	if (ntb->type == NTB_SOC)
479		ntb_reg_write(8, ntb->reg_ofs.ldb_mask, ~0);
480	else
481		ntb_reg_write(2, ntb->reg_ofs.ldb_mask,
482		    ~(1 << ntb->limits.max_db_bits));
483
484	num_vectors = MIN(pci_msix_count(ntb->device),
485	    ntb->limits.max_db_bits);
486	if (num_vectors >= 1) {
487		pci_alloc_msix(ntb->device, &num_vectors);
488		if (num_vectors >= 4)
489			use_msix = true;
490	}
491
492	ntb_create_callbacks(ntb, num_vectors);
493	if (use_msix == true) {
494		for (i = 0; i < num_vectors; i++) {
495			ntb->int_info[i].rid = i + 1;
496			ntb->int_info[i].res = bus_alloc_resource_any(
497			    ntb->device, SYS_RES_IRQ, &ntb->int_info[i].rid,
498			    RF_ACTIVE);
499			if (ntb->int_info[i].res == NULL) {
500				device_printf(ntb->device,
501				    "bus_alloc_resource failed\n");
502				return (ENOMEM);
503			}
504			ntb->int_info[i].tag = NULL;
505			ntb->allocated_interrupts++;
506			if (ntb->type == NTB_SOC) {
507				interrupt_handler = handle_soc_irq;
508				int_arg = &ntb->db_cb[i];
509			} else {
510				if (i == num_vectors - 1) {
511					interrupt_handler =
512					    handle_xeon_event_irq;
513					int_arg = ntb;
514				} else {
515					interrupt_handler =
516					    handle_xeon_irq;
517					int_arg = &ntb->db_cb[i];
518				}
519			}
520			if (bus_setup_intr(ntb->device, ntb->int_info[i].res,
521			    INTR_MPSAFE | INTR_TYPE_MISC, NULL,
522			    interrupt_handler, int_arg,
523			    &ntb->int_info[i].tag) != 0) {
524				device_printf(ntb->device,
525				    "bus_setup_intr failed\n");
526				return (ENXIO);
527			}
528		}
529	} else {
530		ntb->int_info[0].rid = 0;
531		ntb->int_info[0].res = bus_alloc_resource_any(ntb->device,
532		    SYS_RES_IRQ, &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE);
533		interrupt_handler = ntb_handle_legacy_interrupt;
534		if (ntb->int_info[0].res == NULL) {
535			device_printf(ntb->device,
536			    "bus_alloc_resource failed\n");
537			return (ENOMEM);
538		}
539		ntb->int_info[0].tag = NULL;
540		ntb->allocated_interrupts = 1;
541
542		if (bus_setup_intr(ntb->device, ntb->int_info[0].res,
543			INTR_MPSAFE | INTR_TYPE_MISC, NULL,
544			interrupt_handler, ntb, &ntb->int_info[0].tag) != 0) {
545
546			device_printf(ntb->device, "bus_setup_intr failed\n");
547			return (ENXIO);
548		}
549	}
550
551	return (0);
552}
553
554static void
555ntb_teardown_interrupts(struct ntb_softc *ntb)
556{
557	struct ntb_int_info *current_int;
558	int i;
559
560	for (i = 0; i < ntb->allocated_interrupts; i++) {
561		current_int = &ntb->int_info[i];
562		if (current_int->tag != NULL)
563			bus_teardown_intr(ntb->device, current_int->res,
564			    current_int->tag);
565
566		if (current_int->res != NULL)
567			bus_release_resource(ntb->device, SYS_RES_IRQ,
568			    rman_get_rid(current_int->res), current_int->res);
569	}
570
571	ntb_free_callbacks(ntb);
572	pci_release_msi(ntb->device);
573}
574
575static void
576handle_soc_irq(void *arg)
577{
578	struct ntb_db_cb *db_cb = arg;
579	struct ntb_softc *ntb = db_cb->ntb;
580
581	ntb_reg_write(8, ntb->reg_ofs.ldb, (uint64_t) 1 << db_cb->db_num);
582
583	if (db_cb->callback != NULL)
584		db_cb->callback(db_cb->data, db_cb->db_num);
585}
586
587static void
588handle_xeon_irq(void *arg)
589{
590	struct ntb_db_cb *db_cb = arg;
591	struct ntb_softc *ntb = db_cb->ntb;
592
593	/*
594	 * On Xeon, there are 16 bits in the interrupt register
595	 * but only 4 vectors.  So, 5 bits are assigned to the first 3
596	 * vectors, with the 4th having a single bit for link
597	 * interrupts.
598	 */
599	ntb_reg_write(2, ntb->reg_ofs.ldb,
600	    ((1 << ntb->bits_per_vector) - 1) <<
601	    (db_cb->db_num * ntb->bits_per_vector));
602
603	if (db_cb->callback != NULL)
604		db_cb->callback(db_cb->data, db_cb->db_num);
605}
606
607/* Since we do not have a HW doorbell in SOC, this is only used in JF/JT */
608static void
609handle_xeon_event_irq(void *arg)
610{
611	struct ntb_softc *ntb = arg;
612	int rc;
613
614	rc = ntb_check_link_status(ntb);
615	if (rc != 0)
616		device_printf(ntb->device, "Error determining link status\n");
617
618	/* bit 15 is always the link bit */
619	ntb_reg_write(2, ntb->reg_ofs.ldb, 1 << ntb->limits.max_db_bits);
620}
621
622static void
623ntb_handle_legacy_interrupt(void *arg)
624{
625	struct ntb_softc *ntb = arg;
626	unsigned int i = 0;
627	uint64_t ldb64;
628	uint16_t ldb16;
629
630	if (ntb->type == NTB_SOC) {
631		ldb64 = ntb_reg_read(8, ntb->reg_ofs.ldb);
632
633		while (ldb64) {
634			i = ffs(ldb64);
635			ldb64 &= ldb64 - 1;
636			handle_soc_irq(&ntb->db_cb[i]);
637		}
638	} else {
639		ldb16 = ntb_reg_read(2, ntb->reg_ofs.ldb);
640
641		if ((ldb16 & XEON_DB_HW_LINK) != 0) {
642			handle_xeon_event_irq(ntb);
643			ldb16 &= ~XEON_DB_HW_LINK;
644		}
645
646		while (ldb16 != 0) {
647			i = ffs(ldb16);
648			ldb16 &= ldb16 - 1;
649			handle_xeon_irq(&ntb->db_cb[i]);
650		}
651	}
652
653}
654
655static int
656ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors)
657{
658	int i;
659
660	ntb->db_cb = malloc(num_vectors * sizeof(*ntb->db_cb), M_NTB,
661	    M_ZERO | M_WAITOK);
662	for (i = 0; i < num_vectors; i++) {
663		ntb->db_cb[i].db_num = i;
664		ntb->db_cb[i].ntb = ntb;
665	}
666
667	return (0);
668}
669
670static void
671ntb_free_callbacks(struct ntb_softc *ntb)
672{
673	int i;
674
675	for (i = 0; i < ntb->limits.max_db_bits; i++)
676		ntb_unregister_db_callback(ntb, i);
677
678	free(ntb->db_cb, M_NTB);
679}
680
681static struct ntb_hw_info *
682ntb_get_device_info(uint32_t device_id)
683{
684	struct ntb_hw_info *ep = pci_ids;
685
686	while (ep->device_id) {
687		if (ep->device_id == device_id)
688			return (ep);
689		++ep;
690	}
691	return (NULL);
692}
693
694static int
695ntb_initialize_hw(struct ntb_softc *ntb)
696{
697
698	if (ntb->type == NTB_SOC)
699		return (ntb_setup_soc(ntb));
700	else
701		return (ntb_setup_xeon(ntb));
702}
703
704static int
705ntb_setup_xeon(struct ntb_softc *ntb)
706{
707	uint8_t val, connection_type;
708
709	val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1);
710
711	connection_type = val & XEON_PPD_CONN_TYPE;
712
713	if ((val & XEON_PPD_DEV_TYPE) != 0)
714		ntb->dev_type = NTB_DEV_USD;
715	else
716		ntb->dev_type = NTB_DEV_DSD;
717
718	ntb->reg_ofs.ldb	= XEON_PDOORBELL_OFFSET;
719	ntb->reg_ofs.ldb_mask	= XEON_PDBMSK_OFFSET;
720	ntb->reg_ofs.spad_local	= XEON_SPAD_OFFSET;
721	ntb->reg_ofs.bar2_xlat	= XEON_SBAR2XLAT_OFFSET;
722	ntb->reg_ofs.bar4_xlat	= XEON_SBAR4XLAT_OFFSET;
723
724	switch (connection_type) {
725	case NTB_CONN_B2B:
726		ntb->conn_type = NTB_CONN_B2B;
727
728		/*
729		 * reg_ofs.rdb and reg_ofs.spad_remote are effectively ignored
730		 * with the NTB_REGS_THRU_MW errata mode enabled.  (See
731		 * ntb_ring_doorbell() and ntb_read/write_remote_spad().)
732		 */
733		ntb->reg_ofs.rdb	 = XEON_B2B_DOORBELL_OFFSET;
734		ntb->reg_ofs.spad_remote = XEON_B2B_SPAD_OFFSET;
735
736		ntb->limits.max_spads	 = XEON_MAX_SPADS;
737		break;
738
739	case NTB_CONN_RP:
740		/*
741		 * Every Xeon today needs NTB_REGS_THRU_MW, so punt on RP for
742		 * now.
743		 */
744		KASSERT(HAS_FEATURE(NTB_REGS_THRU_MW),
745		    ("Xeon without MW errata unimplemented"));
746		device_printf(ntb->device,
747		    "NTB-RP disabled to due hardware errata.\n");
748		return (ENXIO);
749
750	case NTB_CONN_TRANSPARENT:
751	default:
752		device_printf(ntb->device, "Connection type %d not supported\n",
753		    connection_type);
754		return (ENXIO);
755	}
756
757	/*
758	 * There is a Xeon hardware errata related to writes to SDOORBELL or
759	 * B2BDOORBELL in conjunction with inbound access to NTB MMIO space,
760	 * which may hang the system.  To workaround this use the second memory
761	 * window to access the interrupt and scratch pad registers on the
762	 * remote system.
763	 */
764	if (HAS_FEATURE(NTB_REGS_THRU_MW))
765		/*
766		 * Set the Limit register to 4k, the minimum size, to prevent
767		 * an illegal access.
768		 */
769		ntb_reg_write(8, XEON_PBAR4LMT_OFFSET,
770		    ntb_get_mw_size(ntb, 1) + 0x1000);
771	else
772		/*
773		 * Disable the limit register, just in case it is set to
774		 * something silly.
775		 */
776		ntb_reg_write(8, XEON_PBAR4LMT_OFFSET, 0);
777
778
779	ntb->reg_ofs.lnk_cntl	 = XEON_NTBCNTL_OFFSET;
780	ntb->reg_ofs.lnk_stat	 = XEON_LINK_STATUS_OFFSET;
781	ntb->reg_ofs.spci_cmd	 = XEON_PCICMD_OFFSET;
782
783	ntb->limits.max_db_bits	 = XEON_MAX_DB_BITS;
784	ntb->limits.msix_cnt	 = XEON_MSIX_CNT;
785	ntb->bits_per_vector	 = XEON_DB_BITS_PER_VEC;
786
787	configure_xeon_secondary_side_bars(ntb);
788
789	/* Enable Bus Master and Memory Space on the secondary side */
790	if (ntb->conn_type == NTB_CONN_B2B)
791		ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
792		    PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
793
794	/* Enable link training */
795	ntb_reg_write(4, ntb->reg_ofs.lnk_cntl,
796	    NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP);
797
798	return (0);
799}
800
801static int
802ntb_setup_soc(struct ntb_softc *ntb)
803{
804	uint32_t val, connection_type;
805
806	val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4);
807
808	connection_type = (val & SOC_PPD_CONN_TYPE) >> 8;
809	switch (connection_type) {
810	case NTB_CONN_B2B:
811		ntb->conn_type = NTB_CONN_B2B;
812		break;
813	default:
814		device_printf(ntb->device,
815		    "Unsupported NTB configuration (%d)\n", connection_type);
816		return (ENXIO);
817	}
818
819	if ((val & SOC_PPD_DEV_TYPE) != 0)
820		ntb->dev_type = NTB_DEV_DSD;
821	else
822		ntb->dev_type = NTB_DEV_USD;
823
824	/* Initiate PCI-E link training */
825	pci_write_config(ntb->device, NTB_PPD_OFFSET, val | SOC_PPD_INIT_LINK,
826	    4);
827
828	ntb->reg_ofs.ldb	 = SOC_PDOORBELL_OFFSET;
829	ntb->reg_ofs.ldb_mask	 = SOC_PDBMSK_OFFSET;
830	ntb->reg_ofs.rdb	 = SOC_B2B_DOORBELL_OFFSET;
831	ntb->reg_ofs.bar2_xlat	 = SOC_SBAR2XLAT_OFFSET;
832	ntb->reg_ofs.bar4_xlat	 = SOC_SBAR4XLAT_OFFSET;
833	ntb->reg_ofs.lnk_cntl	 = SOC_NTBCNTL_OFFSET;
834	ntb->reg_ofs.lnk_stat	 = SOC_LINK_STATUS_OFFSET;
835	ntb->reg_ofs.spad_local	 = SOC_SPAD_OFFSET;
836	ntb->reg_ofs.spad_remote = SOC_B2B_SPAD_OFFSET;
837	ntb->reg_ofs.spci_cmd	 = SOC_PCICMD_OFFSET;
838
839	ntb->limits.max_spads	 = SOC_MAX_SPADS;
840	ntb->limits.max_db_bits	 = SOC_MAX_DB_BITS;
841	ntb->limits.msix_cnt	 = SOC_MSIX_CNT;
842	ntb->bits_per_vector	 = SOC_DB_BITS_PER_VEC;
843
844	/*
845	 * FIXME - MSI-X bug on early SOC HW, remove once internal issue is
846	 * resolved.  Mask transaction layer internal parity errors.
847	 */
848	pci_write_config(ntb->device, 0xFC, 0x4, 4);
849
850	configure_soc_secondary_side_bars(ntb);
851
852	/* Enable Bus Master and Memory Space on the secondary side */
853	ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
854	    PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
855
856	callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb);
857
858	return (0);
859}
860
861static void
862configure_soc_secondary_side_bars(struct ntb_softc *ntb)
863{
864
865	if (ntb->dev_type == NTB_DEV_USD) {
866		ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR);
867		ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_USD_ADDR);
868		ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_USD_ADDR);
869		ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_USD_ADDR);
870	} else {
871		ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR);
872		ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_DSD_ADDR);
873		ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_DSD_ADDR);
874		ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_DSD_ADDR);
875	}
876}
877
878static void
879configure_xeon_secondary_side_bars(struct ntb_softc *ntb)
880{
881
882	if (ntb->dev_type == NTB_DEV_USD) {
883		ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR);
884		if (HAS_FEATURE(NTB_REGS_THRU_MW))
885			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
886			    MBAR01_DSD_ADDR);
887		else {
888			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
889			    PBAR4XLAT_USD_ADDR);
890			/*
891			 * B2B_XLAT_OFFSET is a 64-bit register but can only be
892			 * written 32 bits at a time.
893			 */
894			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETL,
895			    MBAR01_DSD_ADDR & 0xffffffff);
896			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETU,
897			    MBAR01_DSD_ADDR >> 32);
898		}
899		ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_USD_ADDR);
900		ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_USD_ADDR);
901		ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_USD_ADDR);
902	} else {
903		ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR);
904		if (HAS_FEATURE(NTB_REGS_THRU_MW))
905			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
906			    MBAR01_USD_ADDR);
907		else {
908			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
909			    PBAR4XLAT_DSD_ADDR);
910			/*
911			 * B2B_XLAT_OFFSET is a 64-bit register but can only be
912			 * written 32 bits at a time.
913			 */
914			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETL,
915			    MBAR01_USD_ADDR & 0xffffffff);
916			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETU,
917			    MBAR01_USD_ADDR >> 32);
918		}
919		ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_DSD_ADDR);
920		ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_DSD_ADDR);
921		ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_DSD_ADDR);
922	}
923}
924
925/* SOC does not have link status interrupt, poll on that platform */
926static void
927ntb_handle_heartbeat(void *arg)
928{
929	struct ntb_softc *ntb = arg;
930	uint32_t status32;
931	int rc;
932
933	rc = ntb_check_link_status(ntb);
934	if (rc != 0)
935		device_printf(ntb->device,
936		    "Error determining link status\n");
937
938	/* Check to see if a link error is the cause of the link down */
939	if (ntb->link_status == NTB_LINK_DOWN) {
940		status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
941		if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) {
942			callout_reset(&ntb->lr_timer, 0, recover_soc_link,
943			    ntb);
944			return;
945		}
946	}
947
948	callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
949	    ntb_handle_heartbeat, ntb);
950}
951
952static void
953soc_perform_link_restart(struct ntb_softc *ntb)
954{
955	uint32_t status;
956
957	/* Driver resets the NTB ModPhy lanes - magic! */
958	ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0xe0);
959	ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x40);
960	ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x60);
961	ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0x60);
962
963	/* Driver waits 100ms to allow the NTB ModPhy to settle */
964	pause("ModPhy", hz / 10);
965
966	/* Clear AER Errors, write to clear */
967	status = ntb_reg_read(4, SOC_ERRCORSTS_OFFSET);
968	status &= PCIM_AER_COR_REPLAY_ROLLOVER;
969	ntb_reg_write(4, SOC_ERRCORSTS_OFFSET, status);
970
971	/* Clear unexpected electrical idle event in LTSSM, write to clear */
972	status = ntb_reg_read(4, SOC_LTSSMERRSTS0_OFFSET);
973	status |= SOC_LTSSMERRSTS0_UNEXPECTEDEI;
974	ntb_reg_write(4, SOC_LTSSMERRSTS0_OFFSET, status);
975
976	/* Clear DeSkew Buffer error, write to clear */
977	status = ntb_reg_read(4, SOC_DESKEWSTS_OFFSET);
978	status |= SOC_DESKEWSTS_DBERR;
979	ntb_reg_write(4, SOC_DESKEWSTS_OFFSET, status);
980
981	status = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET);
982	status &= SOC_IBIST_ERR_OFLOW;
983	ntb_reg_write(4, SOC_IBSTERRRCRVSTS0_OFFSET, status);
984
985	/* Releases the NTB state machine to allow the link to retrain */
986	status = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
987	status &= ~SOC_LTSSMSTATEJMP_FORCEDETECT;
988	ntb_reg_write(4, SOC_LTSSMSTATEJMP_OFFSET, status);
989}
990
991static void
992ntb_handle_link_event(struct ntb_softc *ntb, int link_state)
993{
994	enum ntb_hw_event event;
995	uint16_t status;
996
997	if (ntb->link_status == link_state)
998		return;
999
1000	if (link_state == NTB_LINK_UP) {
1001		device_printf(ntb->device, "Link Up\n");
1002		ntb->link_status = NTB_LINK_UP;
1003		event = NTB_EVENT_HW_LINK_UP;
1004
1005		if (ntb->type == NTB_SOC ||
1006		    ntb->conn_type == NTB_CONN_TRANSPARENT)
1007			status = ntb_reg_read(2, ntb->reg_ofs.lnk_stat);
1008		else
1009			status = pci_read_config(ntb->device,
1010			    XEON_LINK_STATUS_OFFSET, 2);
1011		ntb->link_width = (status & NTB_LINK_WIDTH_MASK) >> 4;
1012		ntb->link_speed = (status & NTB_LINK_SPEED_MASK);
1013		device_printf(ntb->device, "Link Width %d, Link Speed %d\n",
1014		    ntb->link_width, ntb->link_speed);
1015		callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
1016		    ntb_handle_heartbeat, ntb);
1017	} else {
1018		device_printf(ntb->device, "Link Down\n");
1019		ntb->link_status = NTB_LINK_DOWN;
1020		event = NTB_EVENT_HW_LINK_DOWN;
1021		/* Do not modify link width/speed, we need it in link recovery */
1022	}
1023
1024	/* notify the upper layer if we have an event change */
1025	if (ntb->event_cb != NULL)
1026		ntb->event_cb(ntb->ntb_transport, event);
1027}
1028
1029static void
1030recover_soc_link(void *arg)
1031{
1032	struct ntb_softc *ntb = arg;
1033	uint8_t speed, width;
1034	uint32_t status32;
1035	uint16_t status16;
1036
1037	soc_perform_link_restart(ntb);
1038
1039	/*
1040	 * There is a potential race between the 2 NTB devices recovering at
1041	 * the same time.  If the times are the same, the link will not recover
1042	 * and the driver will be stuck in this loop forever.  Add a random
1043	 * interval to the recovery time to prevent this race.
1044	 */
1045	status32 = arc4random() % SOC_LINK_RECOVERY_TIME;
1046	pause("Link", (SOC_LINK_RECOVERY_TIME + status32) * hz / 1000);
1047
1048	status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
1049	if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0)
1050		goto retry;
1051
1052	status32 = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET);
1053	if ((status32 & SOC_IBIST_ERR_OFLOW) != 0)
1054		goto retry;
1055
1056	status32 = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl);
1057	if ((status32 & SOC_CNTL_LINK_DOWN) != 0)
1058		goto out;
1059
1060	status16 = ntb_reg_read(2, ntb->reg_ofs.lnk_stat);
1061	width = (status16 & NTB_LINK_WIDTH_MASK) >> 4;
1062	speed = (status16 & NTB_LINK_SPEED_MASK);
1063	if (ntb->link_width != width || ntb->link_speed != speed)
1064		goto retry;
1065
1066out:
1067	callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
1068	    ntb_handle_heartbeat, ntb);
1069	return;
1070
1071retry:
1072	callout_reset(&ntb->lr_timer, NTB_HB_TIMEOUT * hz, recover_soc_link,
1073	    ntb);
1074}
1075
1076static int
1077ntb_check_link_status(struct ntb_softc *ntb)
1078{
1079	int link_state;
1080	uint32_t ntb_cntl;
1081	uint16_t status;
1082
1083	if (ntb->type == NTB_SOC) {
1084		ntb_cntl = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl);
1085		if ((ntb_cntl & SOC_CNTL_LINK_DOWN) != 0)
1086			link_state = NTB_LINK_DOWN;
1087		else
1088			link_state = NTB_LINK_UP;
1089	} else {
1090		status = pci_read_config(ntb->device, XEON_LINK_STATUS_OFFSET,
1091		    2);
1092
1093		if ((status & NTB_LINK_STATUS_ACTIVE) != 0)
1094			link_state = NTB_LINK_UP;
1095		else
1096			link_state = NTB_LINK_DOWN;
1097	}
1098
1099	ntb_handle_link_event(ntb, link_state);
1100
1101	return (0);
1102}
1103
1104/**
1105 * ntb_register_event_callback() - register event callback
1106 * @ntb: pointer to ntb_softc instance
1107 * @func: callback function to register
1108 *
1109 * This function registers a callback for any HW driver events such as link
1110 * up/down, power management notices and etc.
1111 *
1112 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1113 */
1114int
1115ntb_register_event_callback(struct ntb_softc *ntb, ntb_event_callback func)
1116{
1117
1118	if (ntb->event_cb != NULL)
1119		return (EINVAL);
1120
1121	ntb->event_cb = func;
1122
1123	return (0);
1124}
1125
1126/**
1127 * ntb_unregister_event_callback() - unregisters the event callback
1128 * @ntb: pointer to ntb_softc instance
1129 *
1130 * This function unregisters the existing callback from transport
1131 */
1132void
1133ntb_unregister_event_callback(struct ntb_softc *ntb)
1134{
1135
1136	ntb->event_cb = NULL;
1137}
1138
1139/**
1140 * ntb_register_db_callback() - register a callback for doorbell interrupt
1141 * @ntb: pointer to ntb_softc instance
1142 * @idx: doorbell index to register callback, zero based
1143 * @func: callback function to register
1144 *
1145 * This function registers a callback function for the doorbell interrupt
1146 * on the primary side. The function will unmask the doorbell as well to
1147 * allow interrupt.
1148 *
1149 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1150 */
1151int
1152ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data,
1153    ntb_db_callback func)
1154{
1155	uint16_t mask;
1156
1157	if (idx >= ntb->allocated_interrupts || ntb->db_cb[idx].callback) {
1158		device_printf(ntb->device, "Invalid Index.\n");
1159		return (EINVAL);
1160	}
1161
1162	ntb->db_cb[idx].callback = func;
1163	ntb->db_cb[idx].data = data;
1164
1165	/* unmask interrupt */
1166	mask = ntb_reg_read(2, ntb->reg_ofs.ldb_mask);
1167	mask &= ~(1 << (idx * ntb->bits_per_vector));
1168	ntb_reg_write(2, ntb->reg_ofs.ldb_mask, mask);
1169
1170	return (0);
1171}
1172
1173/**
1174 * ntb_unregister_db_callback() - unregister a callback for doorbell interrupt
1175 * @ntb: pointer to ntb_softc instance
1176 * @idx: doorbell index to register callback, zero based
1177 *
1178 * This function unregisters a callback function for the doorbell interrupt
1179 * on the primary side. The function will also mask the said doorbell.
1180 */
1181void
1182ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx)
1183{
1184	unsigned long mask;
1185
1186	if (idx >= ntb->allocated_interrupts || !ntb->db_cb[idx].callback)
1187		return;
1188
1189	mask = ntb_reg_read(2, ntb->reg_ofs.ldb_mask);
1190	mask |= 1 << (idx * ntb->bits_per_vector);
1191	ntb_reg_write(2, ntb->reg_ofs.ldb_mask, mask);
1192
1193	ntb->db_cb[idx].callback = NULL;
1194}
1195
1196/**
1197 * ntb_find_transport() - find the transport pointer
1198 * @transport: pointer to pci device
1199 *
1200 * Given the pci device pointer, return the transport pointer passed in when
1201 * the transport attached when it was inited.
1202 *
1203 * RETURNS: pointer to transport.
1204 */
1205void *
1206ntb_find_transport(struct ntb_softc *ntb)
1207{
1208
1209	return (ntb->ntb_transport);
1210}
1211
1212/**
1213 * ntb_register_transport() - Register NTB transport with NTB HW driver
1214 * @transport: transport identifier
1215 *
1216 * This function allows a transport to reserve the hardware driver for
1217 * NTB usage.
1218 *
1219 * RETURNS: pointer to ntb_softc, NULL on error.
1220 */
1221struct ntb_softc *
1222ntb_register_transport(struct ntb_softc *ntb, void *transport)
1223{
1224
1225	/*
1226	 * TODO: when we have more than one transport, we will need to rewrite
1227	 * this to prevent race conditions
1228	 */
1229	if (ntb->ntb_transport != NULL)
1230		return (NULL);
1231
1232	ntb->ntb_transport = transport;
1233	return (ntb);
1234}
1235
1236/**
1237 * ntb_unregister_transport() - Unregister the transport with the NTB HW driver
1238 * @ntb - ntb_softc of the transport to be freed
1239 *
1240 * This function unregisters the transport from the HW driver and performs any
1241 * necessary cleanups.
1242 */
1243void
1244ntb_unregister_transport(struct ntb_softc *ntb)
1245{
1246	int i;
1247
1248	if (ntb->ntb_transport == NULL)
1249		return;
1250
1251	for (i = 0; i < ntb->allocated_interrupts; i++)
1252		ntb_unregister_db_callback(ntb, i);
1253
1254	ntb_unregister_event_callback(ntb);
1255	ntb->ntb_transport = NULL;
1256}
1257
1258/**
1259 * ntb_get_max_spads() - get the total scratch regs usable
1260 * @ntb: pointer to ntb_softc instance
1261 *
1262 * This function returns the max 32bit scratchpad registers usable by the
1263 * upper layer.
1264 *
1265 * RETURNS: total number of scratch pad registers available
1266 */
1267uint8_t
1268ntb_get_max_spads(struct ntb_softc *ntb)
1269{
1270
1271	return (ntb->limits.max_spads);
1272}
1273
1274/**
1275 * ntb_write_local_spad() - write to the secondary scratchpad register
1276 * @ntb: pointer to ntb_softc instance
1277 * @idx: index to the scratchpad register, 0 based
1278 * @val: the data value to put into the register
1279 *
1280 * This function allows writing of a 32bit value to the indexed scratchpad
1281 * register. The register resides on the secondary (external) side.
1282 *
1283 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1284 */
1285int
1286ntb_write_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val)
1287{
1288
1289	if (idx >= ntb->limits.max_spads)
1290		return (EINVAL);
1291
1292	ntb_reg_write(4, ntb->reg_ofs.spad_local + idx * 4, val);
1293
1294	return (0);
1295}
1296
1297/**
1298 * ntb_read_local_spad() - read from the primary scratchpad register
1299 * @ntb: pointer to ntb_softc instance
1300 * @idx: index to scratchpad register, 0 based
1301 * @val: pointer to 32bit integer for storing the register value
1302 *
1303 * This function allows reading of the 32bit scratchpad register on
1304 * the primary (internal) side.
1305 *
1306 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1307 */
1308int
1309ntb_read_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val)
1310{
1311
1312	if (idx >= ntb->limits.max_spads)
1313		return (EINVAL);
1314
1315	*val = ntb_reg_read(4, ntb->reg_ofs.spad_local + idx * 4);
1316
1317	return (0);
1318}
1319
1320/**
1321 * ntb_write_remote_spad() - write to the secondary scratchpad register
1322 * @ntb: pointer to ntb_softc instance
1323 * @idx: index to the scratchpad register, 0 based
1324 * @val: the data value to put into the register
1325 *
1326 * This function allows writing of a 32bit value to the indexed scratchpad
1327 * register. The register resides on the secondary (external) side.
1328 *
1329 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1330 */
1331int
1332ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val)
1333{
1334
1335	if (idx >= ntb->limits.max_spads)
1336		return (EINVAL);
1337
1338	if (HAS_FEATURE(NTB_REGS_THRU_MW))
1339		ntb_mw_write(4, XEON_SHADOW_SPAD_OFFSET + idx * 4, val);
1340	else
1341		ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val);
1342
1343	return (0);
1344}
1345
1346/**
1347 * ntb_read_remote_spad() - read from the primary scratchpad register
1348 * @ntb: pointer to ntb_softc instance
1349 * @idx: index to scratchpad register, 0 based
1350 * @val: pointer to 32bit integer for storing the register value
1351 *
1352 * This function allows reading of the 32bit scratchpad register on
1353 * the primary (internal) side.
1354 *
1355 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1356 */
1357int
1358ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val)
1359{
1360
1361	if (idx >= ntb->limits.max_spads)
1362		return (EINVAL);
1363
1364	if (HAS_FEATURE(NTB_REGS_THRU_MW))
1365		*val = ntb_mw_read(4, XEON_SHADOW_SPAD_OFFSET + idx * 4);
1366	else
1367		*val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4);
1368
1369	return (0);
1370}
1371
1372/**
1373 * ntb_get_mw_vbase() - get virtual addr for the NTB memory window
1374 * @ntb: pointer to ntb_softc instance
1375 * @mw: memory window number
1376 *
1377 * This function provides the base virtual address of the memory window
1378 * specified.
1379 *
1380 * RETURNS: pointer to virtual address, or NULL on error.
1381 */
1382void *
1383ntb_get_mw_vbase(struct ntb_softc *ntb, unsigned int mw)
1384{
1385
1386	if (mw >= NTB_NUM_MW)
1387		return (NULL);
1388
1389	return (ntb->bar_info[NTB_MW_TO_BAR(mw)].vbase);
1390}
1391
1392vm_paddr_t
1393ntb_get_mw_pbase(struct ntb_softc *ntb, unsigned int mw)
1394{
1395
1396	if (mw >= NTB_NUM_MW)
1397		return (0);
1398
1399	return (ntb->bar_info[NTB_MW_TO_BAR(mw)].pbase);
1400}
1401
1402/**
1403 * ntb_get_mw_size() - return size of NTB memory window
1404 * @ntb: pointer to ntb_softc instance
1405 * @mw: memory window number
1406 *
1407 * This function provides the physical size of the memory window specified
1408 *
1409 * RETURNS: the size of the memory window or zero on error
1410 */
1411u_long
1412ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw)
1413{
1414
1415	if (mw >= NTB_NUM_MW)
1416		return (0);
1417
1418	return (ntb->bar_info[NTB_MW_TO_BAR(mw)].size);
1419}
1420
1421/**
1422 * ntb_set_mw_addr - set the memory window address
1423 * @ntb: pointer to ntb_softc instance
1424 * @mw: memory window number
1425 * @addr: base address for data
1426 *
1427 * This function sets the base physical address of the memory window.  This
1428 * memory address is where data from the remote system will be transfered into
1429 * or out of depending on how the transport is configured.
1430 */
1431void
1432ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr)
1433{
1434
1435	if (mw >= NTB_NUM_MW)
1436		return;
1437
1438	switch (NTB_MW_TO_BAR(mw)) {
1439	case NTB_B2B_BAR_1:
1440		ntb_reg_write(8, ntb->reg_ofs.bar2_xlat, addr);
1441		break;
1442	case NTB_B2B_BAR_2:
1443		ntb_reg_write(8, ntb->reg_ofs.bar4_xlat, addr);
1444		break;
1445	}
1446}
1447
1448/**
1449 * ntb_ring_doorbell() - Set the doorbell on the secondary/external side
1450 * @ntb: pointer to ntb_softc instance
1451 * @db: doorbell to ring
1452 *
1453 * This function allows triggering of a doorbell on the secondary/external
1454 * side that will initiate an interrupt on the remote host
1455 *
1456 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1457 */
1458void
1459ntb_ring_doorbell(struct ntb_softc *ntb, unsigned int db)
1460{
1461
1462	if (ntb->type == NTB_SOC)
1463		ntb_reg_write(8, ntb->reg_ofs.rdb, (uint64_t) 1 << db);
1464	else {
1465		if (HAS_FEATURE(NTB_REGS_THRU_MW))
1466			ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET,
1467			    ((1 << ntb->bits_per_vector) - 1) <<
1468			    (db * ntb->bits_per_vector));
1469		else
1470			ntb_reg_write(2, ntb->reg_ofs.rdb,
1471			    ((1 << ntb->bits_per_vector) - 1) <<
1472			    (db * ntb->bits_per_vector));
1473	}
1474}
1475
1476/**
1477 * ntb_query_link_status() - return the hardware link status
1478 * @ndev: pointer to ntb_device instance
1479 *
1480 * Returns true if the hardware is connected to the remote system
1481 *
1482 * RETURNS: true or false based on the hardware link state
1483 */
1484bool
1485ntb_query_link_status(struct ntb_softc *ntb)
1486{
1487
1488	return (ntb->link_status == NTB_LINK_UP);
1489}
1490
1491static void
1492save_bar_parameters(struct ntb_pci_bar_info *bar)
1493{
1494
1495	bar->pci_bus_tag = rman_get_bustag(bar->pci_resource);
1496	bar->pci_bus_handle = rman_get_bushandle(bar->pci_resource);
1497	bar->pbase = rman_get_start(bar->pci_resource);
1498	bar->size = rman_get_size(bar->pci_resource);
1499	bar->vbase = rman_get_virtual(bar->pci_resource);
1500}
1501
1502device_t
1503ntb_get_device(struct ntb_softc *ntb)
1504{
1505
1506	return (ntb->device);
1507}
1508
1509/* Export HW-specific errata information. */
1510bool
1511ntb_has_feature(struct ntb_softc *ntb, uint64_t feature)
1512{
1513
1514	return (HAS_FEATURE(feature));
1515}
1516