xref: /freebsd/sys/dev/ntb/ntb_hw/ntb_hw_amd.c (revision 4d846d26)
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license.  When using or
3  * redistributing this file, you may do so under either license.
4  *
5  * GPL LICENSE SUMMARY
6  *
7  * Copyright (C) 2019 Advanced Micro Devices, Inc.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of version 2 of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * BSD LICENSE
14  *
15  * Copyright (c) 2019 Advanced Micro Devices, Inc.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  * 3. Neither the name of AMD corporation nor the names of its
26  *    contributors may be used to endorse or promote products derived
27  *    from this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  * Contact Information :
42  * Rajesh Kumar <rajesh1.kumar@amd.com>
43  */
44 
45 /*
46  * The Non-Transparent Bridge (NTB) is a device that allows you to connect
47  * two or more systems using a PCI-e links, providing remote memory access.
48  *
49  * This module contains a driver for NTB hardware in AMD CPUs
50  *
51  * Much of the code in this module is shared with Linux. Any patches may
52  * be picked up and redistributed in Linux with a dual GPL/BSD license.
53  */
54 
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
57 
58 #include <sys/param.h>
59 #include <sys/kernel.h>
60 #include <sys/systm.h>
61 #include <sys/bus.h>
62 #include <sys/lock.h>
63 #include <sys/malloc.h>
64 #include <sys/module.h>
65 #include <sys/mutex.h>
66 #include <sys/rman.h>
67 #include <sys/sbuf.h>
68 #include <sys/sysctl.h>
69 
70 #include <vm/vm.h>
71 #include <vm/pmap.h>
72 
73 #include <machine/bus.h>
74 
75 #include <dev/pci/pcireg.h>
76 #include <dev/pci/pcivar.h>
77 
78 #include "ntb_hw_amd.h"
79 #include "dev/ntb/ntb.h"
80 
81 MALLOC_DEFINE(M_AMD_NTB, "amd_ntb_hw", "amd_ntb_hw driver memory allocations");
82 
83 static const struct amd_ntb_hw_info amd_ntb_hw_info_list[] = {
84 	{ .vendor_id = NTB_HW_AMD_VENDOR_ID,
85 	  .device_id = NTB_HW_AMD_DEVICE_ID1,
86 	  .mw_count = 3,
87 	  .bar_start_idx = 1,
88 	  .spad_count = 16,
89 	  .db_count = 16,
90 	  .msix_vector_count = 24,
91 	  .quirks = QUIRK_MW0_32BIT,
92 	  .desc = "AMD Non-Transparent Bridge"},
93 
94 	{ .vendor_id = NTB_HW_AMD_VENDOR_ID,
95 	  .device_id = NTB_HW_AMD_DEVICE_ID2,
96 	  .mw_count = 2,
97 	  .bar_start_idx = 2,
98 	  .spad_count = 16,
99 	  .db_count = 16,
100 	  .msix_vector_count = 24,
101 	  .quirks = 0,
102 	  .desc = "AMD Non-Transparent Bridge"},
103 
104 	{ .vendor_id = NTB_HW_HYGON_VENDOR_ID,
105 	  .device_id = NTB_HW_HYGON_DEVICE_ID1,
106 	  .mw_count = 3,
107 	  .bar_start_idx = 1,
108 	  .spad_count = 16,
109 	  .db_count = 16,
110 	  .msix_vector_count = 24,
111 	  .quirks = QUIRK_MW0_32BIT,
112 	  .desc = "Hygon Non-Transparent Bridge"},
113 };
114 
115 static const struct pci_device_table amd_ntb_devs[] = {
116 	{ PCI_DEV(NTB_HW_AMD_VENDOR_ID, NTB_HW_AMD_DEVICE_ID1),
117 	  .driver_data = (uintptr_t)&amd_ntb_hw_info_list[0],
118 	  PCI_DESCR("AMD Non-Transparent Bridge") },
119 	{ PCI_DEV(NTB_HW_AMD_VENDOR_ID, NTB_HW_AMD_DEVICE_ID2),
120 	  .driver_data = (uintptr_t)&amd_ntb_hw_info_list[1],
121 	  PCI_DESCR("AMD Non-Transparent Bridge") },
122 	{ PCI_DEV(NTB_HW_HYGON_VENDOR_ID, NTB_HW_HYGON_DEVICE_ID1),
123 	  .driver_data = (uintptr_t)&amd_ntb_hw_info_list[0],
124 	  PCI_DESCR("Hygon Non-Transparent Bridge") }
125 };
126 
127 static unsigned g_amd_ntb_hw_debug_level;
128 SYSCTL_UINT(_hw_ntb, OID_AUTO, debug_level, CTLFLAG_RWTUN,
129     &g_amd_ntb_hw_debug_level, 0, "amd_ntb_hw log level -- higher is verbose");
130 
131 #define amd_ntb_printf(lvl, ...) do {				\
132         if (lvl <= g_amd_ntb_hw_debug_level)			\
133                 device_printf(ntb->device, __VA_ARGS__);	\
134 } while (0)
135 
136 #ifdef __i386__
137 static __inline uint64_t
138 bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
139     bus_size_t offset)
140 {
141 
142 	return (bus_space_read_4(tag, handle, offset) |
143 	    ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32);
144 }
145 
146 static __inline void
147 bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t handle,
148     bus_size_t offset, uint64_t val)
149 {
150 
151 	bus_space_write_4(tag, handle, offset, val);
152 	bus_space_write_4(tag, handle, offset + 4, val >> 32);
153 }
154 #endif
155 
156 /*
157  * AMD NTB INTERFACE ROUTINES
158  */
159 static int
160 amd_ntb_port_number(device_t dev)
161 {
162 	struct amd_ntb_softc *ntb = device_get_softc(dev);
163 
164 	amd_ntb_printf(1, "%s: conn_type %d\n", __func__, ntb->conn_type);
165 
166 	switch (ntb->conn_type) {
167 	case NTB_CONN_PRI:
168 		return (NTB_PORT_PRI_USD);
169 	case NTB_CONN_SEC:
170 		return (NTB_PORT_SEC_DSD);
171 	default:
172 		break;
173 	}
174 
175 	return (-EINVAL);
176 }
177 
178 static int
179 amd_ntb_peer_port_count(device_t dev)
180 {
181 	struct amd_ntb_softc *ntb = device_get_softc(dev);
182 
183 	amd_ntb_printf(1, "%s: peer cnt %d\n", __func__, NTB_DEF_PEER_CNT);
184 	return (NTB_DEF_PEER_CNT);
185 }
186 
187 static int
188 amd_ntb_peer_port_number(device_t dev, int pidx)
189 {
190 	struct amd_ntb_softc *ntb = device_get_softc(dev);
191 
192 	amd_ntb_printf(1, "%s: pidx %d conn type %d\n",
193 	    __func__, pidx, ntb->conn_type);
194 
195 	if (pidx != NTB_DEF_PEER_IDX)
196 		return (-EINVAL);
197 
198 	switch (ntb->conn_type) {
199 	case NTB_CONN_PRI:
200 		return (NTB_PORT_SEC_DSD);
201 	case NTB_CONN_SEC:
202 		return (NTB_PORT_PRI_USD);
203 	default:
204 		break;
205 	}
206 
207 	return (-EINVAL);
208 }
209 
210 static int
211 amd_ntb_peer_port_idx(device_t dev, int port)
212 {
213 	struct amd_ntb_softc *ntb = device_get_softc(dev);
214 	int peer_port;
215 
216 	peer_port = amd_ntb_peer_port_number(dev, NTB_DEF_PEER_IDX);
217 
218 	amd_ntb_printf(1, "%s: port %d peer_port %d\n",
219 	    __func__, port, peer_port);
220 
221 	if (peer_port == -EINVAL || port != peer_port)
222 		return (-EINVAL);
223 
224 	return (0);
225 }
226 
227 /*
228  * AMD NTB INTERFACE - LINK ROUTINES
229  */
230 static inline int
231 amd_link_is_up(struct amd_ntb_softc *ntb)
232 {
233 
234 	amd_ntb_printf(2, "%s: peer_sta 0x%x cntl_sta 0x%x\n",
235 	    __func__, ntb->peer_sta, ntb->cntl_sta);
236 
237 	if (!ntb->peer_sta)
238 		return (NTB_LNK_STA_ACTIVE(ntb->cntl_sta));
239 
240 	return (0);
241 }
242 
243 static inline enum ntb_speed
244 amd_ntb_link_sta_speed(struct amd_ntb_softc *ntb)
245 {
246 
247 	if (!amd_link_is_up(ntb))
248 		return (NTB_SPEED_NONE);
249 
250 	return (NTB_LNK_STA_SPEED(ntb->lnk_sta));
251 }
252 
253 static inline enum ntb_width
254 amd_ntb_link_sta_width(struct amd_ntb_softc *ntb)
255 {
256 
257 	if (!amd_link_is_up(ntb))
258 		return (NTB_WIDTH_NONE);
259 
260 	return (NTB_LNK_STA_WIDTH(ntb->lnk_sta));
261 }
262 
263 static bool
264 amd_ntb_link_is_up(device_t dev, enum ntb_speed *speed, enum ntb_width *width)
265 {
266 	struct amd_ntb_softc *ntb = device_get_softc(dev);
267 
268 	if (speed != NULL)
269 		*speed = amd_ntb_link_sta_speed(ntb);
270 	if (width != NULL)
271 		*width = amd_ntb_link_sta_width(ntb);
272 
273 	return (amd_link_is_up(ntb));
274 }
275 
276 static int
277 amd_ntb_link_enable(device_t dev, enum ntb_speed max_speed,
278     enum ntb_width max_width)
279 {
280 	struct amd_ntb_softc *ntb = device_get_softc(dev);
281 	uint32_t ntb_ctl;
282 
283 	amd_ntb_printf(1, "%s: int_mask 0x%x conn_type %d\n",
284 	    __func__, ntb->int_mask, ntb->conn_type);
285 
286 	amd_init_side_info(ntb);
287 
288 	/* Enable event interrupt */
289 	ntb->int_mask &= ~AMD_EVENT_INTMASK;
290 	amd_ntb_reg_write(4, AMD_INTMASK_OFFSET, ntb->int_mask);
291 
292 	if (ntb->conn_type == NTB_CONN_SEC)
293 		return (EINVAL);
294 
295 	amd_ntb_printf(0, "%s: Enabling Link.\n", __func__);
296 
297 	ntb_ctl = amd_ntb_reg_read(4, AMD_CNTL_OFFSET);
298 	ntb_ctl |= (PMM_REG_CTL | SMM_REG_CTL);
299 	amd_ntb_printf(1, "%s: ntb_ctl 0x%x\n", __func__, ntb_ctl);
300 	amd_ntb_reg_write(4, AMD_CNTL_OFFSET, ntb_ctl);
301 
302 	return (0);
303 }
304 
305 static int
306 amd_ntb_link_disable(device_t dev)
307 {
308 	struct amd_ntb_softc *ntb = device_get_softc(dev);
309 	uint32_t ntb_ctl;
310 
311 	amd_ntb_printf(1, "%s: int_mask 0x%x conn_type %d\n",
312 	    __func__, ntb->int_mask, ntb->conn_type);
313 
314 	amd_deinit_side_info(ntb);
315 
316 	/* Disable event interrupt */
317 	ntb->int_mask |= AMD_EVENT_INTMASK;
318 	amd_ntb_reg_write(4, AMD_INTMASK_OFFSET, ntb->int_mask);
319 
320 	if (ntb->conn_type == NTB_CONN_SEC)
321 		return (EINVAL);
322 
323 	amd_ntb_printf(0, "%s: Disabling Link.\n", __func__);
324 
325 	ntb_ctl = amd_ntb_reg_read(4, AMD_CNTL_OFFSET);
326 	ntb_ctl &= ~(PMM_REG_CTL | SMM_REG_CTL);
327 	amd_ntb_printf(1, "%s: ntb_ctl 0x%x\n", __func__, ntb_ctl);
328 	amd_ntb_reg_write(4, AMD_CNTL_OFFSET, ntb_ctl);
329 
330 	return (0);
331 }
332 
333 /*
334  * AMD NTB memory window routines
335  */
336 static uint8_t
337 amd_ntb_mw_count(device_t dev)
338 {
339 	struct amd_ntb_softc *ntb = device_get_softc(dev);
340 
341 	return (ntb->hw_info->mw_count);
342 }
343 
344 static int
345 amd_ntb_mw_get_range(device_t dev, unsigned mw_idx, vm_paddr_t *base,
346     caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
347     bus_addr_t *plimit)
348 {
349 	struct amd_ntb_softc *ntb = device_get_softc(dev);
350 	struct amd_ntb_pci_bar_info *bar_info;
351 
352 	if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
353 		return (EINVAL);
354 
355 	bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
356 
357 	if (base != NULL)
358 		*base = bar_info->pbase;
359 
360 	if (vbase != NULL)
361 		*vbase = bar_info->vbase;
362 
363 	if (align != NULL)
364 		*align = bar_info->size;
365 
366 	if (size != NULL)
367 		*size = bar_info->size;
368 
369 	if (align_size != NULL)
370 		*align_size = 1;
371 
372 	if (plimit != NULL) {
373 		/*
374 		 * For Device ID 0x145B (which has 3 memory windows),
375 		 * memory window 0 use a 32-bit bar. The remaining
376 		 * cases all use 64-bit bar.
377 		 */
378 		if ((mw_idx == 0) && (ntb->hw_info->quirks & QUIRK_MW0_32BIT))
379 			*plimit = BUS_SPACE_MAXADDR_32BIT;
380 		else
381 			*plimit = BUS_SPACE_MAXADDR;
382 	}
383 
384 	return (0);
385 }
386 
387 static int
388 amd_ntb_mw_set_trans(device_t dev, unsigned mw_idx, bus_addr_t addr, size_t size)
389 {
390 	struct amd_ntb_softc *ntb = device_get_softc(dev);
391 	struct amd_ntb_pci_bar_info *bar_info;
392 
393 	if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
394 		return (EINVAL);
395 
396 	bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
397 
398 	/* Make sure the range fits in the usable mw size. */
399 	if (size > bar_info->size) {
400 		amd_ntb_printf(0, "%s: size 0x%jx greater than mw_size 0x%jx\n",
401 		    __func__, (uintmax_t)size, (uintmax_t)bar_info->size);
402 		return (EINVAL);
403 	}
404 
405 	amd_ntb_printf(1, "%s: mw %d mw_size 0x%jx size 0x%jx base %p\n",
406 	    __func__, mw_idx, (uintmax_t)bar_info->size,
407 	    (uintmax_t)size, (void *)bar_info->pci_bus_handle);
408 
409 	/*
410 	 * AMD NTB XLAT and Limit registers needs to be written only after
411 	 * link enable.
412 	 *
413 	 * Set and verify setting the translation address register.
414 	 */
415 	amd_ntb_peer_reg_write(8, bar_info->xlat_off, (uint64_t)addr);
416 	amd_ntb_printf(0, "%s: mw %d xlat_off 0x%x cur_val 0x%jx addr %p\n",
417 	    __func__, mw_idx, bar_info->xlat_off,
418 	    amd_ntb_peer_reg_read(8, bar_info->xlat_off), (void *)addr);
419 
420 	/*
421 	 * Set and verify setting the limit register.
422 	 *
423 	 * For Device ID 0x145B (which has 3 memory windows),
424 	 * memory window 0 use a 32-bit bar. The remaining
425 	 * cases all use 64-bit bar.
426 	 */
427 	if ((mw_idx == 0) && (ntb->hw_info->quirks & QUIRK_MW0_32BIT)) {
428 		amd_ntb_reg_write(4, bar_info->limit_off, (uint32_t)size);
429 		amd_ntb_printf(1, "%s: limit_off 0x%x cur_val 0x%x limit 0x%x\n",
430 		    __func__, bar_info->limit_off,
431 		    amd_ntb_peer_reg_read(4, bar_info->limit_off),
432 		    (uint32_t)size);
433 	} else {
434 		amd_ntb_reg_write(8, bar_info->limit_off, (uint64_t)size);
435 		amd_ntb_printf(1, "%s: limit_off 0x%x cur_val 0x%jx limit 0x%jx\n",
436 		    __func__, bar_info->limit_off,
437 		    amd_ntb_peer_reg_read(8, bar_info->limit_off),
438 		    (uintmax_t)size);
439 	}
440 
441 	return (0);
442 }
443 
444 static int
445 amd_ntb_mw_clear_trans(device_t dev, unsigned mw_idx)
446 {
447 	struct amd_ntb_softc *ntb = device_get_softc(dev);
448 
449 	amd_ntb_printf(1, "%s: mw_idx %d\n", __func__, mw_idx);
450 
451 	if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
452 		return (EINVAL);
453 
454 	return (amd_ntb_mw_set_trans(dev, mw_idx, 0, 0));
455 }
456 
457 static int
458 amd_ntb_mw_set_wc(device_t dev, unsigned int mw_idx, vm_memattr_t mode)
459 {
460 	struct amd_ntb_softc *ntb = device_get_softc(dev);
461 	struct amd_ntb_pci_bar_info *bar_info;
462 	int rc;
463 
464 	if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
465 		return (EINVAL);
466 
467 	bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
468 	if (mode == bar_info->map_mode)
469 		return (0);
470 
471 	rc = pmap_change_attr((vm_offset_t)bar_info->vbase, bar_info->size, mode);
472 	if (rc == 0)
473 		bar_info->map_mode = mode;
474 
475 	return (rc);
476 }
477 
478 static int
479 amd_ntb_mw_get_wc(device_t dev, unsigned mw_idx, vm_memattr_t *mode)
480 {
481 	struct amd_ntb_softc *ntb = device_get_softc(dev);
482 	struct amd_ntb_pci_bar_info *bar_info;
483 
484 	amd_ntb_printf(1, "%s: mw_idx %d\n", __func__, mw_idx);
485 
486 	if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
487 		return (EINVAL);
488 
489 	bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
490 	*mode = bar_info->map_mode;
491 
492 	return (0);
493 }
494 
495 /*
496  * AMD NTB doorbell routines
497  */
498 static int
499 amd_ntb_db_vector_count(device_t dev)
500 {
501 	struct amd_ntb_softc *ntb = device_get_softc(dev);
502 
503 	amd_ntb_printf(1, "%s: db_count 0x%x\n", __func__,
504 	    ntb->hw_info->db_count);
505 
506 	return (ntb->hw_info->db_count);
507 }
508 
509 static uint64_t
510 amd_ntb_db_valid_mask(device_t dev)
511 {
512 	struct amd_ntb_softc *ntb = device_get_softc(dev);
513 
514 	amd_ntb_printf(1, "%s: db_valid_mask 0x%x\n",
515 	    __func__, ntb->db_valid_mask);
516 
517 	return (ntb->db_valid_mask);
518 }
519 
520 static uint64_t
521 amd_ntb_db_vector_mask(device_t dev, uint32_t vector)
522 {
523 	struct amd_ntb_softc *ntb = device_get_softc(dev);
524 
525 	amd_ntb_printf(1, "%s: vector %d db_count 0x%x db_valid_mask 0x%x\n",
526 	    __func__, vector, ntb->hw_info->db_count, ntb->db_valid_mask);
527 
528 	if (vector < 0 || vector >= ntb->hw_info->db_count)
529 		return (0);
530 
531 	return (ntb->db_valid_mask & (1 << vector));
532 }
533 
534 static uint64_t
535 amd_ntb_db_read(device_t dev)
536 {
537 	struct amd_ntb_softc *ntb = device_get_softc(dev);
538 	uint64_t dbstat_off;
539 
540 	dbstat_off = (uint64_t)amd_ntb_reg_read(2, AMD_DBSTAT_OFFSET);
541 
542 	amd_ntb_printf(1, "%s: dbstat_off 0x%jx\n", __func__, dbstat_off);
543 
544 	return (dbstat_off);
545 }
546 
547 static void
548 amd_ntb_db_clear(device_t dev, uint64_t db_bits)
549 {
550 	struct amd_ntb_softc *ntb = device_get_softc(dev);
551 
552 	amd_ntb_printf(1, "%s: db_bits 0x%jx\n", __func__, db_bits);
553 	amd_ntb_reg_write(2, AMD_DBSTAT_OFFSET, (uint16_t)db_bits);
554 }
555 
556 static void
557 amd_ntb_db_set_mask(device_t dev, uint64_t db_bits)
558 {
559 	struct amd_ntb_softc *ntb = device_get_softc(dev);
560 
561 	DB_MASK_LOCK(ntb);
562 	amd_ntb_printf(1, "%s: db_mask 0x%x db_bits 0x%jx\n",
563 	    __func__, ntb->db_mask, db_bits);
564 
565 	ntb->db_mask |= db_bits;
566 	amd_ntb_reg_write(2, AMD_DBMASK_OFFSET, ntb->db_mask);
567 	DB_MASK_UNLOCK(ntb);
568 }
569 
570 static void
571 amd_ntb_db_clear_mask(device_t dev, uint64_t db_bits)
572 {
573 	struct amd_ntb_softc *ntb = device_get_softc(dev);
574 
575 	DB_MASK_LOCK(ntb);
576 	amd_ntb_printf(1, "%s: db_mask 0x%x db_bits 0x%jx\n",
577 	    __func__, ntb->db_mask, db_bits);
578 
579 	ntb->db_mask &= ~db_bits;
580 	amd_ntb_reg_write(2, AMD_DBMASK_OFFSET, ntb->db_mask);
581 	DB_MASK_UNLOCK(ntb);
582 }
583 
584 static void
585 amd_ntb_peer_db_set(device_t dev, uint64_t db_bits)
586 {
587 	struct amd_ntb_softc *ntb = device_get_softc(dev);
588 
589 	amd_ntb_printf(1, "%s: db_bits 0x%jx\n", __func__, db_bits);
590 	amd_ntb_reg_write(2, AMD_DBREQ_OFFSET, (uint16_t)db_bits);
591 }
592 
593 /*
594  * AMD NTB scratchpad routines
595  */
596 static uint8_t
597 amd_ntb_spad_count(device_t dev)
598 {
599 	struct amd_ntb_softc *ntb = device_get_softc(dev);
600 
601 	amd_ntb_printf(1, "%s: spad_count 0x%x\n", __func__,
602 	    ntb->spad_count);
603 
604 	return (ntb->spad_count);
605 }
606 
607 static int
608 amd_ntb_spad_read(device_t dev, unsigned int idx, uint32_t *val)
609 {
610 	struct amd_ntb_softc *ntb = device_get_softc(dev);
611 	uint32_t offset;
612 
613 	amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
614 
615 	if (idx < 0 || idx >= ntb->spad_count)
616 		return (EINVAL);
617 
618 	offset = ntb->self_spad + (idx << 2);
619 	*val = amd_ntb_reg_read(4, AMD_SPAD_OFFSET + offset);
620 	amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, *val);
621 
622 	return (0);
623 }
624 
625 static int
626 amd_ntb_spad_write(device_t dev, unsigned int idx, uint32_t val)
627 {
628 	struct amd_ntb_softc *ntb = device_get_softc(dev);
629 	uint32_t offset;
630 
631 	amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
632 
633 	if (idx < 0 || idx >= ntb->spad_count)
634 		return (EINVAL);
635 
636 	offset = ntb->self_spad + (idx << 2);
637 	amd_ntb_reg_write(4, AMD_SPAD_OFFSET + offset, val);
638 	amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, val);
639 
640 	return (0);
641 }
642 
643 static void
644 amd_ntb_spad_clear(struct amd_ntb_softc *ntb)
645 {
646 	uint8_t i;
647 
648 	for (i = 0; i < ntb->spad_count; i++)
649 		amd_ntb_spad_write(ntb->device, i, 0);
650 }
651 
652 static int
653 amd_ntb_peer_spad_read(device_t dev, unsigned int idx, uint32_t *val)
654 {
655 	struct amd_ntb_softc *ntb = device_get_softc(dev);
656 	uint32_t offset;
657 
658 	amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
659 
660 	if (idx < 0 || idx >= ntb->spad_count)
661 		return (EINVAL);
662 
663 	offset = ntb->peer_spad + (idx << 2);
664 	*val = amd_ntb_reg_read(4, AMD_SPAD_OFFSET + offset);
665 	amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, *val);
666 
667 	return (0);
668 }
669 
670 static int
671 amd_ntb_peer_spad_write(device_t dev, unsigned int idx, uint32_t val)
672 {
673 	struct amd_ntb_softc *ntb = device_get_softc(dev);
674 	uint32_t offset;
675 
676 	amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
677 
678 	if (idx < 0 || idx >= ntb->spad_count)
679 		return (EINVAL);
680 
681 	offset = ntb->peer_spad + (idx << 2);
682 	amd_ntb_reg_write(4, AMD_SPAD_OFFSET + offset, val);
683 	amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, val);
684 
685 	return (0);
686 }
687 
688 /*
689  * AMD NTB INIT
690  */
691 static int
692 amd_ntb_hw_info_handler(SYSCTL_HANDLER_ARGS)
693 {
694 	struct amd_ntb_softc* ntb = arg1;
695 	struct sbuf *sb;
696 	int rc = 0;
697 
698 	sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req);
699 	if (sb == NULL)
700 		return (sb->s_error);
701 
702 	sbuf_printf(sb, "NTB AMD Hardware info:\n\n");
703 	sbuf_printf(sb, "AMD NTB side: %s\n",
704 	    (ntb->conn_type == NTB_CONN_PRI)? "PRIMARY" : "SECONDARY");
705 	sbuf_printf(sb, "AMD LNK STA: 0x%#06x\n", ntb->lnk_sta);
706 
707 	if (!amd_link_is_up(ntb))
708 		sbuf_printf(sb, "AMD Link Status: Down\n");
709 	else {
710 		sbuf_printf(sb, "AMD Link Status: Up\n");
711 		sbuf_printf(sb, "AMD Link Speed: PCI-E Gen %u\n",
712 		    NTB_LNK_STA_SPEED(ntb->lnk_sta));
713 		sbuf_printf(sb, "AMD Link Width: PCI-E Width %u\n",
714 		    NTB_LNK_STA_WIDTH(ntb->lnk_sta));
715 	}
716 
717 	sbuf_printf(sb, "AMD Memory window count: %d\n",
718 	    ntb->hw_info->mw_count);
719 	sbuf_printf(sb, "AMD Spad count: %d\n",
720 	    ntb->spad_count);
721 	sbuf_printf(sb, "AMD Doorbell count: %d\n",
722 	    ntb->hw_info->db_count);
723 	sbuf_printf(sb, "AMD MSI-X vec count: %d\n\n",
724 	    ntb->msix_vec_count);
725 	sbuf_printf(sb, "AMD Doorbell valid mask: 0x%x\n",
726 	    ntb->db_valid_mask);
727 	sbuf_printf(sb, "AMD Doorbell Mask: 0x%x\n",
728 	    amd_ntb_reg_read(4, AMD_DBMASK_OFFSET));
729 	sbuf_printf(sb, "AMD Doorbell: 0x%x\n",
730 	    amd_ntb_reg_read(4, AMD_DBSTAT_OFFSET));
731 	sbuf_printf(sb, "AMD NTB Incoming XLAT: \n");
732 	sbuf_printf(sb, "AMD XLAT1: 0x%jx\n",
733 	    amd_ntb_peer_reg_read(8, AMD_BAR1XLAT_OFFSET));
734 	sbuf_printf(sb, "AMD XLAT23: 0x%jx\n",
735 	    amd_ntb_peer_reg_read(8, AMD_BAR23XLAT_OFFSET));
736 	sbuf_printf(sb, "AMD XLAT45: 0x%jx\n",
737 	    amd_ntb_peer_reg_read(8, AMD_BAR45XLAT_OFFSET));
738 	sbuf_printf(sb, "AMD LMT1: 0x%x\n",
739 	    amd_ntb_reg_read(4, AMD_BAR1LMT_OFFSET));
740 	sbuf_printf(sb, "AMD LMT23: 0x%jx\n",
741 	    amd_ntb_reg_read(8, AMD_BAR23LMT_OFFSET));
742 	sbuf_printf(sb, "AMD LMT45: 0x%jx\n",
743 	    amd_ntb_reg_read(8, AMD_BAR45LMT_OFFSET));
744 
745 	rc = sbuf_finish(sb);
746 	sbuf_delete(sb);
747 	return (rc);
748 }
749 
750 static void
751 amd_ntb_sysctl_init(struct amd_ntb_softc *ntb)
752 {
753 	struct sysctl_oid_list *globals;
754 	struct sysctl_ctx_list *ctx;
755 
756 	ctx = device_get_sysctl_ctx(ntb->device);
757 	globals = SYSCTL_CHILDREN(device_get_sysctl_tree(ntb->device));
758 
759 	SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "info",
760 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, ntb, 0,
761 	    amd_ntb_hw_info_handler, "A", "AMD NTB HW Information");
762 }
763 
764 /*
765  * Polls the HW link status register(s); returns true if something has changed.
766  */
767 static bool
768 amd_ntb_poll_link(struct amd_ntb_softc *ntb)
769 {
770 	uint32_t fullreg, reg, stat;
771 
772 	fullreg = amd_ntb_peer_reg_read(4, AMD_SIDEINFO_OFFSET);
773 	reg = fullreg & NTB_LIN_STA_ACTIVE_BIT;
774 
775 	if (reg == ntb->cntl_sta)
776 		return (false);
777 
778 	amd_ntb_printf(0, "%s: SIDEINFO reg_val = 0x%x cntl_sta 0x%x\n",
779 	    __func__, fullreg, ntb->cntl_sta);
780 
781 	ntb->cntl_sta = reg;
782 
783 	stat = pci_read_config(ntb->device, AMD_LINK_STATUS_OFFSET, 4);
784 
785 	amd_ntb_printf(0, "%s: LINK_STATUS stat = 0x%x lnk_sta 0x%x.\n",
786 	    __func__, stat, ntb->lnk_sta);
787 
788 	ntb->lnk_sta = stat;
789 
790 	return (true);
791 }
792 
793 static void
794 amd_link_hb(void *arg)
795 {
796 	struct amd_ntb_softc *ntb = arg;
797 
798 	if (amd_ntb_poll_link(ntb))
799 		ntb_link_event(ntb->device);
800 
801 	if (!amd_link_is_up(ntb)) {
802 		callout_reset(&ntb->hb_timer, AMD_LINK_HB_TIMEOUT,
803 		    amd_link_hb, ntb);
804 	} else {
805 		callout_reset(&ntb->hb_timer, (AMD_LINK_HB_TIMEOUT * 10),
806 		    amd_link_hb, ntb);
807 	}
808 }
809 
810 static void
811 amd_ntb_interrupt(struct amd_ntb_softc *ntb, uint16_t vec)
812 {
813 	if (vec < ntb->hw_info->db_count)
814 		ntb_db_event(ntb->device, vec);
815 	else
816 		amd_ntb_printf(0, "Invalid vector %d\n", vec);
817 }
818 
819 static void
820 amd_ntb_vec_isr(void *arg)
821 {
822 	struct amd_ntb_vec *nvec = arg;
823 
824 	amd_ntb_interrupt(nvec->ntb, nvec->num);
825 }
826 
827 static void
828 amd_ntb_irq_isr(void *arg)
829 {
830 	/* If we couldn't set up MSI-X, we only have the one vector. */
831 	amd_ntb_interrupt(arg, 0);
832 }
833 
834 static void
835 amd_init_side_info(struct amd_ntb_softc *ntb)
836 {
837 	unsigned int reg;
838 
839 	reg = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
840 	if (!(reg & AMD_SIDE_READY)) {
841 		reg |= AMD_SIDE_READY;
842 		amd_ntb_reg_write(4, AMD_SIDEINFO_OFFSET, reg);
843 	}
844 	reg = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
845 }
846 
847 static void
848 amd_deinit_side_info(struct amd_ntb_softc *ntb)
849 {
850 	unsigned int reg;
851 
852 	reg = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
853 	if (reg & AMD_SIDE_READY) {
854 		reg &= ~AMD_SIDE_READY;
855 		amd_ntb_reg_write(4, AMD_SIDEINFO_OFFSET, reg);
856 		amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
857 	}
858 }
859 
860 static int
861 amd_ntb_setup_isr(struct amd_ntb_softc *ntb, uint16_t num_vectors, bool msi,
862     bool intx)
863 {
864 	uint16_t i;
865 	int flags = 0, rc = 0;
866 
867 	flags |= RF_ACTIVE;
868 	if (intx)
869 		flags |= RF_SHAREABLE;
870 
871 	for (i = 0; i < num_vectors; i++) {
872 		/* RID should be 0 for intx */
873 		if (intx)
874 			ntb->int_info[i].rid = i;
875 		else
876 			ntb->int_info[i].rid = i + 1;
877 
878 		ntb->int_info[i].res = bus_alloc_resource_any(ntb->device,
879 		    SYS_RES_IRQ, &ntb->int_info[i].rid, flags);
880 		if (ntb->int_info[i].res == NULL) {
881 			amd_ntb_printf(0, "bus_alloc_resource IRQ failed\n");
882 			return (ENOMEM);
883 		}
884 
885 		ntb->int_info[i].tag = NULL;
886 		ntb->allocated_interrupts++;
887 
888 		if (msi || intx) {
889 			rc = bus_setup_intr(ntb->device, ntb->int_info[i].res,
890 			    INTR_MPSAFE | INTR_TYPE_MISC, NULL, amd_ntb_irq_isr,
891 			    ntb, &ntb->int_info[i].tag);
892 		} else {
893 			rc = bus_setup_intr(ntb->device, ntb->int_info[i].res,
894 			    INTR_MPSAFE | INTR_TYPE_MISC, NULL, amd_ntb_vec_isr,
895 			    &ntb->msix_vec[i], &ntb->int_info[i].tag);
896 		}
897 
898 		if (rc != 0) {
899 			amd_ntb_printf(0, "bus_setup_intr %d failed\n", i);
900 			return (ENXIO);
901 		}
902 	}
903 
904 	return (0);
905 }
906 
907 static int
908 amd_ntb_create_msix_vec(struct amd_ntb_softc *ntb, uint32_t max_vectors)
909 {
910 	uint8_t i;
911 
912 	ntb->msix_vec = malloc(max_vectors * sizeof(*ntb->msix_vec), M_AMD_NTB,
913 	    M_ZERO | M_WAITOK);
914 
915 	for (i = 0; i < max_vectors; i++) {
916 		ntb->msix_vec[i].num = i;
917 		ntb->msix_vec[i].ntb = ntb;
918 	}
919 
920 	return (0);
921 }
922 
923 static void
924 amd_ntb_free_msix_vec(struct amd_ntb_softc *ntb)
925 {
926 	if (ntb->msix_vec_count) {
927 		pci_release_msi(ntb->device);
928 		ntb->msix_vec_count = 0;
929 	}
930 
931 	if (ntb->msix_vec != NULL) {
932 		free(ntb->msix_vec, M_AMD_NTB);
933 		ntb->msix_vec = NULL;
934 	}
935 }
936 
937 static int
938 amd_ntb_init_isr(struct amd_ntb_softc *ntb)
939 {
940 	uint32_t supported_vectors, num_vectors;
941 	bool msi = false, intx = false;
942 	int rc = 0;
943 
944 	ntb->db_mask = ntb->db_valid_mask;
945 
946 	rc = amd_ntb_create_msix_vec(ntb, ntb->hw_info->msix_vector_count);
947 	if (rc != 0) {
948 		amd_ntb_printf(0, "Error creating msix vectors: %d\n", rc);
949 		return (ENOMEM);
950 	}
951 
952 	/*
953 	 * Check the number of MSI-X message supported by the device.
954 	 * Minimum necessary MSI-X message count should be equal to db_count.
955 	 */
956 	supported_vectors = pci_msix_count(ntb->device);
957 	num_vectors = MIN(supported_vectors, ntb->hw_info->db_count);
958 	if (num_vectors < ntb->hw_info->db_count) {
959 		amd_ntb_printf(0, "No minimum msix: supported %d db %d\n",
960 		    supported_vectors, ntb->hw_info->db_count);
961 		msi = true;
962 		goto err_msix_enable;
963 	}
964 
965 	/* Allocate the necessary number of MSI-x messages */
966 	rc = pci_alloc_msix(ntb->device, &num_vectors);
967 	if (rc != 0) {
968 		amd_ntb_printf(0, "Error allocating msix vectors: %d\n", rc);
969 		msi = true;
970 		goto err_msix_enable;
971 	}
972 
973 	if (num_vectors < ntb->hw_info->db_count) {
974 		amd_ntb_printf(0, "Allocated only %d MSI-X\n", num_vectors);
975 		msi = true;
976 		/*
977 		 * Else set ntb->hw_info->db_count = ntb->msix_vec_count =
978 		 * num_vectors, msi=false and dont release msi.
979 		 */
980 	}
981 
982 err_msix_enable:
983 
984 	if (msi) {
985 		free(ntb->msix_vec, M_AMD_NTB);
986 		ntb->msix_vec = NULL;
987 		pci_release_msi(ntb->device);
988 		num_vectors = 1;
989 		rc = pci_alloc_msi(ntb->device, &num_vectors);
990 		if (rc != 0) {
991 			amd_ntb_printf(0, "Error allocating msix vectors: %d\n", rc);
992 			msi = false;
993 			intx = true;
994 		}
995 	}
996 
997 	ntb->hw_info->db_count = ntb->msix_vec_count = num_vectors;
998 
999 	if (intx) {
1000 		num_vectors = 1;
1001 		ntb->hw_info->db_count = 1;
1002 		ntb->msix_vec_count = 0;
1003 	}
1004 
1005 	amd_ntb_printf(0, "%s: db %d msix %d msi %d intx %d\n",
1006 	    __func__, ntb->hw_info->db_count, ntb->msix_vec_count, (int)msi, (int)intx);
1007 
1008 	rc = amd_ntb_setup_isr(ntb, num_vectors, msi, intx);
1009 	if (rc != 0) {
1010 		amd_ntb_printf(0, "Error setting up isr: %d\n", rc);
1011 		amd_ntb_free_msix_vec(ntb);
1012 	}
1013 
1014 	return (rc);
1015 }
1016 
1017 static void
1018 amd_ntb_deinit_isr(struct amd_ntb_softc *ntb)
1019 {
1020 	struct amd_ntb_int_info *current_int;
1021 	int i;
1022 
1023 	/* Mask all doorbell interrupts */
1024 	ntb->db_mask = ntb->db_valid_mask;
1025 	amd_ntb_reg_write(4, AMD_DBMASK_OFFSET, ntb->db_mask);
1026 
1027 	for (i = 0; i < ntb->allocated_interrupts; i++) {
1028 		current_int = &ntb->int_info[i];
1029 		if (current_int->tag != NULL)
1030 			bus_teardown_intr(ntb->device, current_int->res,
1031 			    current_int->tag);
1032 
1033 		if (current_int->res != NULL)
1034 			bus_release_resource(ntb->device, SYS_RES_IRQ,
1035 			    rman_get_rid(current_int->res), current_int->res);
1036 	}
1037 
1038 	amd_ntb_free_msix_vec(ntb);
1039 }
1040 
1041 static enum amd_ntb_conn_type
1042 amd_ntb_get_topo(struct amd_ntb_softc *ntb)
1043 {
1044 	uint32_t info;
1045 
1046 	info = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
1047 
1048 	if (info & AMD_SIDE_MASK)
1049 		return (NTB_CONN_SEC);
1050 
1051 	return (NTB_CONN_PRI);
1052 }
1053 
1054 static int
1055 amd_ntb_init_dev(struct amd_ntb_softc *ntb)
1056 {
1057 	ntb->db_valid_mask	 = (1ull << ntb->hw_info->db_count) - 1;
1058 	mtx_init(&ntb->db_mask_lock, "amd ntb db bits", NULL, MTX_SPIN);
1059 
1060 	switch (ntb->conn_type) {
1061 	case NTB_CONN_PRI:
1062 	case NTB_CONN_SEC:
1063 		ntb->spad_count >>= 1;
1064 
1065 		if (ntb->conn_type == NTB_CONN_PRI) {
1066 			ntb->self_spad = 0;
1067 			ntb->peer_spad = 0x20;
1068 		} else {
1069 			ntb->self_spad = 0x20;
1070 			ntb->peer_spad = 0;
1071 		}
1072 
1073 		callout_init(&ntb->hb_timer, 1);
1074 		callout_reset(&ntb->hb_timer, AMD_LINK_HB_TIMEOUT,
1075 		    amd_link_hb, ntb);
1076 
1077 		break;
1078 
1079 	default:
1080 		amd_ntb_printf(0, "Unsupported AMD NTB topology %d\n",
1081 		    ntb->conn_type);
1082 		return (EINVAL);
1083 	}
1084 
1085 	ntb->int_mask = AMD_EVENT_INTMASK;
1086 	amd_ntb_reg_write(4, AMD_INTMASK_OFFSET, ntb->int_mask);
1087 
1088 	return (0);
1089 }
1090 
1091 static int
1092 amd_ntb_init(struct amd_ntb_softc *ntb)
1093 {
1094 	int rc = 0;
1095 
1096 	ntb->conn_type = amd_ntb_get_topo(ntb);
1097 	amd_ntb_printf(0, "AMD NTB Side: %s\n",
1098 	    (ntb->conn_type == NTB_CONN_PRI)? "PRIMARY" : "SECONDARY");
1099 
1100 	rc = amd_ntb_init_dev(ntb);
1101 	if (rc != 0)
1102 		return (rc);
1103 
1104 	rc = amd_ntb_init_isr(ntb);
1105 	if (rc != 0)
1106 		return (rc);
1107 
1108 	return (0);
1109 }
1110 
1111 static void
1112 print_map_success(struct amd_ntb_softc *ntb, struct amd_ntb_pci_bar_info *bar,
1113     const char *kind)
1114 {
1115 	amd_ntb_printf(0, "Mapped BAR%d v:[%p-%p] p:[0x%jx-0x%jx] (0x%jx bytes) (%s)\n",
1116 	    PCI_RID2BAR(bar->pci_resource_id), bar->vbase,
1117 	    (char *)bar->vbase + bar->size - 1, (uintmax_t)bar->pbase,
1118 	    (uintmax_t)(bar->pbase + bar->size - 1), (uintmax_t)bar->size, kind);
1119 }
1120 
1121 static void
1122 save_bar_parameters(struct amd_ntb_pci_bar_info *bar)
1123 {
1124 	bar->pci_bus_tag = rman_get_bustag(bar->pci_resource);
1125 	bar->pci_bus_handle = rman_get_bushandle(bar->pci_resource);
1126 	bar->pbase = rman_get_start(bar->pci_resource);
1127 	bar->size = rman_get_size(bar->pci_resource);
1128 	bar->vbase = rman_get_virtual(bar->pci_resource);
1129 	bar->map_mode = VM_MEMATTR_UNCACHEABLE;
1130 }
1131 
1132 static int
1133 map_bar(struct amd_ntb_softc *ntb, struct amd_ntb_pci_bar_info *bar)
1134 {
1135 	bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
1136 	    &bar->pci_resource_id, RF_ACTIVE);
1137 	if (bar->pci_resource == NULL)
1138 		return (ENXIO);
1139 
1140 	save_bar_parameters(bar);
1141 	print_map_success(ntb, bar, "mmr");
1142 
1143 	return (0);
1144 }
1145 
1146 static int
1147 amd_ntb_map_pci_bars(struct amd_ntb_softc *ntb)
1148 {
1149 	int rc = 0;
1150 
1151 	/* NTB Config/Control registers - BAR 0 */
1152 	ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0);
1153 	rc = map_bar(ntb, &ntb->bar_info[NTB_CONFIG_BAR]);
1154 	if (rc != 0)
1155 		goto out;
1156 
1157 	/* Memory Window 0 BAR - BAR 1 */
1158 	ntb->bar_info[NTB_BAR_1].pci_resource_id = PCIR_BAR(1);
1159 	rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_1]);
1160 	if (rc != 0)
1161 		goto out;
1162 	ntb->bar_info[NTB_BAR_1].xlat_off = AMD_BAR1XLAT_OFFSET;
1163 	ntb->bar_info[NTB_BAR_1].limit_off = AMD_BAR1LMT_OFFSET;
1164 
1165 	/* Memory Window 1 BAR - BAR 2&3 */
1166 	ntb->bar_info[NTB_BAR_2].pci_resource_id = PCIR_BAR(2);
1167 	rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_2]);
1168 	if (rc != 0)
1169 		goto out;
1170 	ntb->bar_info[NTB_BAR_2].xlat_off = AMD_BAR23XLAT_OFFSET;
1171 	ntb->bar_info[NTB_BAR_2].limit_off = AMD_BAR23LMT_OFFSET;
1172 
1173 	/* Memory Window 2 BAR - BAR 4&5 */
1174 	ntb->bar_info[NTB_BAR_3].pci_resource_id = PCIR_BAR(4);
1175 	rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_3]);
1176 	if (rc != 0)
1177 		goto out;
1178 	ntb->bar_info[NTB_BAR_3].xlat_off = AMD_BAR45XLAT_OFFSET;
1179 	ntb->bar_info[NTB_BAR_3].limit_off = AMD_BAR45LMT_OFFSET;
1180 
1181 out:
1182 	if (rc != 0)
1183 		amd_ntb_printf(0, "unable to allocate pci resource\n");
1184 
1185 	return (rc);
1186 }
1187 
1188 static void
1189 amd_ntb_unmap_pci_bars(struct amd_ntb_softc *ntb)
1190 {
1191 	struct amd_ntb_pci_bar_info *bar_info;
1192 	int i;
1193 
1194 	for (i = 0; i < NTB_MAX_BARS; i++) {
1195 		bar_info = &ntb->bar_info[i];
1196 		if (bar_info->pci_resource != NULL)
1197 			bus_release_resource(ntb->device, SYS_RES_MEMORY,
1198 			    bar_info->pci_resource_id, bar_info->pci_resource);
1199 	}
1200 }
1201 
1202 static int
1203 amd_ntb_probe(device_t device)
1204 {
1205 	struct amd_ntb_softc *ntb = device_get_softc(device);
1206 	const struct pci_device_table *tbl;
1207 
1208 	tbl = PCI_MATCH(device, amd_ntb_devs);
1209 	if (tbl == NULL)
1210 		return (ENXIO);
1211 
1212 	ntb->hw_info = (struct amd_ntb_hw_info *)tbl->driver_data;
1213 	ntb->spad_count = ntb->hw_info->spad_count;
1214 	device_set_desc(device, tbl->descr);
1215 
1216 	return (BUS_PROBE_GENERIC);
1217 }
1218 
1219 static int
1220 amd_ntb_attach(device_t device)
1221 {
1222 	struct amd_ntb_softc *ntb = device_get_softc(device);
1223 	int error;
1224 
1225 	ntb->device = device;
1226 
1227 	/* Enable PCI bus mastering for "device" */
1228 	pci_enable_busmaster(ntb->device);
1229 
1230 	error = amd_ntb_map_pci_bars(ntb);
1231 	if (error)
1232 		goto out;
1233 
1234 	error = amd_ntb_init(ntb);
1235 	if (error)
1236 		goto out;
1237 
1238 	amd_init_side_info(ntb);
1239 
1240 	amd_ntb_spad_clear(ntb);
1241 
1242 	amd_ntb_sysctl_init(ntb);
1243 
1244 	/* Attach children to this controller */
1245 	error = ntb_register_device(device);
1246 
1247 out:
1248 	if (error)
1249 		amd_ntb_detach(device);
1250 
1251 	return (error);
1252 }
1253 
1254 static int
1255 amd_ntb_detach(device_t device)
1256 {
1257 	struct amd_ntb_softc *ntb = device_get_softc(device);
1258 
1259 	ntb_unregister_device(device);
1260 	amd_deinit_side_info(ntb);
1261 	callout_drain(&ntb->hb_timer);
1262 	amd_ntb_deinit_isr(ntb);
1263 	mtx_destroy(&ntb->db_mask_lock);
1264 	pci_disable_busmaster(ntb->device);
1265 	amd_ntb_unmap_pci_bars(ntb);
1266 
1267 	return (0);
1268 }
1269 
1270 static device_method_t ntb_amd_methods[] = {
1271 	/* Device interface */
1272 	DEVMETHOD(device_probe,		amd_ntb_probe),
1273 	DEVMETHOD(device_attach,	amd_ntb_attach),
1274 	DEVMETHOD(device_detach,	amd_ntb_detach),
1275 
1276 	/* Bus interface */
1277 	DEVMETHOD(bus_child_location,	ntb_child_location),
1278 	DEVMETHOD(bus_print_child,	ntb_print_child),
1279 	DEVMETHOD(bus_get_dma_tag,	ntb_get_dma_tag),
1280 
1281 	/* NTB interface */
1282 	DEVMETHOD(ntb_port_number,	amd_ntb_port_number),
1283 	DEVMETHOD(ntb_peer_port_count,	amd_ntb_peer_port_count),
1284 	DEVMETHOD(ntb_peer_port_number,	amd_ntb_peer_port_number),
1285 	DEVMETHOD(ntb_peer_port_idx, 	amd_ntb_peer_port_idx),
1286 	DEVMETHOD(ntb_link_is_up,	amd_ntb_link_is_up),
1287 	DEVMETHOD(ntb_link_enable,	amd_ntb_link_enable),
1288 	DEVMETHOD(ntb_link_disable,	amd_ntb_link_disable),
1289 	DEVMETHOD(ntb_mw_count,		amd_ntb_mw_count),
1290 	DEVMETHOD(ntb_mw_get_range,	amd_ntb_mw_get_range),
1291 	DEVMETHOD(ntb_mw_set_trans,	amd_ntb_mw_set_trans),
1292 	DEVMETHOD(ntb_mw_clear_trans,	amd_ntb_mw_clear_trans),
1293 	DEVMETHOD(ntb_mw_set_wc,	amd_ntb_mw_set_wc),
1294 	DEVMETHOD(ntb_mw_get_wc,	amd_ntb_mw_get_wc),
1295 	DEVMETHOD(ntb_db_valid_mask,	amd_ntb_db_valid_mask),
1296 	DEVMETHOD(ntb_db_vector_count,	amd_ntb_db_vector_count),
1297 	DEVMETHOD(ntb_db_vector_mask,	amd_ntb_db_vector_mask),
1298 	DEVMETHOD(ntb_db_read,		amd_ntb_db_read),
1299 	DEVMETHOD(ntb_db_clear,		amd_ntb_db_clear),
1300 	DEVMETHOD(ntb_db_set_mask,	amd_ntb_db_set_mask),
1301 	DEVMETHOD(ntb_db_clear_mask,	amd_ntb_db_clear_mask),
1302 	DEVMETHOD(ntb_peer_db_set,	amd_ntb_peer_db_set),
1303 	DEVMETHOD(ntb_spad_count,	amd_ntb_spad_count),
1304 	DEVMETHOD(ntb_spad_read,	amd_ntb_spad_read),
1305 	DEVMETHOD(ntb_spad_write,	amd_ntb_spad_write),
1306 	DEVMETHOD(ntb_peer_spad_read,	amd_ntb_peer_spad_read),
1307 	DEVMETHOD(ntb_peer_spad_write,	amd_ntb_peer_spad_write),
1308 	DEVMETHOD_END
1309 };
1310 
1311 static DEFINE_CLASS_0(ntb_hw, ntb_amd_driver, ntb_amd_methods,
1312     sizeof(struct amd_ntb_softc));
1313 DRIVER_MODULE(ntb_hw_amd, pci, ntb_amd_driver, NULL, NULL);
1314 MODULE_DEPEND(ntb_hw_amd, ntb, 1, 1, 1);
1315 MODULE_VERSION(ntb_hw_amd, 1);
1316 PCI_PNP_INFO(amd_ntb_devs);
1317