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