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