xref: /freebsd/sys/dev/ntb/ntb_hw/ntb_hw_plx.c (revision 4bc52338)
1 /*-
2  * Copyright (c) 2017 Alexander Motin <mav@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 /*
28  * The Non-Transparent Bridge (NTB) is a device that allows you to connect
29  * two or more systems using a PCI-e links, providing remote memory access.
30  *
31  * This module contains a driver for NTBs in PLX/Avago/Broadcom PCIe bridges.
32  */
33 
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36 
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 #include <sys/bus.h>
41 #include <sys/interrupt.h>
42 #include <sys/module.h>
43 #include <sys/rman.h>
44 #include <sys/sysctl.h>
45 #include <vm/vm.h>
46 #include <vm/pmap.h>
47 #include <machine/bus.h>
48 #include <machine/intr_machdep.h>
49 #include <machine/resource.h>
50 #include <dev/pci/pcireg.h>
51 #include <dev/pci/pcivar.h>
52 
53 #include "../ntb.h"
54 
55 #define PLX_MAX_BARS		4	/* There are at most 4 data BARs. */
56 #define PLX_NUM_SPAD		8	/* There are 8 scratchpads. */
57 #define PLX_NUM_SPAD_PATT	4	/* Use test pattern as 4 more. */
58 #define PLX_NUM_DB		16	/* There are 16 doorbells. */
59 
60 struct ntb_plx_mw_info {
61 	int			 mw_bar;
62 	int			 mw_64bit;
63 	int			 mw_rid;
64 	struct resource		*mw_res;
65 	vm_paddr_t		 mw_pbase;
66 	caddr_t			 mw_vbase;
67 	vm_size_t		 mw_size;
68 	vm_memattr_t		 mw_map_mode;
69 	bus_addr_t		 mw_xlat_addr;
70 	size_t			 mw_xlat_size;
71 };
72 
73 struct ntb_plx_softc {
74 	/* ntb.c context. Do not move! Must go first! */
75 	void			*ntb_store;
76 
77 	device_t		 dev;
78 	struct resource		*conf_res;
79 	int			 conf_rid;
80 	u_int			 ntx;		/* NTx number within chip. */
81 	u_int			 link;		/* Link v/s Virtual side. */
82 	u_int			 port;		/* Port number within chip. */
83 	u_int			 alut;		/* A-LUT is enabled for NTx */
84 
85 	int			 int_rid;
86 	struct resource		*int_res;
87 	void			*int_tag;
88 
89 	struct ntb_plx_mw_info	 mw_info[PLX_MAX_BARS];
90 	int			 mw_count;	/* Number of memory windows. */
91 
92 	int			 spad_count1;	/* Number of standard spads. */
93 	int			 spad_count2;	/* Number of extra spads. */
94 	uint32_t		 spad_off1;	/* Offset of our spads. */
95 	uint32_t		 spad_off2;	/* Offset of our extra spads. */
96 	uint32_t		 spad_offp1;	/* Offset of peer spads. */
97 	uint32_t		 spad_offp2;	/* Offset of peer extra spads. */
98 
99 	/* Parameters of window shared with peer config access in B2B mode. */
100 	int			 b2b_mw;	/* Shared window number. */
101 	uint64_t		 b2b_off;	/* Offset in shared window. */
102 };
103 
104 #define	PLX_NT0_BASE		0x3E000
105 #define	PLX_NT1_BASE		0x3C000
106 #define	PLX_NTX_BASE(sc)	((sc)->ntx ? PLX_NT1_BASE : PLX_NT0_BASE)
107 #define	PLX_NTX_LINK_OFFSET	0x01000
108 
109 /* Bases of NTx our/peer interface registers */
110 #define	PLX_NTX_OUR_BASE(sc)				\
111     (PLX_NTX_BASE(sc) + ((sc)->link ? PLX_NTX_LINK_OFFSET : 0))
112 #define	PLX_NTX_PEER_BASE(sc)				\
113     (PLX_NTX_BASE(sc) + ((sc)->link ? 0 : PLX_NTX_LINK_OFFSET))
114 
115 /* Read/write NTx our interface registers */
116 #define	NTX_READ(sc, reg)				\
117     bus_read_4((sc)->conf_res, PLX_NTX_OUR_BASE(sc) + (reg))
118 #define	NTX_WRITE(sc, reg, val)				\
119     bus_write_4((sc)->conf_res, PLX_NTX_OUR_BASE(sc) + (reg), (val))
120 
121 /* Read/write NTx peer interface registers */
122 #define	PNTX_READ(sc, reg)				\
123     bus_read_4((sc)->conf_res, PLX_NTX_PEER_BASE(sc) + (reg))
124 #define	PNTX_WRITE(sc, reg, val)			\
125     bus_write_4((sc)->conf_res, PLX_NTX_PEER_BASE(sc) + (reg), (val))
126 
127 /* Read/write B2B NTx registers */
128 #define	BNTX_READ(sc, reg)				\
129     bus_read_4((sc)->mw_info[(sc)->b2b_mw].mw_res,	\
130     PLX_NTX_BASE(sc) + (reg))
131 #define	BNTX_WRITE(sc, reg, val)			\
132     bus_write_4((sc)->mw_info[(sc)->b2b_mw].mw_res,	\
133     PLX_NTX_BASE(sc) + (reg), (val))
134 
135 #define	PLX_PORT_BASE(p)		((p) << 12)
136 #define	PLX_STATION_PORT_BASE(sc)	PLX_PORT_BASE((sc)->port & ~7)
137 
138 #define	PLX_PORT_CONTROL(sc)		(PLX_STATION_PORT_BASE(sc) + 0x208)
139 
140 static int ntb_plx_init(device_t dev);
141 static int ntb_plx_detach(device_t dev);
142 static int ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx);
143 
144 static int
145 ntb_plx_probe(device_t dev)
146 {
147 
148 	switch (pci_get_devid(dev)) {
149 	case 0x87a010b5:
150 		device_set_desc(dev, "PLX Non-Transparent Bridge NT0 Link");
151 		return (BUS_PROBE_DEFAULT);
152 	case 0x87a110b5:
153 		device_set_desc(dev, "PLX Non-Transparent Bridge NT1 Link");
154 		return (BUS_PROBE_DEFAULT);
155 	case 0x87b010b5:
156 		device_set_desc(dev, "PLX Non-Transparent Bridge NT0 Virtual");
157 		return (BUS_PROBE_DEFAULT);
158 	case 0x87b110b5:
159 		device_set_desc(dev, "PLX Non-Transparent Bridge NT1 Virtual");
160 		return (BUS_PROBE_DEFAULT);
161 	}
162 	return (ENXIO);
163 }
164 
165 static int
166 ntb_plx_init(device_t dev)
167 {
168 	struct ntb_plx_softc *sc = device_get_softc(dev);
169 	struct ntb_plx_mw_info *mw;
170 	uint64_t val64;
171 	int i;
172 	uint32_t val;
173 
174 	if (sc->b2b_mw >= 0) {
175 		/* Set peer BAR0/1 size and address for B2B NTx access. */
176 		mw = &sc->mw_info[sc->b2b_mw];
177 		if (mw->mw_64bit) {
178 			PNTX_WRITE(sc, 0xe4, 0x3);	/* 64-bit */
179 			val64 = 0x2000000000000000 * mw->mw_bar | 0x4;
180 			PNTX_WRITE(sc, PCIR_BAR(0), val64);
181 			PNTX_WRITE(sc, PCIR_BAR(0) + 4, val64 >> 32);
182 		} else {
183 			PNTX_WRITE(sc, 0xe4, 0x2);	/* 32-bit */
184 			val = 0x20000000 * mw->mw_bar;
185 			PNTX_WRITE(sc, PCIR_BAR(0), val);
186 		}
187 
188 		/* Set Virtual to Link address translation for B2B. */
189 		for (i = 0; i < sc->mw_count; i++) {
190 			mw = &sc->mw_info[i];
191 			if (mw->mw_64bit) {
192 				val64 = 0x2000000000000000 * mw->mw_bar;
193 				NTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, val64);
194 				NTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4 + 4, val64 >> 32);
195 			} else {
196 				val = 0x20000000 * mw->mw_bar;
197 				NTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, val);
198 			}
199 		}
200 
201 		/* Make sure Virtual to Link A-LUT is disabled. */
202 		if (sc->alut)
203 			PNTX_WRITE(sc, 0xc94, 0);
204 
205 		/* Enable all Link Interface LUT entries for peer. */
206 		for (i = 0; i < 32; i += 2) {
207 			PNTX_WRITE(sc, 0xdb4 + i * 2,
208 			    0x00010001 | ((i + 1) << 19) | (i << 3));
209 		}
210 	}
211 
212 	/*
213 	 * Enable Virtual Interface LUT entry 0 for 0:0.*.
214 	 * entry 1 for our Requester ID reported by the chip,
215 	 * entries 2-5 for 0/64/128/192:4.* of I/OAT DMA engines.
216 	 * XXX: Its a hack, we can't know all DMA engines, but this covers all
217 	 * I/OAT of Xeon E5/E7 at least from Sandy Bridge till Skylake I saw.
218 	 */
219 	val = (NTX_READ(sc, 0xc90) << 16) | 0x00010001;
220 	NTX_WRITE(sc, sc->link ? 0xdb4 : 0xd94, val);
221 	NTX_WRITE(sc, sc->link ? 0xdb8 : 0xd98, 0x40210021);
222 	NTX_WRITE(sc, sc->link ? 0xdbc : 0xd9c, 0xc0218021);
223 
224 	/* Set Link to Virtual address translation. */
225 	for (i = 0; i < sc->mw_count; i++) {
226 		mw = &sc->mw_info[i];
227 		if (mw->mw_xlat_size != 0)
228 			ntb_plx_mw_set_trans_internal(dev, i);
229 	}
230 
231 	pci_enable_busmaster(dev);
232 	if (sc->b2b_mw >= 0)
233 		PNTX_WRITE(sc, PCIR_COMMAND, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
234 
235 	return (0);
236 }
237 
238 static void
239 ntb_plx_isr(void *arg)
240 {
241 	device_t dev = arg;
242 	struct ntb_plx_softc *sc = device_get_softc(dev);
243 	uint32_t val;
244 
245 	ntb_db_event((device_t)arg, 0);
246 
247 	if (sc->link)	/* Link Interface has no Link Error registers. */
248 		return;
249 
250 	val = NTX_READ(sc, 0xfe0);
251 	if (val == 0)
252 		return;
253 	NTX_WRITE(sc, 0xfe0, val);
254 	if (val & 1)
255 		device_printf(dev, "Correctable Error\n");
256 	if (val & 2)
257 		device_printf(dev, "Uncorrectable Error\n");
258 	if (val & 4) {
259 		/* DL_Down resets link side registers, have to reinit. */
260 		ntb_plx_init(dev);
261 		ntb_link_event(dev);
262 	}
263 	if (val & 8)
264 		device_printf(dev, "Uncorrectable Error Message Drop\n");
265 }
266 
267 static int
268 ntb_plx_setup_intr(device_t dev)
269 {
270 	struct ntb_plx_softc *sc = device_get_softc(dev);
271 	int error;
272 
273 	/*
274 	 * XXX: This hardware supports MSI, but I found it unusable.
275 	 * It generates new MSI only when doorbell register goes from
276 	 * zero, but does not generate it when another bit is set or on
277 	 * partial clear.  It makes operation very racy and unreliable.
278 	 * The data book mentions some mask juggling magic to workaround
279 	 * that, but I failed to make it work.
280 	 */
281 	sc->int_rid = 0;
282 	sc->int_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
283 	    &sc->int_rid, RF_SHAREABLE|RF_ACTIVE);
284 	if (sc->int_res == NULL) {
285 		device_printf(dev, "bus_alloc_resource failed\n");
286 		return (ENOMEM);
287 	}
288 	error = bus_setup_intr(dev, sc->int_res, INTR_MPSAFE | INTR_TYPE_MISC,
289 	    NULL, ntb_plx_isr, dev, &sc->int_tag);
290 	if (error != 0) {
291 		device_printf(dev, "bus_setup_intr failed: %d\n", error);
292 		return (error);
293 	}
294 
295 	if (!sc->link) { /* Link Interface has no Link Error registers. */
296 		NTX_WRITE(sc, 0xfe0, 0xf);	/* Clear link interrupts. */
297 		NTX_WRITE(sc, 0xfe4, 0x0);	/* Unmask link interrupts. */
298 	}
299 	return (0);
300 }
301 
302 static void
303 ntb_plx_teardown_intr(device_t dev)
304 {
305 	struct ntb_plx_softc *sc = device_get_softc(dev);
306 
307 	if (!sc->link)	/* Link Interface has no Link Error registers. */
308 		NTX_WRITE(sc, 0xfe4, 0xf);	/* Mask link interrupts. */
309 
310 	if (sc->int_res) {
311 		bus_teardown_intr(dev, sc->int_res, sc->int_tag);
312 		bus_release_resource(dev, SYS_RES_IRQ, sc->int_rid,
313 		    sc->int_res);
314 	}
315 }
316 
317 static int
318 ntb_plx_attach(device_t dev)
319 {
320 	struct ntb_plx_softc *sc = device_get_softc(dev);
321 	struct ntb_plx_mw_info *mw;
322 	int error = 0, i;
323 	uint32_t val;
324 	char buf[32];
325 
326 	/* Identify what we are (what side of what NTx). */
327 	sc->dev = dev;
328 	val = pci_read_config(dev, 0xc8c, 4);
329 	sc->ntx = (val & 1) != 0;
330 	sc->link = (val & 0x80000000) != 0;
331 
332 	/* Get access to whole 256KB of chip configuration space via BAR0/1. */
333 	sc->conf_rid = PCIR_BAR(0);
334 	sc->conf_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
335 	    &sc->conf_rid, RF_ACTIVE);
336 	if (sc->conf_res == NULL) {
337 		device_printf(dev, "Can't allocate configuration BAR.\n");
338 		return (ENXIO);
339 	}
340 
341 	/* Identify chip port we are connected to. */
342 	val = bus_read_4(sc->conf_res, 0x360);
343 	sc->port = (val >> ((sc->ntx == 0) ? 8 : 16)) & 0x1f;
344 
345 	/* Detect A-LUT enable and size. */
346 	val >>= 30;
347 	sc->alut = (val == 0x3) ? 1 : ((val & (1 << sc->ntx)) ? 2 : 0);
348 	if (sc->alut)
349 		device_printf(dev, "%u A-LUT entries\n", 128 * sc->alut);
350 
351 	/* Find configured memory windows at BAR2-5. */
352 	sc->mw_count = 0;
353 	for (i = 2; i <= 5; i++) {
354 		mw = &sc->mw_info[sc->mw_count];
355 		mw->mw_bar = i;
356 		mw->mw_rid = PCIR_BAR(mw->mw_bar);
357 		mw->mw_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
358 		    &mw->mw_rid, RF_ACTIVE);
359 		if (mw->mw_res == NULL)
360 			continue;
361 		mw->mw_pbase = rman_get_start(mw->mw_res);
362 		mw->mw_size = rman_get_size(mw->mw_res);
363 		mw->mw_vbase = rman_get_virtual(mw->mw_res);
364 		mw->mw_map_mode = VM_MEMATTR_UNCACHEABLE;
365 		sc->mw_count++;
366 
367 		/* Skip over adjacent BAR for 64-bit BARs. */
368 		val = pci_read_config(dev, PCIR_BAR(mw->mw_bar), 4);
369 		if ((val & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64) {
370 			mw->mw_64bit = 1;
371 			i++;
372 		}
373 	}
374 
375 	/* Try to identify B2B mode. */
376 	i = 1;
377 	snprintf(buf, sizeof(buf), "hint.%s.%d.b2b", device_get_name(dev),
378 	    device_get_unit(dev));
379 	TUNABLE_INT_FETCH(buf, &i);
380 	if (sc->link) {
381 		device_printf(dev, "NTB-to-Root Port mode (Link Interface)\n");
382 		sc->b2b_mw = -1;
383 	} else if (i == 0) {
384 		device_printf(dev, "NTB-to-Root Port mode (Virtual Interface)\n");
385 		sc->b2b_mw = -1;
386 	} else {
387 		device_printf(dev, "NTB-to-NTB (back-to-back) mode\n");
388 
389 		/* We need at least one memory window for B2B peer access. */
390 		if (sc->mw_count == 0) {
391 			device_printf(dev, "No memory window BARs enabled.\n");
392 			error = ENXIO;
393 			goto out;
394 		}
395 		sc->b2b_mw = sc->mw_count - 1;
396 
397 		/* Use half of the window for B2B, but no less then 1MB. */
398 		mw = &sc->mw_info[sc->b2b_mw];
399 		if (mw->mw_size >= 2 * 1024 * 1024)
400 			sc->b2b_off = mw->mw_size / 2;
401 		else
402 			sc->b2b_off = 0;
403 	}
404 
405 	/*
406 	 * Use Physical Layer User Test Pattern as additional scratchpad.
407 	 * Make sure they are present and enabled by writing to them.
408 	 * XXX: Its a hack, but standard 8 registers are not enough.
409 	 */
410 	sc->spad_offp1 = sc->spad_off1 = PLX_NTX_OUR_BASE(sc) + 0xc6c;
411 	sc->spad_offp2 = sc->spad_off2 = PLX_PORT_BASE(sc->ntx * 8) + 0x20c;
412 	if (sc->b2b_mw >= 0) {
413 		/* In NTB-to-NTB mode each side has own scratchpads. */
414 		sc->spad_count1 = PLX_NUM_SPAD;
415 		bus_write_4(sc->conf_res, sc->spad_off2, 0x12345678);
416 		if (bus_read_4(sc->conf_res, sc->spad_off2) == 0x12345678)
417 			sc->spad_count2 = PLX_NUM_SPAD_PATT;
418 	} else {
419 		/* Otherwise we have share scratchpads with the peer. */
420 		if (sc->link) {
421 			sc->spad_off1 += PLX_NUM_SPAD / 2 * 4;
422 			sc->spad_off2 += PLX_NUM_SPAD_PATT / 2 * 4;
423 		} else {
424 			sc->spad_offp1 += PLX_NUM_SPAD / 2 * 4;
425 			sc->spad_offp2 += PLX_NUM_SPAD_PATT / 2 * 4;
426 		}
427 		sc->spad_count1 = PLX_NUM_SPAD / 2;
428 		bus_write_4(sc->conf_res, sc->spad_off2, 0x12345678);
429 		if (bus_read_4(sc->conf_res, sc->spad_off2) == 0x12345678)
430 			sc->spad_count2 = PLX_NUM_SPAD_PATT / 2;
431 	}
432 
433 	/* Apply static part of NTB configuration. */
434 	ntb_plx_init(dev);
435 
436 	/* Allocate and setup interrupts. */
437 	error = ntb_plx_setup_intr(dev);
438 	if (error)
439 		goto out;
440 
441 	/* Attach children to this controller */
442 	error = ntb_register_device(dev);
443 
444 out:
445 	if (error != 0)
446 		ntb_plx_detach(dev);
447 	return (error);
448 }
449 
450 static int
451 ntb_plx_detach(device_t dev)
452 {
453 	struct ntb_plx_softc *sc = device_get_softc(dev);
454 	struct ntb_plx_mw_info *mw;
455 	int i;
456 
457 	/* Detach & delete all children */
458 	ntb_unregister_device(dev);
459 
460 	/* Disable and free interrupts. */
461 	ntb_plx_teardown_intr(dev);
462 
463 	/* Free memory resources. */
464 	for (i = 0; i < sc->mw_count; i++) {
465 		mw = &sc->mw_info[i];
466 		bus_release_resource(dev, SYS_RES_MEMORY, mw->mw_rid,
467 		    mw->mw_res);
468 	}
469 	bus_release_resource(dev, SYS_RES_MEMORY, sc->conf_rid, sc->conf_res);
470 	return (0);
471 }
472 
473 
474 static bool
475 ntb_plx_link_is_up(device_t dev, enum ntb_speed *speed, enum ntb_width *width)
476 {
477 	uint16_t link;
478 
479 	link = pcie_read_config(dev, PCIER_LINK_STA, 2);
480 	if (speed != NULL)
481 		*speed = (link & PCIEM_LINK_STA_SPEED);
482 	if (width != NULL)
483 		*width = (link & PCIEM_LINK_STA_WIDTH) >> 4;
484 	return ((link & PCIEM_LINK_STA_WIDTH) != 0);
485 }
486 
487 static int
488 ntb_plx_link_enable(device_t dev, enum ntb_speed speed __unused,
489     enum ntb_width width __unused)
490 {
491 	struct ntb_plx_softc *sc = device_get_softc(dev);
492 	uint32_t reg, val;
493 
494 	/* The fact that we see the Link Interface means link is enabled. */
495 	if (sc->link) {
496 		ntb_link_event(dev);
497 		return (0);
498 	}
499 
500 	reg = PLX_PORT_CONTROL(sc);
501 	val = bus_read_4(sc->conf_res, reg);
502 	if ((val & (1 << (sc->port & 7))) == 0) {
503 		/* If already enabled, generate fake link event and exit. */
504 		ntb_link_event(dev);
505 		return (0);
506 	}
507 	val &= ~(1 << (sc->port & 7));
508 	bus_write_4(sc->conf_res, reg, val);
509 	return (0);
510 }
511 
512 static int
513 ntb_plx_link_disable(device_t dev)
514 {
515 	struct ntb_plx_softc *sc = device_get_softc(dev);
516 	uint32_t reg, val;
517 
518 	/* Link disable for Link Interface would be suicidal. */
519 	if (sc->link)
520 		return (0);
521 
522 	reg = PLX_PORT_CONTROL(sc);
523 	val = bus_read_4(sc->conf_res, reg);
524 	val |= (1 << (sc->port & 7));
525 	bus_write_4(sc->conf_res, reg, val);
526 	return (0);
527 }
528 
529 static bool
530 ntb_plx_link_enabled(device_t dev)
531 {
532 	struct ntb_plx_softc *sc = device_get_softc(dev);
533 	uint32_t reg, val;
534 
535 	/* The fact that we see the Link Interface means link is enabled. */
536 	if (sc->link)
537 		return (TRUE);
538 
539 	reg = PLX_PORT_CONTROL(sc);
540 	val = bus_read_4(sc->conf_res, reg);
541 	return ((val & (1 << (sc->port & 7))) == 0);
542 }
543 
544 static uint8_t
545 ntb_plx_mw_count(device_t dev)
546 {
547 	struct ntb_plx_softc *sc = device_get_softc(dev);
548 
549 	if (sc->b2b_mw >= 0 && sc->b2b_off == 0)
550 		return (sc->mw_count - 1); /* B2B consumed whole window. */
551 	return (sc->mw_count);
552 }
553 
554 static int
555 ntb_plx_mw_get_range(device_t dev, unsigned mw_idx, vm_paddr_t *base,
556     caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
557     bus_addr_t *plimit)
558 {
559 	struct ntb_plx_softc *sc = device_get_softc(dev);
560 	struct ntb_plx_mw_info *mw;
561 	size_t off;
562 
563 	if (mw_idx >= sc->mw_count)
564 		return (EINVAL);
565 	off = 0;
566 	if (mw_idx == sc->b2b_mw) {
567 		KASSERT(sc->b2b_off != 0,
568 		    ("user shouldn't get non-shared b2b mw"));
569 		off = sc->b2b_off;
570 	}
571 	mw = &sc->mw_info[mw_idx];
572 
573 	/* Local to remote memory window parameters. */
574 	if (base != NULL)
575 		*base = mw->mw_pbase + off;
576 	if (vbase != NULL)
577 		*vbase = mw->mw_vbase + off;
578 	if (size != NULL)
579 		*size = mw->mw_size - off;
580 
581 	/*
582 	 * Remote to local memory window translation address alignment.
583 	 * Translation address has to be aligned to the BAR size, but A-LUT
584 	 * entries re-map addresses can be aligned to 1/128 or 1/256 of it.
585 	 * XXX: In B2B mode we can change BAR size (and so alignmet) live,
586 	 * but there is no way to report it here, so report safe value.
587 	 */
588 	if (align != NULL) {
589 		if (sc->alut && mw->mw_bar == 2)
590 			*align = (mw->mw_size - off) / 128 / sc->alut;
591 		else
592 			*align = mw->mw_size - off;
593 	}
594 
595 	/*
596 	 * Remote to local memory window size alignment.
597 	 * The chip has no limit registers, but A-LUT, when available, allows
598 	 * access control with granularity of 1/128 or 1/256 of the BAR size.
599 	 * XXX: In B2B case we can change BAR size live, but there is no way
600 	 * to report it, so report half of the BAR size, that should be safe.
601 	 * In non-B2B case there is no control at all, so report the BAR size.
602 	 */
603 	if (align_size != NULL) {
604 		if (sc->alut && mw->mw_bar == 2)
605 			*align_size = (mw->mw_size - off) / 128 / sc->alut;
606 		else if (sc->b2b_mw >= 0)
607 			*align_size = (mw->mw_size - off) / 2;
608 		else
609 			*align_size = mw->mw_size - off;
610 	}
611 
612 	/* Remote to local memory window translation address upper limit. */
613 	if (plimit != NULL)
614 		*plimit = mw->mw_64bit ? BUS_SPACE_MAXADDR :
615 		    BUS_SPACE_MAXADDR_32BIT;
616 	return (0);
617 }
618 
619 static int
620 ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx)
621 {
622 	struct ntb_plx_softc *sc = device_get_softc(dev);
623 	struct ntb_plx_mw_info *mw;
624 	uint64_t addr, eaddr, off, size, bsize, esize, val64;
625 	uint32_t val;
626 	int i;
627 
628 	mw = &sc->mw_info[mw_idx];
629 	addr = mw->mw_xlat_addr;
630 	size = mw->mw_xlat_size;
631 	off = 0;
632 	if (mw_idx == sc->b2b_mw) {
633 		off = sc->b2b_off;
634 		KASSERT(off != 0, ("user shouldn't get non-shared b2b mw"));
635 
636 		/*
637 		 * While generally we can set any BAR size on link side,
638 		 * for B2B shared window we can't go above preconfigured
639 		 * size due to BAR address alignment requirements.
640 		 */
641 		if (size > mw->mw_size - off)
642 			return (EINVAL);
643 	}
644 
645 	if (size > 0) {
646 		/* Round BAR size to next power of 2 or at least 1MB. */
647 		bsize = size;
648 		if (!powerof2(bsize))
649 			bsize = 1LL << flsll(bsize);
650 		if (bsize < 1024 * 1024)
651 			bsize = 1024 * 1024;
652 
653 		/* A-LUT has 128 or 256 times better granularity. */
654 		esize = bsize;
655 		if (sc->alut && mw->mw_bar == 2)
656 			esize /= 128 * sc->alut;
657 
658 		/* addr should be aligned to BAR or A-LUT element size. */
659 		if ((addr & (esize - 1)) != 0)
660 			return (EINVAL);
661 	} else
662 		esize = bsize = 0;
663 
664 	if (mw->mw_64bit) {
665 		if (sc->b2b_mw >= 0) {
666 			/* Set Link Interface BAR size and enable/disable it. */
667 			val64 = 0;
668 			if (bsize > 0)
669 				val64 = (~(bsize - 1) & ~0xfffff);
670 			val64 |= 0xc;
671 			PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4, val64);
672 			PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4 + 4, val64 >> 32);
673 
674 			/* Set Link Interface BAR address. */
675 			val64 = 0x2000000000000000 * mw->mw_bar + off;
676 			PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar), val64);
677 			PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar) + 4, val64 >> 32);
678 		}
679 
680 		/* Set Virtual Interface BARs address translation */
681 		PNTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, addr);
682 		PNTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4 + 4, addr >> 32);
683 	} else {
684 		/* Make sure we fit into 32-bit address space. */
685 		if ((addr & UINT32_MAX) != addr)
686 			return (ERANGE);
687 		if (((addr + bsize) & UINT32_MAX) != (addr + bsize))
688 			return (ERANGE);
689 
690 		if (sc->b2b_mw >= 0) {
691 			/* Set Link Interface BAR size and enable/disable it. */
692 			val = 0;
693 			if (bsize > 0)
694 				val = (~(bsize - 1) & ~0xfffff);
695 			PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4, val);
696 
697 			/* Set Link Interface BAR address. */
698 			val64 = 0x20000000 * mw->mw_bar + off;
699 			PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar), val64);
700 		}
701 
702 		/* Set Virtual Interface BARs address translation */
703 		PNTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, addr);
704 	}
705 
706 	/* Configure and enable Link to Virtual A-LUT if we need it. */
707 	if (sc->alut && mw->mw_bar == 2 &&
708 	    ((addr & (bsize - 1)) != 0 || size != bsize)) {
709 		eaddr = addr;
710 		for (i = 0; i < 128 * sc->alut; i++) {
711 			val = sc->link ? 0 : 1;
712 			if (sc->alut == 1)
713 				val += 2 * sc->ntx;
714 			val *= 0x1000 * sc->alut;
715 			val += 0x38000 + i * 4 + (i >= 128 ? 0x0e00 : 0);
716 			bus_write_4(sc->conf_res, val, eaddr);
717 			bus_write_4(sc->conf_res, val + 0x400, eaddr >> 32);
718 			bus_write_4(sc->conf_res, val + 0x800,
719 			    (eaddr < addr + size) ? 0x3 : 0);
720 			eaddr += esize;
721 		}
722 		NTX_WRITE(sc, 0xc94, 0x10000000);
723 	} else if (sc->alut && mw->mw_bar == 2)
724 		NTX_WRITE(sc, 0xc94, 0);
725 
726 	return (0);
727 }
728 
729 static int
730 ntb_plx_mw_set_trans(device_t dev, unsigned mw_idx, bus_addr_t addr, size_t size)
731 {
732 	struct ntb_plx_softc *sc = device_get_softc(dev);
733 	struct ntb_plx_mw_info *mw;
734 
735 	if (mw_idx >= sc->mw_count)
736 		return (EINVAL);
737 	mw = &sc->mw_info[mw_idx];
738 	mw->mw_xlat_addr = addr;
739 	mw->mw_xlat_size = size;
740 	return (ntb_plx_mw_set_trans_internal(dev, mw_idx));
741 }
742 
743 static int
744 ntb_plx_mw_clear_trans(device_t dev, unsigned mw_idx)
745 {
746 
747 	return (ntb_plx_mw_set_trans(dev, mw_idx, 0, 0));
748 }
749 
750 static int
751 ntb_plx_mw_get_wc(device_t dev, unsigned idx, vm_memattr_t *mode)
752 {
753 	struct ntb_plx_softc *sc = device_get_softc(dev);
754 	struct ntb_plx_mw_info *mw;
755 
756 	if (idx >= sc->mw_count)
757 		return (EINVAL);
758 	mw = &sc->mw_info[idx];
759 	*mode = mw->mw_map_mode;
760 	return (0);
761 }
762 
763 static int
764 ntb_plx_mw_set_wc(device_t dev, unsigned idx, vm_memattr_t mode)
765 {
766 	struct ntb_plx_softc *sc = device_get_softc(dev);
767 	struct ntb_plx_mw_info *mw;
768 	uint64_t off;
769 	int rc;
770 
771 	if (idx >= sc->mw_count)
772 		return (EINVAL);
773 	mw = &sc->mw_info[idx];
774 	if (mw->mw_map_mode == mode)
775 		return (0);
776 
777 	off = 0;
778 	if (idx == sc->b2b_mw) {
779 		KASSERT(sc->b2b_off != 0,
780 		    ("user shouldn't get non-shared b2b mw"));
781 		off = sc->b2b_off;
782 	}
783 
784 	rc = pmap_change_attr((vm_offset_t)mw->mw_vbase + off,
785 	    mw->mw_size - off, mode);
786 	if (rc == 0)
787 		mw->mw_map_mode = mode;
788 	return (rc);
789 }
790 
791 static uint8_t
792 ntb_plx_spad_count(device_t dev)
793 {
794 	struct ntb_plx_softc *sc = device_get_softc(dev);
795 
796 	return (sc->spad_count1 + sc->spad_count2);
797 }
798 
799 static int
800 ntb_plx_spad_write(device_t dev, unsigned int idx, uint32_t val)
801 {
802 	struct ntb_plx_softc *sc = device_get_softc(dev);
803 	u_int off;
804 
805 	if (idx >= sc->spad_count1 + sc->spad_count2)
806 		return (EINVAL);
807 
808 	if (idx < sc->spad_count1)
809 		off = sc->spad_off1 + idx * 4;
810 	else
811 		off = sc->spad_off2 + (idx - sc->spad_count1) * 4;
812 	bus_write_4(sc->conf_res, off, val);
813 	return (0);
814 }
815 
816 static void
817 ntb_plx_spad_clear(device_t dev)
818 {
819 	struct ntb_plx_softc *sc = device_get_softc(dev);
820 	int i;
821 
822 	for (i = 0; i < sc->spad_count1 + sc->spad_count2; i++)
823 		ntb_plx_spad_write(dev, i, 0);
824 }
825 
826 static int
827 ntb_plx_spad_read(device_t dev, unsigned int idx, uint32_t *val)
828 {
829 	struct ntb_plx_softc *sc = device_get_softc(dev);
830 	u_int off;
831 
832 	if (idx >= sc->spad_count1 + sc->spad_count2)
833 		return (EINVAL);
834 
835 	if (idx < sc->spad_count1)
836 		off = sc->spad_off1 + idx * 4;
837 	else
838 		off = sc->spad_off2 + (idx - sc->spad_count1) * 4;
839 	*val = bus_read_4(sc->conf_res, off);
840 	return (0);
841 }
842 
843 static int
844 ntb_plx_peer_spad_write(device_t dev, unsigned int idx, uint32_t val)
845 {
846 	struct ntb_plx_softc *sc = device_get_softc(dev);
847 	u_int off;
848 
849 	if (idx >= sc->spad_count1 + sc->spad_count2)
850 		return (EINVAL);
851 
852 	if (idx < sc->spad_count1)
853 		off = sc->spad_offp1 + idx * 4;
854 	else
855 		off = sc->spad_offp2 + (idx - sc->spad_count1) * 4;
856 	if (sc->b2b_mw >= 0)
857 		bus_write_4(sc->mw_info[sc->b2b_mw].mw_res, off, val);
858 	else
859 		bus_write_4(sc->conf_res, off, val);
860 	return (0);
861 }
862 
863 static int
864 ntb_plx_peer_spad_read(device_t dev, unsigned int idx, uint32_t *val)
865 {
866 	struct ntb_plx_softc *sc = device_get_softc(dev);
867 	u_int off;
868 
869 	if (idx >= sc->spad_count1 + sc->spad_count2)
870 		return (EINVAL);
871 
872 	if (idx < sc->spad_count1)
873 		off = sc->spad_offp1 + idx * 4;
874 	else
875 		off = sc->spad_offp2 + (idx - sc->spad_count1) * 4;
876 	if (sc->b2b_mw >= 0)
877 		*val = bus_read_4(sc->mw_info[sc->b2b_mw].mw_res, off);
878 	else
879 		*val = bus_read_4(sc->conf_res, off);
880 	return (0);
881 }
882 
883 static uint64_t
884 ntb_plx_db_valid_mask(device_t dev)
885 {
886 
887 	return ((1LL << PLX_NUM_DB) - 1);
888 }
889 
890 static int
891 ntb_plx_db_vector_count(device_t dev)
892 {
893 
894 	return (1);
895 }
896 
897 static uint64_t
898 ntb_plx_db_vector_mask(device_t dev, uint32_t vector)
899 {
900 
901 	if (vector > 0)
902 		return (0);
903 	return ((1LL << PLX_NUM_DB) - 1);
904 }
905 
906 static void
907 ntb_plx_db_clear(device_t dev, uint64_t bits)
908 {
909 	struct ntb_plx_softc *sc = device_get_softc(dev);
910 
911 	NTX_WRITE(sc, sc->link ? 0xc60 : 0xc50, bits);
912 }
913 
914 static void
915 ntb_plx_db_clear_mask(device_t dev, uint64_t bits)
916 {
917 	struct ntb_plx_softc *sc = device_get_softc(dev);
918 
919 	NTX_WRITE(sc, sc->link ? 0xc68 : 0xc58, bits);
920 }
921 
922 static uint64_t
923 ntb_plx_db_read(device_t dev)
924 {
925 	struct ntb_plx_softc *sc = device_get_softc(dev);
926 
927 	return (NTX_READ(sc, sc->link ? 0xc5c : 0xc4c));
928 }
929 
930 static void
931 ntb_plx_db_set_mask(device_t dev, uint64_t bits)
932 {
933 	struct ntb_plx_softc *sc = device_get_softc(dev);
934 
935 	NTX_WRITE(sc, sc->link ? 0xc64 : 0xc54, bits);
936 }
937 
938 static int
939 ntb_plx_peer_db_addr(device_t dev, bus_addr_t *db_addr, vm_size_t *db_size)
940 {
941 	struct ntb_plx_softc *sc = device_get_softc(dev);
942 	struct ntb_plx_mw_info *mw;
943 
944 	KASSERT((db_addr != NULL && db_size != NULL), ("must be non-NULL"));
945 
946 	if (sc->b2b_mw >= 0) {
947 		mw = &sc->mw_info[sc->b2b_mw];
948 		*db_addr = (uint64_t)mw->mw_pbase + PLX_NTX_BASE(sc) + 0xc4c;
949 	} else {
950 		*db_addr = rman_get_start(sc->conf_res) + PLX_NTX_BASE(sc);
951 		*db_addr += sc->link ? 0xc4c : 0xc5c;
952 	}
953 	*db_size = 4;
954 	return (0);
955 }
956 
957 static void
958 ntb_plx_peer_db_set(device_t dev, uint64_t bit)
959 {
960 	struct ntb_plx_softc *sc = device_get_softc(dev);
961 
962 	if (sc->b2b_mw >= 0)
963 		BNTX_WRITE(sc, 0xc4c, bit);
964 	else
965 		NTX_WRITE(sc, sc->link ? 0xc4c : 0xc5c, bit);
966 }
967 
968 static device_method_t ntb_plx_methods[] = {
969 	/* Device interface */
970 	DEVMETHOD(device_probe,		ntb_plx_probe),
971 	DEVMETHOD(device_attach,	ntb_plx_attach),
972 	DEVMETHOD(device_detach,	ntb_plx_detach),
973 	/* Bus interface */
974 	DEVMETHOD(bus_child_location_str, ntb_child_location_str),
975 	DEVMETHOD(bus_print_child,	ntb_print_child),
976 	/* NTB interface */
977 	DEVMETHOD(ntb_link_is_up,	ntb_plx_link_is_up),
978 	DEVMETHOD(ntb_link_enable,	ntb_plx_link_enable),
979 	DEVMETHOD(ntb_link_disable,	ntb_plx_link_disable),
980 	DEVMETHOD(ntb_link_enabled,	ntb_plx_link_enabled),
981 	DEVMETHOD(ntb_mw_count,		ntb_plx_mw_count),
982 	DEVMETHOD(ntb_mw_get_range,	ntb_plx_mw_get_range),
983 	DEVMETHOD(ntb_mw_set_trans,	ntb_plx_mw_set_trans),
984 	DEVMETHOD(ntb_mw_clear_trans,	ntb_plx_mw_clear_trans),
985 	DEVMETHOD(ntb_mw_get_wc,	ntb_plx_mw_get_wc),
986 	DEVMETHOD(ntb_mw_set_wc,	ntb_plx_mw_set_wc),
987 	DEVMETHOD(ntb_spad_count,	ntb_plx_spad_count),
988 	DEVMETHOD(ntb_spad_clear,	ntb_plx_spad_clear),
989 	DEVMETHOD(ntb_spad_write,	ntb_plx_spad_write),
990 	DEVMETHOD(ntb_spad_read,	ntb_plx_spad_read),
991 	DEVMETHOD(ntb_peer_spad_write,	ntb_plx_peer_spad_write),
992 	DEVMETHOD(ntb_peer_spad_read,	ntb_plx_peer_spad_read),
993 	DEVMETHOD(ntb_db_valid_mask,	ntb_plx_db_valid_mask),
994 	DEVMETHOD(ntb_db_vector_count,	ntb_plx_db_vector_count),
995 	DEVMETHOD(ntb_db_vector_mask,	ntb_plx_db_vector_mask),
996 	DEVMETHOD(ntb_db_clear,		ntb_plx_db_clear),
997 	DEVMETHOD(ntb_db_clear_mask,	ntb_plx_db_clear_mask),
998 	DEVMETHOD(ntb_db_read,		ntb_plx_db_read),
999 	DEVMETHOD(ntb_db_set_mask,	ntb_plx_db_set_mask),
1000 	DEVMETHOD(ntb_peer_db_addr,	ntb_plx_peer_db_addr),
1001 	DEVMETHOD(ntb_peer_db_set,	ntb_plx_peer_db_set),
1002 	DEVMETHOD_END
1003 };
1004 
1005 static DEFINE_CLASS_0(ntb_hw, ntb_plx_driver, ntb_plx_methods,
1006     sizeof(struct ntb_plx_softc));
1007 DRIVER_MODULE(ntb_hw_plx, pci, ntb_plx_driver, ntb_hw_devclass, NULL, NULL);
1008 MODULE_DEPEND(ntb_hw_plx, ntb, 1, 1, 1);
1009 MODULE_VERSION(ntb_hw_plx, 1);
1010