ntb_hw_intel.c revision 289539
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 289539 2015-10-18 20:19:53Z 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 MAX_MSIX_INTERRUPTS MAX(XEON_DB_COUNT, SOC_DB_COUNT)
63
64#define NTB_HB_TIMEOUT		1 /* second */
65#define SOC_LINK_RECOVERY_TIME	500 /* ms */
66
67#define DEVICE2SOFTC(dev) ((struct ntb_softc *) device_get_softc(dev))
68
69enum ntb_device_type {
70	NTB_XEON,
71	NTB_SOC
72};
73
74enum ntb_bar {
75	NTB_CONFIG_BAR = 0,
76	NTB_B2B_BAR_1,
77	NTB_B2B_BAR_2,
78	NTB_B2B_BAR_3,
79	NTB_MAX_BARS
80};
81
82/* Device features and workarounds */
83#define HAS_FEATURE(feature)	\
84	((ntb->features & (feature)) != 0)
85
86struct ntb_hw_info {
87	uint32_t		device_id;
88	const char		*desc;
89	enum ntb_device_type	type;
90	uint32_t		features;
91};
92
93struct ntb_pci_bar_info {
94	bus_space_tag_t		pci_bus_tag;
95	bus_space_handle_t	pci_bus_handle;
96	int			pci_resource_id;
97	struct resource		*pci_resource;
98	vm_paddr_t		pbase;
99	void			*vbase;
100	u_long			size;
101};
102
103struct ntb_int_info {
104	struct resource	*res;
105	int		rid;
106	void		*tag;
107};
108
109struct ntb_db_cb {
110	ntb_db_callback		callback;
111	unsigned int		db_num;
112	void			*data;
113	struct ntb_softc	*ntb;
114	struct callout		irq_work;
115	bool			reserved;
116};
117
118struct ntb_softc {
119	device_t		device;
120	enum ntb_device_type	type;
121	uint64_t		features;
122
123	struct ntb_pci_bar_info	bar_info[NTB_MAX_BARS];
124	struct ntb_int_info	int_info[MAX_MSIX_INTERRUPTS];
125	uint32_t		allocated_interrupts;
126
127	struct callout		heartbeat_timer;
128	struct callout		lr_timer;
129
130	void			*ntb_transport;
131	ntb_event_callback	event_cb;
132	struct ntb_db_cb	*db_cb;
133	uint8_t			max_cbs;
134
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 bar5_xlat;
142		uint32_t spad_remote;
143		uint32_t spad_local;
144		uint32_t lnk_cntl;
145		uint32_t lnk_stat;
146		uint32_t spci_cmd;
147	} reg_ofs;
148	uint32_t ppd;
149	uint8_t conn_type;
150	uint8_t dev_type;
151	uint8_t link_status;
152	uint8_t link_width;
153	uint8_t link_speed;
154
155	uint8_t				mw_count;
156	uint8_t				spad_count;
157	uint8_t				db_count;
158	uint8_t				db_vec_count;
159	uint8_t				db_vec_shift;
160};
161
162#ifdef __i386__
163static __inline uint64_t
164bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
165    bus_size_t offset)
166{
167
168	return (bus_space_read_4(tag, handle, offset) |
169	    ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32);
170}
171
172static __inline void
173bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t handle,
174    bus_size_t offset, uint64_t val)
175{
176
177	bus_space_write_4(tag, handle, offset, val);
178	bus_space_write_4(tag, handle, offset + 4, val >> 32);
179}
180#endif
181
182#define ntb_bar_read(SIZE, bar, offset) \
183	    bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
184	    ntb->bar_info[(bar)].pci_bus_handle, (offset))
185#define ntb_bar_write(SIZE, bar, offset, val) \
186	    bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
187	    ntb->bar_info[(bar)].pci_bus_handle, (offset), (val))
188#define ntb_reg_read(SIZE, offset) ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset)
189#define ntb_reg_write(SIZE, offset, val) \
190	    ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val)
191#define ntb_mw_read(SIZE, offset) \
192	    ntb_bar_read(SIZE, ntb_mw_to_bar(ntb, ntb->mw_count), offset)
193#define ntb_mw_write(SIZE, offset, val) \
194	    ntb_bar_write(SIZE, ntb_mw_to_bar(ntb, ntb->mw_count), \
195		offset, val)
196
197typedef int (*bar_map_strategy)(struct ntb_softc *ntb,
198    struct ntb_pci_bar_info *bar);
199
200static int ntb_probe(device_t device);
201static int ntb_attach(device_t device);
202static int ntb_detach(device_t device);
203static inline enum ntb_bar ntb_mw_to_bar(struct ntb_softc *, unsigned mw);
204static int ntb_map_pci_bars(struct ntb_softc *ntb);
205static int map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy,
206    struct ntb_pci_bar_info *bar);
207static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar);
208static int map_memory_window_bar(struct ntb_softc *ntb,
209    struct ntb_pci_bar_info *bar);
210static void ntb_unmap_pci_bar(struct ntb_softc *ntb);
211static int ntb_remap_msix(device_t, uint32_t desired, uint32_t avail);
212static int ntb_setup_interrupts(struct ntb_softc *ntb);
213static int ntb_setup_legacy_interrupt(struct ntb_softc *ntb);
214static int ntb_setup_xeon_msix(struct ntb_softc *ntb, uint32_t num_vectors);
215static int ntb_setup_soc_msix(struct ntb_softc *ntb, uint32_t num_vectors);
216static void ntb_teardown_interrupts(struct ntb_softc *ntb);
217static void handle_soc_irq(void *arg);
218static void handle_xeon_irq(void *arg);
219static void handle_xeon_event_irq(void *arg);
220static void ntb_handle_legacy_interrupt(void *arg);
221static void ntb_irq_work(void *arg);
222static inline uint64_t ntb_db_read(struct ntb_softc *, uint64_t regoff);
223static inline void ntb_db_write(struct ntb_softc *, uint64_t regoff, uint64_t val);
224static inline void mask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx);
225static inline void unmask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx);
226static int ntb_create_callbacks(struct ntb_softc *ntb, uint32_t num_vectors);
227static void ntb_free_callbacks(struct ntb_softc *ntb);
228static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id);
229static void ntb_detect_max_mw(struct ntb_softc *ntb);
230static int ntb_detect_xeon(struct ntb_softc *ntb);
231static int ntb_detect_soc(struct ntb_softc *ntb);
232static int ntb_setup_xeon(struct ntb_softc *ntb);
233static int ntb_setup_soc(struct ntb_softc *ntb);
234static void ntb_teardown_xeon(struct ntb_softc *ntb);
235static void configure_soc_secondary_side_bars(struct ntb_softc *ntb);
236static void configure_xeon_secondary_side_bars(struct ntb_softc *ntb);
237static void ntb_handle_heartbeat(void *arg);
238static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state);
239static void ntb_hw_link_down(struct ntb_softc *ntb);
240static void ntb_hw_link_up(struct ntb_softc *ntb);
241static void recover_soc_link(void *arg);
242static int ntb_check_link_status(struct ntb_softc *ntb);
243static void save_bar_parameters(struct ntb_pci_bar_info *bar);
244
245static struct ntb_hw_info pci_ids[] = {
246	{ 0x0C4E8086, "Atom Processor S1200 NTB Primary B2B", NTB_SOC, 0 },
247
248	/* XXX: PS/SS IDs left out until they are supported. */
249	{ 0x37258086, "JSF Xeon C35xx/C55xx Non-Transparent Bridge B2B",
250		NTB_XEON, NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 },
251	{ 0x3C0D8086, "SNB Xeon E5/Core i7 Non-Transparent Bridge B2B",
252		NTB_XEON, NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 },
253	{ 0x0E0D8086, "IVT Xeon E5 V2 Non-Transparent Bridge B2B", NTB_XEON,
254		NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 |
255		    NTB_SB01BASE_LOCKUP | NTB_BAR_SIZE_4K },
256	{ 0x2F0D8086, "HSX Xeon E5 V3 Non-Transparent Bridge B2B", NTB_XEON,
257		NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 |
258		    NTB_SB01BASE_LOCKUP },
259	{ 0x6F0D8086, "BDX Xeon E5 V4 Non-Transparent Bridge B2B", NTB_XEON,
260		NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 |
261		    NTB_SB01BASE_LOCKUP },
262
263	{ 0x00000000, NULL, NTB_SOC, 0 }
264};
265
266/*
267 * OS <-> Driver interface structures
268 */
269MALLOC_DEFINE(M_NTB, "ntb_hw", "ntb_hw driver memory allocations");
270
271static device_method_t ntb_pci_methods[] = {
272	/* Device interface */
273	DEVMETHOD(device_probe,     ntb_probe),
274	DEVMETHOD(device_attach,    ntb_attach),
275	DEVMETHOD(device_detach,    ntb_detach),
276	DEVMETHOD_END
277};
278
279static driver_t ntb_pci_driver = {
280	"ntb_hw",
281	ntb_pci_methods,
282	sizeof(struct ntb_softc),
283};
284
285static devclass_t ntb_devclass;
286DRIVER_MODULE(ntb_hw, pci, ntb_pci_driver, ntb_devclass, NULL, NULL);
287MODULE_VERSION(ntb_hw, 1);
288
289SYSCTL_NODE(_hw, OID_AUTO, ntb, CTLFLAG_RW, 0, "NTB sysctls");
290
291/*
292 * OS <-> Driver linkage functions
293 */
294static int
295ntb_probe(device_t device)
296{
297	struct ntb_hw_info *p;
298
299	p = ntb_get_device_info(pci_get_devid(device));
300	if (p == NULL)
301		return (ENXIO);
302
303	device_set_desc(device, p->desc);
304	return (0);
305}
306
307static int
308ntb_attach(device_t device)
309{
310	struct ntb_softc *ntb;
311	struct ntb_hw_info *p;
312	int error;
313
314	ntb = DEVICE2SOFTC(device);
315	p = ntb_get_device_info(pci_get_devid(device));
316
317	ntb->device = device;
318	ntb->type = p->type;
319	ntb->features = p->features;
320
321	/* Heartbeat timer for NTB_SOC since there is no link interrupt */
322	callout_init(&ntb->heartbeat_timer, 1);
323	callout_init(&ntb->lr_timer, 1);
324
325	if (ntb->type == NTB_SOC)
326		error = ntb_detect_soc(ntb);
327	else
328		error = ntb_detect_xeon(ntb);
329	if (error)
330		goto out;
331
332	ntb_detect_max_mw(ntb);
333
334	error = ntb_map_pci_bars(ntb);
335	if (error)
336		goto out;
337	if (ntb->type == NTB_SOC)
338		error = ntb_setup_soc(ntb);
339	else
340		error = ntb_setup_xeon(ntb);
341	if (error)
342		goto out;
343	error = ntb_setup_interrupts(ntb);
344	if (error)
345		goto out;
346
347	pci_enable_busmaster(ntb->device);
348
349out:
350	if (error != 0)
351		ntb_detach(device);
352	return (error);
353}
354
355static int
356ntb_detach(device_t device)
357{
358	struct ntb_softc *ntb;
359
360	ntb = DEVICE2SOFTC(device);
361	callout_drain(&ntb->heartbeat_timer);
362	callout_drain(&ntb->lr_timer);
363	if (ntb->type == NTB_XEON)
364		ntb_teardown_xeon(ntb);
365	ntb_teardown_interrupts(ntb);
366
367	/*
368	 * Redetect total MWs so we unmap properly -- in case we lowered the
369	 * maximum to work around Xeon errata.
370	 */
371	ntb_detect_max_mw(ntb);
372	ntb_unmap_pci_bar(ntb);
373
374	return (0);
375}
376
377static inline enum ntb_bar
378ntb_mw_to_bar(struct ntb_softc *ntb, unsigned mw)
379{
380
381	KASSERT(mw < ntb->mw_count, ("%s: mw:%u > count:%u", __func__, mw,
382	    (unsigned)ntb->mw_count));
383
384	return (NTB_B2B_BAR_1 + mw);
385}
386
387static int
388ntb_map_pci_bars(struct ntb_softc *ntb)
389{
390	int rc;
391
392	ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0);
393	rc = map_pci_bar(ntb, map_mmr_bar, &ntb->bar_info[NTB_CONFIG_BAR]);
394	if (rc != 0)
395		return (rc);
396
397	ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2);
398	rc = map_pci_bar(ntb, map_memory_window_bar,
399	    &ntb->bar_info[NTB_B2B_BAR_1]);
400	if (rc != 0)
401		return (rc);
402
403	ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4);
404	if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP) && !HAS_FEATURE(NTB_SPLIT_BAR))
405		rc = map_pci_bar(ntb, map_mmr_bar,
406		    &ntb->bar_info[NTB_B2B_BAR_2]);
407	else
408		rc = map_pci_bar(ntb, map_memory_window_bar,
409		    &ntb->bar_info[NTB_B2B_BAR_2]);
410	if (!HAS_FEATURE(NTB_SPLIT_BAR))
411		return (rc);
412
413	ntb->bar_info[NTB_B2B_BAR_3].pci_resource_id = PCIR_BAR(5);
414	if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP))
415		rc = map_pci_bar(ntb, map_mmr_bar,
416		    &ntb->bar_info[NTB_B2B_BAR_3]);
417	else
418		rc = map_pci_bar(ntb, map_memory_window_bar,
419		    &ntb->bar_info[NTB_B2B_BAR_3]);
420	return (rc);
421}
422
423static int
424map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy,
425    struct ntb_pci_bar_info *bar)
426{
427	int rc;
428
429	rc = strategy(ntb, bar);
430	if (rc != 0)
431		device_printf(ntb->device,
432		    "unable to allocate pci resource\n");
433	else
434		device_printf(ntb->device,
435		    "Bar size = %lx, v %p, p %p\n",
436		    bar->size, bar->vbase, (void *)(bar->pbase));
437	return (rc);
438}
439
440static int
441map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
442{
443
444	bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
445	    &bar->pci_resource_id, RF_ACTIVE);
446	if (bar->pci_resource == NULL)
447		return (ENXIO);
448
449	save_bar_parameters(bar);
450	return (0);
451}
452
453static int
454map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
455{
456	int rc;
457	uint8_t bar_size_bits = 0;
458
459	bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
460	    &bar->pci_resource_id, RF_ACTIVE);
461
462	if (bar->pci_resource == NULL)
463		return (ENXIO);
464
465	save_bar_parameters(bar);
466	/*
467	 * Ivytown NTB BAR sizes are misreported by the hardware due to a
468	 * hardware issue. To work around this, query the size it should be
469	 * configured to by the device and modify the resource to correspond to
470	 * this new size. The BIOS on systems with this problem is required to
471	 * provide enough address space to allow the driver to make this change
472	 * safely.
473	 *
474	 * Ideally I could have just specified the size when I allocated the
475	 * resource like:
476	 *  bus_alloc_resource(ntb->device,
477	 *	SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul,
478	 *	1ul << bar_size_bits, RF_ACTIVE);
479	 * but the PCI driver does not honor the size in this call, so we have
480	 * to modify it after the fact.
481	 */
482	if (HAS_FEATURE(NTB_BAR_SIZE_4K)) {
483		if (bar->pci_resource_id == PCIR_BAR(2))
484			bar_size_bits = pci_read_config(ntb->device,
485			    XEON_PBAR23SZ_OFFSET, 1);
486		else
487			bar_size_bits = pci_read_config(ntb->device,
488			    XEON_PBAR45SZ_OFFSET, 1);
489
490		rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY,
491		    bar->pci_resource, bar->pbase,
492		    bar->pbase + (1ul << bar_size_bits) - 1);
493		if (rc != 0) {
494			device_printf(ntb->device,
495			    "unable to resize bar\n");
496			return (rc);
497		}
498
499		save_bar_parameters(bar);
500	}
501
502	/* Mark bar region as write combining to improve performance. */
503	rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size,
504	    VM_MEMATTR_WRITE_COMBINING);
505	if (rc != 0) {
506		device_printf(ntb->device,
507		    "unable to mark bar as WRITE_COMBINING\n");
508		return (rc);
509	}
510	return (0);
511}
512
513static void
514ntb_unmap_pci_bar(struct ntb_softc *ntb)
515{
516	struct ntb_pci_bar_info *current_bar;
517	int i;
518
519	for (i = 0; i < NTB_MAX_BARS; i++) {
520		current_bar = &ntb->bar_info[i];
521		if (current_bar->pci_resource != NULL)
522			bus_release_resource(ntb->device, SYS_RES_MEMORY,
523			    current_bar->pci_resource_id,
524			    current_bar->pci_resource);
525	}
526}
527
528static int
529ntb_setup_xeon_msix(struct ntb_softc *ntb, uint32_t num_vectors)
530{
531	void (*interrupt_handler)(void *);
532	void *int_arg;
533	uint32_t i;
534	int rc;
535
536	if (num_vectors < 4)
537		return (ENOSPC);
538
539	for (i = 0; i < num_vectors; i++) {
540		ntb->int_info[i].rid = i + 1;
541		ntb->int_info[i].res = bus_alloc_resource_any(ntb->device,
542		    SYS_RES_IRQ, &ntb->int_info[i].rid, RF_ACTIVE);
543		if (ntb->int_info[i].res == NULL) {
544			device_printf(ntb->device,
545			    "bus_alloc_resource failed\n");
546			return (ENOMEM);
547		}
548		ntb->int_info[i].tag = NULL;
549		ntb->allocated_interrupts++;
550		if (i == num_vectors - 1) {
551			interrupt_handler = handle_xeon_event_irq;
552			int_arg = ntb;
553		} else {
554			interrupt_handler = handle_xeon_irq;
555			int_arg = &ntb->db_cb[i];
556		}
557		rc = bus_setup_intr(ntb->device, ntb->int_info[i].res,
558		    INTR_MPSAFE | INTR_TYPE_MISC, NULL, interrupt_handler,
559		    int_arg, &ntb->int_info[i].tag);
560		if (rc != 0) {
561			device_printf(ntb->device,
562			    "bus_setup_intr failed\n");
563			return (ENXIO);
564		}
565	}
566
567	/*
568	 * Prevent consumers from registering callbacks on the link event irq
569	 * slot, from which they will never be called back.
570	 */
571	ntb->db_cb[num_vectors - 1].reserved = true;
572	ntb->max_cbs--;
573	return (0);
574}
575
576static int
577ntb_setup_soc_msix(struct ntb_softc *ntb, uint32_t num_vectors)
578{
579	uint32_t i;
580	int rc;
581
582	for (i = 0; i < num_vectors; i++) {
583		ntb->int_info[i].rid = i + 1;
584		ntb->int_info[i].res = bus_alloc_resource_any(ntb->device,
585		    SYS_RES_IRQ, &ntb->int_info[i].rid, RF_ACTIVE);
586		if (ntb->int_info[i].res == NULL) {
587			device_printf(ntb->device,
588			    "bus_alloc_resource failed\n");
589			return (ENOMEM);
590		}
591		ntb->int_info[i].tag = NULL;
592		ntb->allocated_interrupts++;
593		rc = bus_setup_intr(ntb->device, ntb->int_info[i].res,
594		    INTR_MPSAFE | INTR_TYPE_MISC, NULL, handle_soc_irq,
595		    &ntb->db_cb[i], &ntb->int_info[i].tag);
596		if (rc != 0) {
597			device_printf(ntb->device, "bus_setup_intr failed\n");
598			return (ENXIO);
599		}
600	}
601	return (0);
602}
603
604/*
605 * The Linux NTB driver drops from MSI-X to legacy INTx if a unique vector
606 * cannot be allocated for each MSI-X message.  JHB seems to think remapping
607 * should be okay.  This tunable should enable us to test that hypothesis
608 * when someone gets their hands on some Xeon hardware.
609 */
610static int ntb_force_remap_mode;
611SYSCTL_INT(_hw_ntb, OID_AUTO, force_remap_mode, CTLFLAG_RDTUN,
612    &ntb_force_remap_mode, 0, "If enabled, force MSI-X messages to be remapped"
613    " to a smaller number of ithreads, even if the desired number are "
614    "available");
615
616/*
617 * In case it is NOT ok, give consumers an abort button.
618 */
619static int ntb_prefer_intx;
620SYSCTL_INT(_hw_ntb, OID_AUTO, prefer_intx_to_remap, CTLFLAG_RDTUN,
621    &ntb_prefer_intx, 0, "If enabled, prefer to use legacy INTx mode rather "
622    "than remapping MSI-X messages over available slots (match Linux driver "
623    "behavior)");
624
625/*
626 * Remap the desired number of MSI-X messages to available ithreads in a simple
627 * round-robin fashion.
628 */
629static int
630ntb_remap_msix(device_t dev, uint32_t desired, uint32_t avail)
631{
632	u_int *vectors;
633	uint32_t i;
634	int rc;
635
636	if (ntb_prefer_intx != 0)
637		return (ENXIO);
638
639	vectors = malloc(desired * sizeof(*vectors), M_NTB, M_ZERO | M_WAITOK);
640
641	for (i = 0; i < desired; i++)
642		vectors[i] = (i % avail) + 1;
643
644	rc = pci_remap_msix(dev, desired, vectors);
645	free(vectors, M_NTB);
646	return (rc);
647}
648
649static int
650ntb_setup_interrupts(struct ntb_softc *ntb)
651{
652	uint32_t desired_vectors, num_vectors;
653	uint64_t mask;
654	int rc;
655
656	ntb->allocated_interrupts = 0;
657
658	/*
659	 * On SOC, disable all interrupts.  On XEON, disable all but Link
660	 * Interrupt.  The rest will be unmasked as callbacks are registered.
661	 */
662	mask = 0;
663	if (ntb->type == NTB_XEON)
664		mask = (1 << XEON_DB_LINK);
665	ntb_db_write(ntb, ntb->reg_ofs.ldb_mask, ~mask);
666
667	num_vectors = desired_vectors = MIN(pci_msix_count(ntb->device),
668	    ntb->db_count);
669	if (desired_vectors >= 1) {
670		rc = pci_alloc_msix(ntb->device, &num_vectors);
671
672		if (ntb_force_remap_mode != 0 && rc == 0 &&
673		    num_vectors == desired_vectors)
674			num_vectors--;
675
676		if (rc == 0 && num_vectors < desired_vectors) {
677			rc = ntb_remap_msix(ntb->device, desired_vectors,
678			    num_vectors);
679			if (rc == 0)
680				num_vectors = desired_vectors;
681			else
682				pci_release_msi(ntb->device);
683		}
684		if (rc != 0)
685			num_vectors = 1;
686	} else
687		num_vectors = 1;
688
689	if (ntb->type == NTB_XEON && num_vectors < ntb->db_vec_count) {
690		/*
691		 * If allocating MSI-X interrupts failed and we're forced to
692		 * use legacy INTx anyway, the only limit on individual
693		 * callbacks is the number of doorbell bits.
694		 */
695		ntb->db_vec_count = 1;
696		ntb->db_vec_shift = ntb->db_count;
697		ntb_create_callbacks(ntb, ntb->db_count);
698		rc = ntb_setup_legacy_interrupt(ntb);
699	} else {
700		ntb_create_callbacks(ntb, num_vectors);
701		if (ntb->type == NTB_XEON)
702			rc = ntb_setup_xeon_msix(ntb, num_vectors);
703		else
704			rc = ntb_setup_soc_msix(ntb, num_vectors);
705		if (rc == 0 && ntb->type == NTB_XEON) {
706			/*
707			 * Prevent consumers from registering callbacks on the link event irq
708			 * slot, from which they will never be called back.
709			 */
710			ntb->db_cb[num_vectors - 1].reserved = true;
711			ntb->max_cbs--;
712		}
713	}
714	if (rc != 0) {
715		device_printf(ntb->device,
716		    "Error allocating interrupts: %d\n", rc);
717		ntb_free_callbacks(ntb);
718	}
719
720	return (rc);
721}
722
723static int
724ntb_setup_legacy_interrupt(struct ntb_softc *ntb)
725{
726	int rc;
727
728	ntb->int_info[0].rid = 0;
729	ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, SYS_RES_IRQ,
730	    &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE);
731	if (ntb->int_info[0].res == NULL) {
732		device_printf(ntb->device, "bus_alloc_resource failed\n");
733		return (ENOMEM);
734	}
735
736	ntb->int_info[0].tag = NULL;
737	ntb->allocated_interrupts = 1;
738
739	rc = bus_setup_intr(ntb->device, ntb->int_info[0].res,
740	    INTR_MPSAFE | INTR_TYPE_MISC, NULL, ntb_handle_legacy_interrupt,
741	    ntb, &ntb->int_info[0].tag);
742	if (rc != 0) {
743		device_printf(ntb->device, "bus_setup_intr failed\n");
744		return (ENXIO);
745	}
746
747	return (0);
748}
749
750static void
751ntb_teardown_interrupts(struct ntb_softc *ntb)
752{
753	struct ntb_int_info *current_int;
754	int i;
755
756	for (i = 0; i < ntb->allocated_interrupts; i++) {
757		current_int = &ntb->int_info[i];
758		if (current_int->tag != NULL)
759			bus_teardown_intr(ntb->device, current_int->res,
760			    current_int->tag);
761
762		if (current_int->res != NULL)
763			bus_release_resource(ntb->device, SYS_RES_IRQ,
764			    rman_get_rid(current_int->res), current_int->res);
765	}
766
767	ntb_free_callbacks(ntb);
768	pci_release_msi(ntb->device);
769}
770
771/*
772 * Doorbell register and mask are 64-bit on SoC, 16-bit on Xeon.  Abstract it
773 * out to make code clearer.
774 */
775static inline uint64_t
776ntb_db_read(struct ntb_softc *ntb, uint64_t regoff)
777{
778
779	if (ntb->type == NTB_SOC)
780		return (ntb_reg_read(8, regoff));
781
782	KASSERT(ntb->type == NTB_XEON, ("bad ntb type"));
783
784	return (ntb_reg_read(2, regoff));
785}
786
787static inline void
788ntb_db_write(struct ntb_softc *ntb, uint64_t regoff, uint64_t val)
789{
790
791	if (ntb->type == NTB_SOC) {
792		ntb_reg_write(8, regoff, val);
793		return;
794	}
795
796	KASSERT(ntb->type == NTB_XEON, ("bad ntb type"));
797	ntb_reg_write(2, regoff, (uint16_t)val);
798}
799
800static void
801mask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx)
802{
803	uint64_t mask;
804
805	mask = ntb_db_read(ntb, ntb->reg_ofs.ldb_mask);
806	mask |= 1 << (idx * ntb->db_vec_shift);
807	ntb_db_write(ntb, ntb->reg_ofs.ldb_mask, mask);
808}
809
810static void
811unmask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx)
812{
813	uint64_t mask;
814
815	mask = ntb_db_read(ntb, ntb->reg_ofs.ldb_mask);
816	mask &= ~(1 << (idx * ntb->db_vec_shift));
817	ntb_db_write(ntb, ntb->reg_ofs.ldb_mask, mask);
818}
819
820static void
821handle_soc_irq(void *arg)
822{
823	struct ntb_db_cb *db_cb = arg;
824	struct ntb_softc *ntb = db_cb->ntb;
825
826	ntb_db_write(ntb, ntb->reg_ofs.ldb, (uint64_t) 1 << db_cb->db_num);
827
828	if (db_cb->callback != NULL) {
829		mask_ldb_interrupt(ntb, db_cb->db_num);
830		callout_reset(&db_cb->irq_work, 0, ntb_irq_work, db_cb);
831	}
832}
833
834static void
835handle_xeon_irq(void *arg)
836{
837	struct ntb_db_cb *db_cb = arg;
838	struct ntb_softc *ntb = db_cb->ntb;
839
840	/*
841	 * On Xeon, there are 16 bits in the interrupt register
842	 * but only 4 vectors.  So, 5 bits are assigned to the first 3
843	 * vectors, with the 4th having a single bit for link
844	 * interrupts.
845	 */
846	ntb_db_write(ntb, ntb->reg_ofs.ldb,
847	    ((1 << ntb->db_vec_shift) - 1) <<
848	    (db_cb->db_num * ntb->db_vec_shift));
849
850	if (db_cb->callback != NULL) {
851		mask_ldb_interrupt(ntb, db_cb->db_num);
852		callout_reset(&db_cb->irq_work, 0, ntb_irq_work, db_cb);
853	}
854}
855
856/* Since we do not have a HW doorbell in SOC, this is only used in JF/JT */
857static void
858handle_xeon_event_irq(void *arg)
859{
860	struct ntb_softc *ntb = arg;
861	int rc;
862
863	rc = ntb_check_link_status(ntb);
864	if (rc != 0)
865		device_printf(ntb->device, "Error determining link status\n");
866
867	/* bit 15 is always the link bit */
868	ntb_db_write(ntb, ntb->reg_ofs.ldb, 1 << XEON_DB_LINK);
869}
870
871static void
872ntb_handle_legacy_interrupt(void *arg)
873{
874	struct ntb_softc *ntb = arg;
875	unsigned int i;
876	uint64_t ldb;
877
878	ldb = ntb_db_read(ntb, ntb->reg_ofs.ldb);
879
880	if (ntb->type == NTB_XEON && (ldb & XEON_DB_LINK_BIT) != 0) {
881		handle_xeon_event_irq(ntb);
882		ldb &= ~XEON_DB_LINK_BIT;
883	}
884
885	while (ldb != 0) {
886		i = ffs(ldb);
887		ldb &= ldb - 1;
888		if (ntb->type == NTB_SOC)
889			handle_soc_irq(&ntb->db_cb[i]);
890		else
891			handle_xeon_irq(&ntb->db_cb[i]);
892	}
893}
894
895static int
896ntb_create_callbacks(struct ntb_softc *ntb, uint32_t num_vectors)
897{
898	uint32_t i;
899
900	ntb->max_cbs = num_vectors;
901	ntb->db_cb = malloc(num_vectors * sizeof(*ntb->db_cb), M_NTB,
902	    M_ZERO | M_WAITOK);
903	for (i = 0; i < num_vectors; i++) {
904		ntb->db_cb[i].db_num = i;
905		ntb->db_cb[i].ntb = ntb;
906	}
907
908	return (0);
909}
910
911static void
912ntb_free_callbacks(struct ntb_softc *ntb)
913{
914	uint8_t i;
915
916	if (ntb->db_cb == NULL)
917		return;
918
919	for (i = 0; i < ntb->max_cbs; i++)
920		ntb_unregister_db_callback(ntb, i);
921
922	free(ntb->db_cb, M_NTB);
923	ntb->db_cb = NULL;
924	ntb->max_cbs = 0;
925}
926
927static struct ntb_hw_info *
928ntb_get_device_info(uint32_t device_id)
929{
930	struct ntb_hw_info *ep = pci_ids;
931
932	while (ep->device_id) {
933		if (ep->device_id == device_id)
934			return (ep);
935		++ep;
936	}
937	return (NULL);
938}
939
940static void
941ntb_teardown_xeon(struct ntb_softc *ntb)
942{
943
944	ntb_hw_link_down(ntb);
945}
946
947static void
948ntb_detect_max_mw(struct ntb_softc *ntb)
949{
950
951	if (ntb->type == NTB_SOC) {
952		ntb->mw_count = SOC_MW_COUNT;
953		return;
954	}
955
956	if (HAS_FEATURE(NTB_SPLIT_BAR))
957		ntb->mw_count = XEON_HSX_SPLIT_MW_COUNT;
958	else
959		ntb->mw_count = XEON_SNB_MW_COUNT;
960}
961
962static int
963ntb_detect_xeon(struct ntb_softc *ntb)
964{
965	uint8_t ppd, conn_type;
966
967	ppd = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1);
968	ntb->ppd = ppd;
969
970	if ((ppd & XEON_PPD_DEV_TYPE) != 0)
971		ntb->dev_type = NTB_DEV_USD;
972	else
973		ntb->dev_type = NTB_DEV_DSD;
974
975	if ((ppd & XEON_PPD_SPLIT_BAR) != 0)
976		ntb->features |= NTB_SPLIT_BAR;
977
978	conn_type = ppd & XEON_PPD_CONN_TYPE;
979	switch (conn_type) {
980	case NTB_CONN_B2B:
981		ntb->conn_type = conn_type;
982		break;
983	case NTB_CONN_RP:
984	case NTB_CONN_TRANSPARENT:
985	default:
986		device_printf(ntb->device, "Unsupported connection type: %u\n",
987		    (unsigned)conn_type);
988		return (ENXIO);
989	}
990	return (0);
991}
992
993static int
994ntb_detect_soc(struct ntb_softc *ntb)
995{
996	uint32_t ppd, conn_type;
997
998	ppd = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4);
999	ntb->ppd = ppd;
1000
1001	if ((ppd & SOC_PPD_DEV_TYPE) != 0)
1002		ntb->dev_type = NTB_DEV_DSD;
1003	else
1004		ntb->dev_type = NTB_DEV_USD;
1005
1006	conn_type = (ppd & SOC_PPD_CONN_TYPE) >> 8;
1007	switch (conn_type) {
1008	case NTB_CONN_B2B:
1009		ntb->conn_type = conn_type;
1010		break;
1011	default:
1012		device_printf(ntb->device, "Unsupported NTB configuration\n");
1013		return (ENXIO);
1014	}
1015	return (0);
1016}
1017
1018static int
1019ntb_setup_xeon(struct ntb_softc *ntb)
1020{
1021
1022	ntb->reg_ofs.ldb	= XEON_PDOORBELL_OFFSET;
1023	ntb->reg_ofs.ldb_mask	= XEON_PDBMSK_OFFSET;
1024	ntb->reg_ofs.spad_local	= XEON_SPAD_OFFSET;
1025	ntb->reg_ofs.bar2_xlat	= XEON_SBAR2XLAT_OFFSET;
1026	ntb->reg_ofs.bar4_xlat	= XEON_SBAR4XLAT_OFFSET;
1027	if (HAS_FEATURE(NTB_SPLIT_BAR))
1028		ntb->reg_ofs.bar5_xlat = XEON_SBAR5XLAT_OFFSET;
1029
1030	switch (ntb->conn_type) {
1031	case NTB_CONN_B2B:
1032		/*
1033		 * reg_ofs.rdb and reg_ofs.spad_remote are effectively ignored
1034		 * with the NTB_SDOORBELL_LOCKUP errata mode enabled.  (See
1035		 * ntb_ring_doorbell() and ntb_read/write_remote_spad().)
1036		 */
1037		ntb->reg_ofs.rdb	 = XEON_B2B_DOORBELL_OFFSET;
1038		ntb->reg_ofs.spad_remote = XEON_B2B_SPAD_OFFSET;
1039
1040		ntb->spad_count	 = XEON_SPAD_COUNT;
1041		break;
1042
1043	case NTB_CONN_RP:
1044		/*
1045		 * Every Xeon today needs NTB_SDOORBELL_LOCKUP, so punt on RP for
1046		 * now.
1047		 */
1048		KASSERT(HAS_FEATURE(NTB_SDOORBELL_LOCKUP),
1049		    ("Xeon without MW errata unimplemented"));
1050		device_printf(ntb->device,
1051		    "NTB-RP disabled to due hardware errata.\n");
1052		return (ENXIO);
1053
1054	case NTB_CONN_TRANSPARENT:
1055	default:
1056		device_printf(ntb->device, "Connection type %d not supported\n",
1057		    ntb->conn_type);
1058		return (ENXIO);
1059	}
1060
1061	/*
1062	 * There is a Xeon hardware errata related to writes to SDOORBELL or
1063	 * B2BDOORBELL in conjunction with inbound access to NTB MMIO space,
1064	 * which may hang the system.  To workaround this use the second memory
1065	 * window to access the interrupt and scratch pad registers on the
1066	 * remote system.
1067	 *
1068	 * There is another HW errata on the limit registers -- they can only
1069	 * be written when the base register is (?)4GB aligned and < 32-bit.
1070	 * This should already be the case based on the driver defaults, but
1071	 * write the limit registers first just in case.
1072	 */
1073	if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP)) {
1074		/*
1075		 * Set the Limit register to 4k, the minimum size, to prevent
1076		 * an illegal access.
1077		 *
1078		 * XXX: Should this be PBAR5LMT / get_mw_size(, max_mw - 1)?
1079		 */
1080		ntb_reg_write(8, XEON_PBAR4LMT_OFFSET,
1081		    ntb_get_mw_size(ntb, 1) + 0x1000);
1082		/* Reserve the last MW for mapping remote spad */
1083		ntb->mw_count--;
1084	} else
1085		/*
1086		 * Disable the limit register, just in case it is set to
1087		 * something silly.  A 64-bit write will also clear PBAR5LMT in
1088		 * split-bar mode, and this is desired.
1089		 */
1090		ntb_reg_write(8, XEON_PBAR4LMT_OFFSET, 0);
1091
1092	ntb->reg_ofs.lnk_cntl	 = XEON_NTBCNTL_OFFSET;
1093	ntb->reg_ofs.lnk_stat	 = XEON_LINK_STATUS_OFFSET;
1094	ntb->reg_ofs.spci_cmd	 = XEON_PCICMD_OFFSET;
1095
1096	ntb->db_count		 = XEON_DB_COUNT;
1097	ntb->db_vec_count	 = XEON_DB_MSIX_VECTOR_COUNT;
1098	ntb->db_vec_shift	 = XEON_DB_MSIX_VECTOR_SHIFT;
1099
1100	/*
1101	 * HW Errata on bit 14 of b2bdoorbell register.  Writes will not be
1102	 * mirrored to the remote system.  Shrink the number of bits by one,
1103	 * since bit 14 is the last bit.
1104	 *
1105	 * On REGS_THRU_MW errata mode, we don't use the b2bdoorbell register
1106	 * anyway.  Nor for non-B2B connection types.
1107	 */
1108	if (HAS_FEATURE(NTB_B2BDOORBELL_BIT14) &&
1109	    !HAS_FEATURE(NTB_SDOORBELL_LOCKUP) &&
1110	    ntb->conn_type == NTB_CONN_B2B)
1111		ntb->db_count = XEON_DB_COUNT - 1;
1112
1113	configure_xeon_secondary_side_bars(ntb);
1114
1115	/* Enable Bus Master and Memory Space on the secondary side */
1116	if (ntb->conn_type == NTB_CONN_B2B)
1117		ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
1118		    PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
1119
1120	/* Enable link training */
1121	ntb_hw_link_up(ntb);
1122
1123	return (0);
1124}
1125
1126static int
1127ntb_setup_soc(struct ntb_softc *ntb)
1128{
1129
1130	KASSERT(ntb->conn_type == NTB_CONN_B2B,
1131	    ("Unsupported NTB configuration (%d)\n", ntb->conn_type));
1132
1133	/* Initiate PCI-E link training */
1134	pci_write_config(ntb->device, NTB_PPD_OFFSET,
1135	    ntb->ppd | SOC_PPD_INIT_LINK, 4);
1136
1137	ntb->reg_ofs.ldb	 = SOC_PDOORBELL_OFFSET;
1138	ntb->reg_ofs.ldb_mask	 = SOC_PDBMSK_OFFSET;
1139	ntb->reg_ofs.rdb	 = SOC_B2B_DOORBELL_OFFSET;
1140	ntb->reg_ofs.bar2_xlat	 = SOC_SBAR2XLAT_OFFSET;
1141	ntb->reg_ofs.bar4_xlat	 = SOC_SBAR4XLAT_OFFSET;
1142	ntb->reg_ofs.lnk_cntl	 = SOC_NTBCNTL_OFFSET;
1143	ntb->reg_ofs.lnk_stat	 = SOC_LINK_STATUS_OFFSET;
1144	ntb->reg_ofs.spad_local	 = SOC_SPAD_OFFSET;
1145	ntb->reg_ofs.spad_remote = SOC_B2B_SPAD_OFFSET;
1146	ntb->reg_ofs.spci_cmd	 = SOC_PCICMD_OFFSET;
1147
1148	ntb->spad_count	 = SOC_SPAD_COUNT;
1149	ntb->db_count		 = SOC_DB_COUNT;
1150	ntb->db_vec_count	 = SOC_DB_MSIX_VECTOR_COUNT;
1151	ntb->db_vec_shift	 = SOC_DB_MSIX_VECTOR_SHIFT;
1152
1153	/*
1154	 * FIXME - MSI-X bug on early SOC HW, remove once internal issue is
1155	 * resolved.  Mask transaction layer internal parity errors.
1156	 */
1157	pci_write_config(ntb->device, 0xFC, 0x4, 4);
1158
1159	configure_soc_secondary_side_bars(ntb);
1160
1161	/* Enable Bus Master and Memory Space on the secondary side */
1162	ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
1163	    PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
1164
1165	callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb);
1166
1167	return (0);
1168}
1169
1170static void
1171configure_soc_secondary_side_bars(struct ntb_softc *ntb)
1172{
1173
1174	if (ntb->dev_type == NTB_DEV_USD) {
1175		ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET,
1176		    XEON_B2B_BAR2_DSD_ADDR);
1177		ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, XEON_B2B_BAR4_DSD_ADDR);
1178		ntb_reg_write(8, SOC_MBAR23_OFFSET, XEON_B2B_BAR2_USD_ADDR);
1179		ntb_reg_write(8, SOC_MBAR45_OFFSET, XEON_B2B_BAR4_USD_ADDR);
1180	} else {
1181		ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET,
1182		    XEON_B2B_BAR2_USD_ADDR);
1183		ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, XEON_B2B_BAR4_USD_ADDR);
1184		ntb_reg_write(8, SOC_MBAR23_OFFSET, XEON_B2B_BAR2_DSD_ADDR);
1185		ntb_reg_write(8, SOC_MBAR45_OFFSET, XEON_B2B_BAR4_DSD_ADDR);
1186	}
1187}
1188
1189static void
1190configure_xeon_secondary_side_bars(struct ntb_softc *ntb)
1191{
1192
1193	if (ntb->dev_type == NTB_DEV_USD) {
1194		ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET,
1195		    XEON_B2B_BAR2_DSD_ADDR);
1196		if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP))
1197			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
1198			    XEON_B2B_BAR0_DSD_ADDR);
1199		else {
1200			if (HAS_FEATURE(NTB_SPLIT_BAR)) {
1201				ntb_reg_write(4, XEON_PBAR4XLAT_OFFSET,
1202				    XEON_B2B_BAR4_DSD_ADDR);
1203				ntb_reg_write(4, XEON_PBAR5XLAT_OFFSET,
1204				    XEON_B2B_BAR5_DSD_ADDR);
1205			} else
1206				ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
1207				    XEON_B2B_BAR4_DSD_ADDR);
1208			/*
1209			 * B2B_XLAT_OFFSET is a 64-bit register but can only be
1210			 * written 32 bits at a time.
1211			 */
1212			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETL,
1213			    XEON_B2B_BAR0_DSD_ADDR & 0xffffffff);
1214			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETU,
1215			    XEON_B2B_BAR0_DSD_ADDR >> 32);
1216		}
1217		ntb_reg_write(8, XEON_SBAR0BASE_OFFSET,
1218		    XEON_B2B_BAR0_USD_ADDR);
1219		ntb_reg_write(8, XEON_SBAR2BASE_OFFSET,
1220		    XEON_B2B_BAR2_USD_ADDR);
1221		if (HAS_FEATURE(NTB_SPLIT_BAR)) {
1222			ntb_reg_write(4, XEON_SBAR4BASE_OFFSET,
1223			    XEON_B2B_BAR4_USD_ADDR);
1224			ntb_reg_write(4, XEON_SBAR5BASE_OFFSET,
1225			    XEON_B2B_BAR5_USD_ADDR);
1226		} else
1227			ntb_reg_write(8, XEON_SBAR4BASE_OFFSET,
1228			    XEON_B2B_BAR4_USD_ADDR);
1229	} else {
1230		ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET,
1231		    XEON_B2B_BAR2_USD_ADDR);
1232		if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP))
1233			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
1234			    XEON_B2B_BAR0_USD_ADDR);
1235		else {
1236			if (HAS_FEATURE(NTB_SPLIT_BAR)) {
1237				ntb_reg_write(4, XEON_PBAR4XLAT_OFFSET,
1238				    XEON_B2B_BAR4_USD_ADDR);
1239				ntb_reg_write(4, XEON_PBAR5XLAT_OFFSET,
1240				    XEON_B2B_BAR5_USD_ADDR);
1241			} else
1242				ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
1243				    XEON_B2B_BAR4_USD_ADDR);
1244			/*
1245			 * B2B_XLAT_OFFSET is a 64-bit register but can only be
1246			 * written 32 bits at a time.
1247			 */
1248			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETL,
1249			    XEON_B2B_BAR0_USD_ADDR & 0xffffffff);
1250			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETU,
1251			    XEON_B2B_BAR0_USD_ADDR >> 32);
1252		}
1253		ntb_reg_write(8, XEON_SBAR0BASE_OFFSET,
1254		    XEON_B2B_BAR0_DSD_ADDR);
1255		ntb_reg_write(8, XEON_SBAR2BASE_OFFSET,
1256		    XEON_B2B_BAR2_DSD_ADDR);
1257		if (HAS_FEATURE(NTB_SPLIT_BAR)) {
1258			ntb_reg_write(4, XEON_SBAR4BASE_OFFSET,
1259			    XEON_B2B_BAR4_DSD_ADDR);
1260			ntb_reg_write(4, XEON_SBAR5BASE_OFFSET,
1261			    XEON_B2B_BAR5_DSD_ADDR);
1262		} else
1263			ntb_reg_write(8, XEON_SBAR4BASE_OFFSET,
1264			    XEON_B2B_BAR4_DSD_ADDR);
1265	}
1266}
1267
1268/* SOC does not have link status interrupt, poll on that platform */
1269static void
1270ntb_handle_heartbeat(void *arg)
1271{
1272	struct ntb_softc *ntb = arg;
1273	uint32_t status32;
1274	int rc;
1275
1276	rc = ntb_check_link_status(ntb);
1277	if (rc != 0)
1278		device_printf(ntb->device,
1279		    "Error determining link status\n");
1280
1281	/* Check to see if a link error is the cause of the link down */
1282	if (ntb->link_status == NTB_LINK_DOWN) {
1283		status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
1284		if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) {
1285			callout_reset(&ntb->lr_timer, 0, recover_soc_link,
1286			    ntb);
1287			return;
1288		}
1289	}
1290
1291	callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
1292	    ntb_handle_heartbeat, ntb);
1293}
1294
1295static void
1296soc_perform_link_restart(struct ntb_softc *ntb)
1297{
1298	uint32_t status;
1299
1300	/* Driver resets the NTB ModPhy lanes - magic! */
1301	ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0xe0);
1302	ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x40);
1303	ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x60);
1304	ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0x60);
1305
1306	/* Driver waits 100ms to allow the NTB ModPhy to settle */
1307	pause("ModPhy", hz / 10);
1308
1309	/* Clear AER Errors, write to clear */
1310	status = ntb_reg_read(4, SOC_ERRCORSTS_OFFSET);
1311	status &= PCIM_AER_COR_REPLAY_ROLLOVER;
1312	ntb_reg_write(4, SOC_ERRCORSTS_OFFSET, status);
1313
1314	/* Clear unexpected electrical idle event in LTSSM, write to clear */
1315	status = ntb_reg_read(4, SOC_LTSSMERRSTS0_OFFSET);
1316	status |= SOC_LTSSMERRSTS0_UNEXPECTEDEI;
1317	ntb_reg_write(4, SOC_LTSSMERRSTS0_OFFSET, status);
1318
1319	/* Clear DeSkew Buffer error, write to clear */
1320	status = ntb_reg_read(4, SOC_DESKEWSTS_OFFSET);
1321	status |= SOC_DESKEWSTS_DBERR;
1322	ntb_reg_write(4, SOC_DESKEWSTS_OFFSET, status);
1323
1324	status = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET);
1325	status &= SOC_IBIST_ERR_OFLOW;
1326	ntb_reg_write(4, SOC_IBSTERRRCRVSTS0_OFFSET, status);
1327
1328	/* Releases the NTB state machine to allow the link to retrain */
1329	status = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
1330	status &= ~SOC_LTSSMSTATEJMP_FORCEDETECT;
1331	ntb_reg_write(4, SOC_LTSSMSTATEJMP_OFFSET, status);
1332}
1333
1334static void
1335ntb_handle_link_event(struct ntb_softc *ntb, int link_state)
1336{
1337	enum ntb_hw_event event;
1338	uint16_t status;
1339
1340	if (ntb->link_status == link_state)
1341		return;
1342
1343	if (link_state == NTB_LINK_UP) {
1344		device_printf(ntb->device, "Link Up\n");
1345		ntb->link_status = NTB_LINK_UP;
1346		event = NTB_EVENT_HW_LINK_UP;
1347
1348		if (ntb->type == NTB_SOC ||
1349		    ntb->conn_type == NTB_CONN_TRANSPARENT)
1350			status = ntb_reg_read(2, ntb->reg_ofs.lnk_stat);
1351		else
1352			status = pci_read_config(ntb->device,
1353			    XEON_LINK_STATUS_OFFSET, 2);
1354		ntb->link_width = (status & NTB_LINK_WIDTH_MASK) >> 4;
1355		ntb->link_speed = (status & NTB_LINK_SPEED_MASK);
1356		device_printf(ntb->device, "Link Width %d, Link Speed %d\n",
1357		    ntb->link_width, ntb->link_speed);
1358		callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
1359		    ntb_handle_heartbeat, ntb);
1360	} else {
1361		device_printf(ntb->device, "Link Down\n");
1362		ntb->link_status = NTB_LINK_DOWN;
1363		event = NTB_EVENT_HW_LINK_DOWN;
1364		/* Do not modify link width/speed, we need it in link recovery */
1365	}
1366
1367	/* notify the upper layer if we have an event change */
1368	if (ntb->event_cb != NULL)
1369		ntb->event_cb(ntb->ntb_transport, event);
1370}
1371
1372static void
1373ntb_hw_link_up(struct ntb_softc *ntb)
1374{
1375	uint32_t cntl;
1376
1377	if (ntb->conn_type == NTB_CONN_TRANSPARENT) {
1378		ntb_handle_link_event(ntb, NTB_LINK_UP);
1379		return;
1380	}
1381
1382	cntl = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl);
1383	cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK);
1384	cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP;
1385	cntl |= NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP;
1386	if (HAS_FEATURE(NTB_SPLIT_BAR))
1387		cntl |= NTB_CNTL_P2S_BAR5_SNOOP | NTB_CNTL_S2P_BAR5_SNOOP;
1388	ntb_reg_write(4, ntb->reg_ofs.lnk_cntl, cntl);
1389}
1390
1391static void
1392ntb_hw_link_down(struct ntb_softc *ntb)
1393{
1394	uint32_t cntl;
1395
1396	if (ntb->conn_type == NTB_CONN_TRANSPARENT) {
1397		ntb_handle_link_event(ntb, NTB_LINK_DOWN);
1398		return;
1399	}
1400
1401	cntl = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl);
1402	cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP);
1403	cntl &= ~(NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP);
1404	if (HAS_FEATURE(NTB_SPLIT_BAR))
1405		cntl &= ~(NTB_CNTL_P2S_BAR5_SNOOP | NTB_CNTL_S2P_BAR5_SNOOP);
1406	cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK;
1407	ntb_reg_write(4, ntb->reg_ofs.lnk_cntl, cntl);
1408}
1409
1410static void
1411recover_soc_link(void *arg)
1412{
1413	struct ntb_softc *ntb = arg;
1414	uint8_t speed, width;
1415	uint32_t status32;
1416	uint16_t status16;
1417
1418	soc_perform_link_restart(ntb);
1419
1420	/*
1421	 * There is a potential race between the 2 NTB devices recovering at
1422	 * the same time.  If the times are the same, the link will not recover
1423	 * and the driver will be stuck in this loop forever.  Add a random
1424	 * interval to the recovery time to prevent this race.
1425	 */
1426	status32 = arc4random() % SOC_LINK_RECOVERY_TIME;
1427	pause("Link", (SOC_LINK_RECOVERY_TIME + status32) * hz / 1000);
1428
1429	status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
1430	if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0)
1431		goto retry;
1432
1433	status32 = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET);
1434	if ((status32 & SOC_IBIST_ERR_OFLOW) != 0)
1435		goto retry;
1436
1437	status32 = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl);
1438	if ((status32 & SOC_CNTL_LINK_DOWN) != 0)
1439		goto out;
1440
1441	status16 = ntb_reg_read(2, ntb->reg_ofs.lnk_stat);
1442	width = (status16 & NTB_LINK_WIDTH_MASK) >> 4;
1443	speed = (status16 & NTB_LINK_SPEED_MASK);
1444	if (ntb->link_width != width || ntb->link_speed != speed)
1445		goto retry;
1446
1447out:
1448	callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
1449	    ntb_handle_heartbeat, ntb);
1450	return;
1451
1452retry:
1453	callout_reset(&ntb->lr_timer, NTB_HB_TIMEOUT * hz, recover_soc_link,
1454	    ntb);
1455}
1456
1457static int
1458ntb_check_link_status(struct ntb_softc *ntb)
1459{
1460	int link_state;
1461	uint32_t ntb_cntl;
1462	uint16_t status;
1463
1464	if (ntb->type == NTB_SOC) {
1465		ntb_cntl = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl);
1466		if ((ntb_cntl & SOC_CNTL_LINK_DOWN) != 0)
1467			link_state = NTB_LINK_DOWN;
1468		else
1469			link_state = NTB_LINK_UP;
1470	} else {
1471		status = pci_read_config(ntb->device, XEON_LINK_STATUS_OFFSET,
1472		    2);
1473
1474		if ((status & NTB_LINK_STATUS_ACTIVE) != 0)
1475			link_state = NTB_LINK_UP;
1476		else
1477			link_state = NTB_LINK_DOWN;
1478	}
1479
1480	ntb_handle_link_event(ntb, link_state);
1481
1482	return (0);
1483}
1484
1485/**
1486 * ntb_register_event_callback() - register event callback
1487 * @ntb: pointer to ntb_softc instance
1488 * @func: callback function to register
1489 *
1490 * This function registers a callback for any HW driver events such as link
1491 * up/down, power management notices and etc.
1492 *
1493 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1494 */
1495int
1496ntb_register_event_callback(struct ntb_softc *ntb, ntb_event_callback func)
1497{
1498
1499	if (ntb->event_cb != NULL)
1500		return (EINVAL);
1501
1502	ntb->event_cb = func;
1503
1504	return (0);
1505}
1506
1507/**
1508 * ntb_unregister_event_callback() - unregisters the event callback
1509 * @ntb: pointer to ntb_softc instance
1510 *
1511 * This function unregisters the existing callback from transport
1512 */
1513void
1514ntb_unregister_event_callback(struct ntb_softc *ntb)
1515{
1516
1517	ntb->event_cb = NULL;
1518}
1519
1520static void
1521ntb_irq_work(void *arg)
1522{
1523	struct ntb_db_cb *db_cb = arg;
1524	struct ntb_softc *ntb;
1525	int rc;
1526
1527	rc = db_cb->callback(db_cb->data, db_cb->db_num);
1528	/* Poll if forward progress was made. */
1529	if (rc != 0) {
1530		callout_reset(&db_cb->irq_work, 0, ntb_irq_work, db_cb);
1531		return;
1532	}
1533
1534	/* Unmask interrupt if no progress was made. */
1535	ntb = db_cb->ntb;
1536	unmask_ldb_interrupt(ntb, db_cb->db_num);
1537}
1538
1539/**
1540 * ntb_register_db_callback() - register a callback for doorbell interrupt
1541 * @ntb: pointer to ntb_softc instance
1542 * @idx: doorbell index to register callback, zero based
1543 * @data: pointer to be returned to caller with every callback
1544 * @func: callback function to register
1545 *
1546 * This function registers a callback function for the doorbell interrupt
1547 * on the primary side. The function will unmask the doorbell as well to
1548 * allow interrupt.
1549 *
1550 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1551 */
1552int
1553ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data,
1554    ntb_db_callback func)
1555{
1556	struct ntb_db_cb *db_cb = &ntb->db_cb[idx];
1557
1558	if (idx >= ntb->max_cbs || db_cb->callback != NULL || db_cb->reserved) {
1559		device_printf(ntb->device, "Invalid Index.\n");
1560		return (EINVAL);
1561	}
1562
1563	db_cb->callback = func;
1564	db_cb->data = data;
1565	callout_init(&db_cb->irq_work, 1);
1566
1567	unmask_ldb_interrupt(ntb, idx);
1568
1569	return (0);
1570}
1571
1572/**
1573 * ntb_unregister_db_callback() - unregister a callback for doorbell interrupt
1574 * @ntb: pointer to ntb_softc instance
1575 * @idx: doorbell index to register callback, zero based
1576 *
1577 * This function unregisters a callback function for the doorbell interrupt
1578 * on the primary side. The function will also mask the said doorbell.
1579 */
1580void
1581ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx)
1582{
1583
1584	if (idx >= ntb->max_cbs || ntb->db_cb[idx].callback == NULL)
1585		return;
1586
1587	mask_ldb_interrupt(ntb, idx);
1588
1589	callout_drain(&ntb->db_cb[idx].irq_work);
1590	ntb->db_cb[idx].callback = NULL;
1591}
1592
1593/**
1594 * ntb_find_transport() - find the transport pointer
1595 * @transport: pointer to pci device
1596 *
1597 * Given the pci device pointer, return the transport pointer passed in when
1598 * the transport attached when it was inited.
1599 *
1600 * RETURNS: pointer to transport.
1601 */
1602void *
1603ntb_find_transport(struct ntb_softc *ntb)
1604{
1605
1606	return (ntb->ntb_transport);
1607}
1608
1609/**
1610 * ntb_register_transport() - Register NTB transport with NTB HW driver
1611 * @transport: transport identifier
1612 *
1613 * This function allows a transport to reserve the hardware driver for
1614 * NTB usage.
1615 *
1616 * RETURNS: pointer to ntb_softc, NULL on error.
1617 */
1618struct ntb_softc *
1619ntb_register_transport(struct ntb_softc *ntb, void *transport)
1620{
1621
1622	/*
1623	 * TODO: when we have more than one transport, we will need to rewrite
1624	 * this to prevent race conditions
1625	 */
1626	if (ntb->ntb_transport != NULL)
1627		return (NULL);
1628
1629	ntb->ntb_transport = transport;
1630	return (ntb);
1631}
1632
1633/**
1634 * ntb_unregister_transport() - Unregister the transport with the NTB HW driver
1635 * @ntb - ntb_softc of the transport to be freed
1636 *
1637 * This function unregisters the transport from the HW driver and performs any
1638 * necessary cleanups.
1639 */
1640void
1641ntb_unregister_transport(struct ntb_softc *ntb)
1642{
1643	uint8_t i;
1644
1645	if (ntb->ntb_transport == NULL)
1646		return;
1647
1648	for (i = 0; i < ntb->max_cbs; i++)
1649		ntb_unregister_db_callback(ntb, i);
1650
1651	ntb_unregister_event_callback(ntb);
1652	ntb->ntb_transport = NULL;
1653}
1654
1655/**
1656 * ntb_get_max_spads() - get the total scratch regs usable
1657 * @ntb: pointer to ntb_softc instance
1658 *
1659 * This function returns the max 32bit scratchpad registers usable by the
1660 * upper layer.
1661 *
1662 * RETURNS: total number of scratch pad registers available
1663 */
1664uint8_t
1665ntb_get_max_spads(struct ntb_softc *ntb)
1666{
1667
1668	return (ntb->spad_count);
1669}
1670
1671uint8_t
1672ntb_get_max_cbs(struct ntb_softc *ntb)
1673{
1674
1675	return (ntb->max_cbs);
1676}
1677
1678uint8_t
1679ntb_mw_count(struct ntb_softc *ntb)
1680{
1681
1682	return (ntb->mw_count);
1683}
1684
1685/**
1686 * ntb_write_local_spad() - write to the secondary scratchpad register
1687 * @ntb: pointer to ntb_softc instance
1688 * @idx: index to the scratchpad register, 0 based
1689 * @val: the data value to put into the register
1690 *
1691 * This function allows writing of a 32bit value to the indexed scratchpad
1692 * register. The register resides on the secondary (external) side.
1693 *
1694 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1695 */
1696int
1697ntb_write_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val)
1698{
1699
1700	if (idx >= ntb->spad_count)
1701		return (EINVAL);
1702
1703	ntb_reg_write(4, ntb->reg_ofs.spad_local + idx * 4, val);
1704
1705	return (0);
1706}
1707
1708/**
1709 * ntb_read_local_spad() - read from the primary scratchpad register
1710 * @ntb: pointer to ntb_softc instance
1711 * @idx: index to scratchpad register, 0 based
1712 * @val: pointer to 32bit integer for storing the register value
1713 *
1714 * This function allows reading of the 32bit scratchpad register on
1715 * the primary (internal) side.
1716 *
1717 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1718 */
1719int
1720ntb_read_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val)
1721{
1722
1723	if (idx >= ntb->spad_count)
1724		return (EINVAL);
1725
1726	*val = ntb_reg_read(4, ntb->reg_ofs.spad_local + idx * 4);
1727
1728	return (0);
1729}
1730
1731/**
1732 * ntb_write_remote_spad() - write to the secondary scratchpad register
1733 * @ntb: pointer to ntb_softc instance
1734 * @idx: index to the scratchpad register, 0 based
1735 * @val: the data value to put into the register
1736 *
1737 * This function allows writing of a 32bit value to the indexed scratchpad
1738 * register. The register resides on the secondary (external) side.
1739 *
1740 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1741 */
1742int
1743ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val)
1744{
1745
1746	if (idx >= ntb->spad_count)
1747		return (EINVAL);
1748
1749	if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP))
1750		ntb_mw_write(4, XEON_SHADOW_SPAD_OFFSET + idx * 4, val);
1751	else
1752		ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val);
1753
1754	return (0);
1755}
1756
1757/**
1758 * ntb_read_remote_spad() - read from the primary scratchpad register
1759 * @ntb: pointer to ntb_softc instance
1760 * @idx: index to scratchpad register, 0 based
1761 * @val: pointer to 32bit integer for storing the register value
1762 *
1763 * This function allows reading of the 32bit scratchpad register on
1764 * the primary (internal) side.
1765 *
1766 * RETURNS: An appropriate ERRNO error value on error, or zero for success.
1767 */
1768int
1769ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val)
1770{
1771
1772	if (idx >= ntb->spad_count)
1773		return (EINVAL);
1774
1775	if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP))
1776		*val = ntb_mw_read(4, XEON_SHADOW_SPAD_OFFSET + idx * 4);
1777	else
1778		*val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4);
1779
1780	return (0);
1781}
1782
1783/**
1784 * ntb_get_mw_vbase() - get virtual addr for the NTB memory window
1785 * @ntb: pointer to ntb_softc instance
1786 * @mw: memory window number
1787 *
1788 * This function provides the base virtual address of the memory window
1789 * specified.
1790 *
1791 * RETURNS: pointer to virtual address, or NULL on error.
1792 */
1793void *
1794ntb_get_mw_vbase(struct ntb_softc *ntb, unsigned int mw)
1795{
1796
1797	if (mw >= ntb_mw_count(ntb))
1798		return (NULL);
1799
1800	return (ntb->bar_info[ntb_mw_to_bar(ntb, mw)].vbase);
1801}
1802
1803vm_paddr_t
1804ntb_get_mw_pbase(struct ntb_softc *ntb, unsigned int mw)
1805{
1806
1807	if (mw >= ntb_mw_count(ntb))
1808		return (0);
1809
1810	return (ntb->bar_info[ntb_mw_to_bar(ntb, mw)].pbase);
1811}
1812
1813/**
1814 * ntb_get_mw_size() - return size of NTB memory window
1815 * @ntb: pointer to ntb_softc instance
1816 * @mw: memory window number
1817 *
1818 * This function provides the physical size of the memory window specified
1819 *
1820 * RETURNS: the size of the memory window or zero on error
1821 */
1822u_long
1823ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw)
1824{
1825
1826	if (mw >= ntb_mw_count(ntb))
1827		return (0);
1828
1829	return (ntb->bar_info[ntb_mw_to_bar(ntb, mw)].size);
1830}
1831
1832/**
1833 * ntb_set_mw_addr - set the memory window address
1834 * @ntb: pointer to ntb_softc instance
1835 * @mw: memory window number
1836 * @addr: base address for data
1837 *
1838 * This function sets the base physical address of the memory window.  This
1839 * memory address is where data from the remote system will be transfered into
1840 * or out of depending on how the transport is configured.
1841 */
1842void
1843ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr)
1844{
1845
1846	if (mw >= ntb_mw_count(ntb))
1847		return;
1848
1849	switch (ntb_mw_to_bar(ntb, mw)) {
1850	case NTB_B2B_BAR_1:
1851		ntb_reg_write(8, ntb->reg_ofs.bar2_xlat, addr);
1852		break;
1853	case NTB_B2B_BAR_2:
1854		if (HAS_FEATURE(NTB_SPLIT_BAR))
1855			ntb_reg_write(4, ntb->reg_ofs.bar4_xlat, addr);
1856		else
1857			ntb_reg_write(8, ntb->reg_ofs.bar4_xlat, addr);
1858		break;
1859	case NTB_B2B_BAR_3:
1860		ntb_reg_write(4, ntb->reg_ofs.bar5_xlat, addr);
1861		break;
1862	default:
1863		KASSERT(false, ("invalid BAR"));
1864		break;
1865	}
1866}
1867
1868/**
1869 * ntb_ring_doorbell() - Set the doorbell on the secondary/external side
1870 * @ntb: pointer to ntb_softc instance
1871 * @db: doorbell to ring
1872 *
1873 * This function allows triggering of a doorbell on the secondary/external
1874 * side that will initiate an interrupt on the remote host
1875 */
1876void
1877ntb_ring_doorbell(struct ntb_softc *ntb, unsigned int db)
1878{
1879	uint64_t bit;
1880
1881	if (ntb->type == NTB_SOC)
1882		bit = 1 << db;
1883	else
1884		bit = ((1 << ntb->db_vec_shift) - 1) <<
1885		    (db * ntb->db_vec_shift);
1886
1887	if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP)) {
1888		ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET, bit);
1889		return;
1890	}
1891
1892	ntb_db_write(ntb, ntb->reg_ofs.rdb, bit);
1893}
1894
1895/**
1896 * ntb_query_link_status() - return the hardware link status
1897 * @ndev: pointer to ntb_device instance
1898 *
1899 * Returns true if the hardware is connected to the remote system
1900 *
1901 * RETURNS: true or false based on the hardware link state
1902 */
1903bool
1904ntb_query_link_status(struct ntb_softc *ntb)
1905{
1906
1907	return (ntb->link_status == NTB_LINK_UP);
1908}
1909
1910static void
1911save_bar_parameters(struct ntb_pci_bar_info *bar)
1912{
1913
1914	bar->pci_bus_tag = rman_get_bustag(bar->pci_resource);
1915	bar->pci_bus_handle = rman_get_bushandle(bar->pci_resource);
1916	bar->pbase = rman_get_start(bar->pci_resource);
1917	bar->size = rman_get_size(bar->pci_resource);
1918	bar->vbase = rman_get_virtual(bar->pci_resource);
1919}
1920
1921device_t
1922ntb_get_device(struct ntb_softc *ntb)
1923{
1924
1925	return (ntb->device);
1926}
1927
1928/* Export HW-specific errata information. */
1929bool
1930ntb_has_feature(struct ntb_softc *ntb, uint64_t feature)
1931{
1932
1933	return (HAS_FEATURE(feature));
1934}
1935