2 * Copyright (C) 2013 Intel Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/systm.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/queue.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>
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.
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.
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.
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)
67 #define MAX_MSIX_INTERRUPTS MAX(XEON_MAX_DB_BITS, SOC_MAX_DB_BITS)
69 #define NTB_HB_TIMEOUT 1 /* second */
70 #define SOC_LINK_RECOVERY_TIME 500
72 #define DEVICE2SOFTC(dev) ((struct ntb_softc *) device_get_softc(dev))
74 enum ntb_device_type {
79 /* Device features and workarounds */
80 #define HAS_FEATURE(feature) \
81 ((ntb->features & (feature)) != 0)
83 #define NTB_BAR_SIZE_4K (1 << 0)
84 #define NTB_REGS_THRU_MW (1 << 1)
89 enum ntb_device_type type;
93 struct ntb_pci_bar_info {
94 bus_space_tag_t pci_bus_tag;
95 bus_space_handle_t pci_bus_handle;
97 struct resource *pci_resource;
103 struct ntb_int_info {
104 struct resource *res;
110 ntb_db_callback callback;
113 struct ntb_softc *ntb;
118 enum ntb_device_type type;
121 struct ntb_pci_bar_info bar_info[NTB_MAX_BARS];
122 struct ntb_int_info int_info[MAX_MSIX_INTERRUPTS];
123 uint32_t allocated_interrupts;
125 struct callout heartbeat_timer;
126 struct callout lr_timer;
129 ntb_event_callback event_cb;
130 struct ntb_db_cb *db_cb;
134 uint32_t max_db_bits;
143 uint32_t spad_remote;
151 uint8_t bits_per_vector;
157 #define ntb_bar_read(SIZE, bar, offset) \
158 bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
159 ntb->bar_info[(bar)].pci_bus_handle, (offset))
160 #define ntb_bar_write(SIZE, bar, offset, val) \
161 bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
162 ntb->bar_info[(bar)].pci_bus_handle, (offset), (val))
163 #define ntb_reg_read(SIZE, offset) ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset)
164 #define ntb_reg_write(SIZE, offset, val) \
165 ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val)
166 #define ntb_mw_read(SIZE, offset) ntb_bar_read(SIZE, NTB_B2B_BAR_2, offset)
167 #define ntb_mw_write(SIZE, offset, val) \
168 ntb_bar_write(SIZE, NTB_B2B_BAR_2, offset, val)
170 typedef int (*bar_map_strategy)(struct ntb_softc *ntb,
171 struct ntb_pci_bar_info *bar);
173 static int ntb_probe(device_t device);
174 static int ntb_attach(device_t device);
175 static int ntb_detach(device_t device);
176 static int ntb_map_pci_bars(struct ntb_softc *ntb);
177 static int map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy,
178 struct ntb_pci_bar_info *bar);
179 static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar);
180 static int map_memory_window_bar(struct ntb_softc *ntb,
181 struct ntb_pci_bar_info *bar);
182 static void ntb_unmap_pci_bar(struct ntb_softc *ntb);
183 static int ntb_setup_interrupts(struct ntb_softc *ntb);
184 static void ntb_teardown_interrupts(struct ntb_softc *ntb);
185 static void handle_soc_irq(void *arg);
186 static void handle_xeon_irq(void *arg);
187 static void handle_xeon_event_irq(void *arg);
188 static void ntb_handle_legacy_interrupt(void *arg);
189 static int ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors);
190 static void ntb_free_callbacks(struct ntb_softc *ntb);
191 static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id);
192 static int ntb_initialize_hw(struct ntb_softc *ntb);
193 static int ntb_setup_xeon(struct ntb_softc *ntb);
194 static int ntb_setup_soc(struct ntb_softc *ntb);
195 static void configure_soc_secondary_side_bars(struct ntb_softc *ntb);
196 static void configure_xeon_secondary_side_bars(struct ntb_softc *ntb);
197 static void ntb_handle_heartbeat(void *arg);
198 static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state);
199 static void recover_soc_link(void *arg);
200 static int ntb_check_link_status(struct ntb_softc *ntb);
201 static void save_bar_parameters(struct ntb_pci_bar_info *bar);
203 static struct ntb_hw_info pci_ids[] = {
204 { 0x3C0D8086, "Xeon E5/Core i7 Non-Transparent Bridge B2B", NTB_XEON,
206 { 0x0C4E8086, "Atom Processor S1200 NTB Primary B2B", NTB_SOC, 0 },
207 { 0x0E0D8086, "Xeon E5 V2 Non-Transparent Bridge B2B", NTB_XEON,
208 NTB_REGS_THRU_MW | NTB_BAR_SIZE_4K },
209 { 0x00000000, NULL, NTB_SOC, 0 }
213 * OS <-> Driver interface structures
215 MALLOC_DEFINE(M_NTB, "ntb_hw", "ntb_hw driver memory allocations");
217 static device_method_t ntb_pci_methods[] = {
218 /* Device interface */
219 DEVMETHOD(device_probe, ntb_probe),
220 DEVMETHOD(device_attach, ntb_attach),
221 DEVMETHOD(device_detach, ntb_detach),
225 static driver_t ntb_pci_driver = {
228 sizeof(struct ntb_softc),
231 static devclass_t ntb_devclass;
232 DRIVER_MODULE(ntb_hw, pci, ntb_pci_driver, ntb_devclass, NULL, NULL);
233 MODULE_VERSION(ntb_hw, 1);
236 * OS <-> Driver linkage functions
239 ntb_probe(device_t device)
241 struct ntb_hw_info *p = ntb_get_device_info(pci_get_devid(device));
244 device_set_desc(device, p->desc);
250 #define DETACH_ON_ERROR(func) \
253 ntb_detach(device); \
258 ntb_attach(device_t device)
260 struct ntb_softc *ntb = DEVICE2SOFTC(device);
261 struct ntb_hw_info *p = ntb_get_device_info(pci_get_devid(device));
264 ntb->device = device;
266 ntb->features = p->features;
268 /* Heartbeat timer for NTB_SOC since there is no link interrupt */
269 callout_init(&ntb->heartbeat_timer, 1);
270 callout_init(&ntb->lr_timer, 1);
272 DETACH_ON_ERROR(ntb_map_pci_bars(ntb));
273 DETACH_ON_ERROR(ntb_initialize_hw(ntb));
274 DETACH_ON_ERROR(ntb_setup_interrupts(ntb));
276 pci_enable_busmaster(ntb->device);
282 ntb_detach(device_t device)
284 struct ntb_softc *ntb = DEVICE2SOFTC(device);
286 callout_drain(&ntb->heartbeat_timer);
287 callout_drain(&ntb->lr_timer);
288 ntb_teardown_interrupts(ntb);
289 ntb_unmap_pci_bar(ntb);
295 ntb_map_pci_bars(struct ntb_softc *ntb)
299 ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0);
300 rc = map_pci_bar(ntb, map_mmr_bar, &ntb->bar_info[NTB_CONFIG_BAR]);
304 ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2);
305 rc = map_pci_bar(ntb, map_memory_window_bar,
306 &ntb->bar_info[NTB_B2B_BAR_1]);
310 ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4);
311 if (HAS_FEATURE(NTB_REGS_THRU_MW))
312 rc = map_pci_bar(ntb, map_mmr_bar,
313 &ntb->bar_info[NTB_B2B_BAR_2]);
315 rc = map_pci_bar(ntb, map_memory_window_bar,
316 &ntb->bar_info[NTB_B2B_BAR_2]);
324 map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy,
325 struct ntb_pci_bar_info *bar)
329 rc = strategy(ntb, bar);
331 device_printf(ntb->device,
332 "unable to allocate pci resource\n");
334 device_printf(ntb->device,
335 "Bar size = %lx, v %p, p %p\n",
336 bar->size, bar->vbase,
337 (void *)(bar->pbase));
343 map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
346 bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
347 &bar->pci_resource_id, RF_ACTIVE);
349 if (bar->pci_resource == NULL)
352 save_bar_parameters(bar);
358 map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
361 uint8_t bar_size_bits = 0;
363 bar->pci_resource = bus_alloc_resource_any(ntb->device,
364 SYS_RES_MEMORY, &bar->pci_resource_id, RF_ACTIVE);
366 if (bar->pci_resource == NULL)
369 save_bar_parameters(bar);
371 * Ivytown NTB BAR sizes are misreported by the hardware due to
372 * a hardware issue. To work around this, query the size it
373 * should be configured to by the device and modify the resource
374 * to correspond to this new size. The BIOS on systems with this
375 * problem is required to provide enough address space to allow
376 * the driver to make this change safely.
378 * Ideally I could have just specified the size when I allocated
380 * bus_alloc_resource(ntb->device,
381 * SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul,
382 * 1ul << bar_size_bits, RF_ACTIVE);
383 * but the PCI driver does not honor the size in this call, so
384 * we have to modify it after the fact.
386 if (HAS_FEATURE(NTB_BAR_SIZE_4K)) {
387 if (bar->pci_resource_id == PCIR_BAR(2))
388 bar_size_bits = pci_read_config(ntb->device,
389 XEON_PBAR23SZ_OFFSET, 1);
391 bar_size_bits = pci_read_config(ntb->device,
392 XEON_PBAR45SZ_OFFSET, 1);
393 rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY,
394 bar->pci_resource, bar->pbase,
395 bar->pbase + (1ul << bar_size_bits) - 1);
397 device_printf(ntb->device,
398 "unable to resize bar\n");
401 save_bar_parameters(bar);
404 /* Mark bar region as write combining to improve performance. */
405 rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size,
406 VM_MEMATTR_WRITE_COMBINING);
408 device_printf(ntb->device, "unable to mark bar as"
409 " WRITE_COMBINING\n");
417 ntb_unmap_pci_bar(struct ntb_softc *ntb)
419 struct ntb_pci_bar_info *current_bar;
422 for (i = 0; i< NTB_MAX_BARS; i++) {
423 current_bar = &ntb->bar_info[i];
424 if (current_bar->pci_resource != NULL)
425 bus_release_resource(ntb->device, SYS_RES_MEMORY,
426 current_bar->pci_resource_id,
427 current_bar->pci_resource);
432 ntb_setup_interrupts(struct ntb_softc *ntb)
434 void (*interrupt_handler)(void *);
437 uint32_t num_vectors;
440 ntb->allocated_interrupts = 0;
442 * On SOC, disable all interrupts. On XEON, disable all but Link
443 * Interrupt. The rest will be unmasked as callbacks are registered.
445 if (ntb->type == NTB_SOC)
446 ntb_reg_write(8, ntb->reg_ofs.pdb_mask, ~0);
448 ntb_reg_write(2, ntb->reg_ofs.pdb_mask,
449 ~(1 << ntb->limits.max_db_bits));
451 num_vectors = MIN(pci_msix_count(ntb->device),
452 ntb->limits.max_db_bits);
453 if (num_vectors >= 1) {
454 pci_alloc_msix(ntb->device, &num_vectors);
455 if (num_vectors >= 4)
459 ntb_create_callbacks(ntb, num_vectors);
460 if (use_msix == TRUE) {
461 for (i = 0; i < num_vectors; i++) {
462 ntb->int_info[i].rid = i + 1;
463 ntb->int_info[i].res = bus_alloc_resource_any(
464 ntb->device, SYS_RES_IRQ, &ntb->int_info[i].rid,
466 if (ntb->int_info[i].res == NULL) {
467 device_printf(ntb->device,
468 "bus_alloc_resource failed\n");
471 ntb->int_info[i].tag = NULL;
472 ntb->allocated_interrupts++;
473 if (ntb->type == NTB_SOC) {
474 interrupt_handler = handle_soc_irq;
475 int_arg = &ntb->db_cb[i];
477 if (i == num_vectors - 1) {
479 handle_xeon_event_irq;
484 int_arg = &ntb->db_cb[i];
487 if (bus_setup_intr(ntb->device, ntb->int_info[i].res,
488 INTR_MPSAFE | INTR_TYPE_MISC, NULL,
489 interrupt_handler, int_arg,
490 &ntb->int_info[i].tag) != 0) {
491 device_printf(ntb->device,
492 "bus_setup_intr failed\n");
498 ntb->int_info[0].rid = 0;
499 ntb->int_info[0].res = bus_alloc_resource_any(ntb->device,
500 SYS_RES_IRQ, &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE);
501 interrupt_handler = ntb_handle_legacy_interrupt;
502 if (ntb->int_info[0].res == NULL) {
503 device_printf(ntb->device,
504 "bus_alloc_resource failed\n");
507 ntb->int_info[0].tag = NULL;
508 ntb->allocated_interrupts = 1;
510 if (bus_setup_intr(ntb->device, ntb->int_info[0].res,
511 INTR_MPSAFE | INTR_TYPE_MISC, NULL,
512 interrupt_handler, ntb, &ntb->int_info[0].tag) != 0) {
514 device_printf(ntb->device, "bus_setup_intr failed\n");
523 ntb_teardown_interrupts(struct ntb_softc *ntb)
525 struct ntb_int_info *current_int;
528 for (i=0; i<ntb->allocated_interrupts; i++) {
529 current_int = &ntb->int_info[i];
530 if (current_int->tag != NULL)
531 bus_teardown_intr(ntb->device, current_int->res,
534 if (current_int->res != NULL)
535 bus_release_resource(ntb->device, SYS_RES_IRQ,
536 rman_get_rid(current_int->res), current_int->res);
539 ntb_free_callbacks(ntb);
540 pci_release_msi(ntb->device);
544 handle_soc_irq(void *arg)
546 struct ntb_db_cb *db_cb = arg;
547 struct ntb_softc *ntb = db_cb->ntb;
549 ntb_reg_write(8, ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num);
551 if (db_cb->callback != NULL)
552 db_cb->callback(db_cb->data, db_cb->db_num);
556 handle_xeon_irq(void *arg)
558 struct ntb_db_cb *db_cb = arg;
559 struct ntb_softc *ntb = db_cb->ntb;
562 * On Xeon, there are 16 bits in the interrupt register
563 * but only 4 vectors. So, 5 bits are assigned to the first 3
564 * vectors, with the 4th having a single bit for link
567 ntb_reg_write(2, ntb->reg_ofs.pdb,
568 ((1 << ntb->bits_per_vector) - 1) <<
569 (db_cb->db_num * ntb->bits_per_vector));
571 if (db_cb->callback != NULL)
572 db_cb->callback(db_cb->data, db_cb->db_num);
575 /* Since we do not have a HW doorbell in SOC, this is only used in JF/JT */
577 handle_xeon_event_irq(void *arg)
579 struct ntb_softc *ntb = arg;
582 rc = ntb_check_link_status(ntb);
584 device_printf(ntb->device, "Error determining link status\n");
586 /* bit 15 is always the link bit */
587 ntb_reg_write(2, ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits);
591 ntb_handle_legacy_interrupt(void *arg)
593 struct ntb_softc *ntb = arg;
598 if (ntb->type == NTB_SOC) {
599 pdb64 = ntb_reg_read(8, ntb->reg_ofs.pdb);
604 handle_soc_irq(&ntb->db_cb[i]);
607 pdb16 = ntb_reg_read(2, ntb->reg_ofs.pdb);
609 if ((pdb16 & XEON_DB_HW_LINK) != 0) {
610 handle_xeon_event_irq(ntb);
611 pdb16 &= ~XEON_DB_HW_LINK;
617 handle_xeon_irq(&ntb->db_cb[i]);
624 ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors)
628 ntb->db_cb = malloc(num_vectors * sizeof(struct ntb_db_cb), M_NTB,
630 for (i = 0; i < num_vectors; i++) {
631 ntb->db_cb[i].db_num = i;
632 ntb->db_cb[i].ntb = ntb;
639 ntb_free_callbacks(struct ntb_softc *ntb)
643 for (i = 0; i < ntb->limits.max_db_bits; i++)
644 ntb_unregister_db_callback(ntb, i);
646 free(ntb->db_cb, M_NTB);
649 static struct ntb_hw_info *
650 ntb_get_device_info(uint32_t device_id)
652 struct ntb_hw_info *ep = pci_ids;
654 while (ep->device_id) {
655 if (ep->device_id == device_id)
663 ntb_initialize_hw(struct ntb_softc *ntb)
666 if (ntb->type == NTB_SOC)
667 return (ntb_setup_soc(ntb));
669 return (ntb_setup_xeon(ntb));
673 ntb_setup_xeon(struct ntb_softc *ntb)
675 uint8_t val, connection_type;
677 val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1);
679 connection_type = val & XEON_PPD_CONN_TYPE;
680 switch (connection_type) {
682 ntb->conn_type = NTB_CONN_B2B;
684 case NTB_CONN_CLASSIC:
687 device_printf(ntb->device, "Connection type %d not supported\n",
692 if ((val & XEON_PPD_DEV_TYPE) != 0)
693 ntb->dev_type = NTB_DEV_DSD;
695 ntb->dev_type = NTB_DEV_USD;
697 ntb->reg_ofs.pdb = XEON_PDOORBELL_OFFSET;
698 ntb->reg_ofs.pdb_mask = XEON_PDBMSK_OFFSET;
699 ntb->reg_ofs.sbar2_xlat = XEON_SBAR2XLAT_OFFSET;
700 ntb->reg_ofs.sbar4_xlat = XEON_SBAR4XLAT_OFFSET;
701 ntb->reg_ofs.lnk_cntl = XEON_NTBCNTL_OFFSET;
702 ntb->reg_ofs.lnk_stat = XEON_LINK_STATUS_OFFSET;
703 ntb->reg_ofs.spad_local = XEON_SPAD_OFFSET;
704 ntb->reg_ofs.spci_cmd = XEON_PCICMD_OFFSET;
706 if (ntb->conn_type == NTB_CONN_B2B) {
707 ntb->reg_ofs.sdb = XEON_B2B_DOORBELL_OFFSET;
708 ntb->reg_ofs.spad_remote = XEON_B2B_SPAD_OFFSET;
709 ntb->limits.max_spads = XEON_MAX_SPADS;
711 ntb->reg_ofs.sdb = XEON_SDOORBELL_OFFSET;
712 ntb->reg_ofs.spad_remote = XEON_SPAD_OFFSET;
713 ntb->limits.max_spads = XEON_MAX_COMPAT_SPADS;
716 ntb->limits.max_db_bits = XEON_MAX_DB_BITS;
717 ntb->limits.msix_cnt = XEON_MSIX_CNT;
718 ntb->bits_per_vector = XEON_DB_BITS_PER_VEC;
720 configure_xeon_secondary_side_bars(ntb);
721 /* Enable Bus Master and Memory Space on the secondary side */
722 ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
723 PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
725 /* Enable link training */
726 ntb_reg_write(4, ntb->reg_ofs.lnk_cntl,
727 NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP);
733 ntb_setup_soc(struct ntb_softc *ntb)
735 uint32_t val, connection_type;
737 val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4);
739 connection_type = (val & SOC_PPD_CONN_TYPE) >> 8;
740 switch (connection_type) {
742 ntb->conn_type = NTB_CONN_B2B;
746 device_printf(ntb->device, "Connection type %d not supported\n",
751 if ((val & SOC_PPD_DEV_TYPE) != 0)
752 ntb->dev_type = NTB_DEV_DSD;
754 ntb->dev_type = NTB_DEV_USD;
756 /* Initiate PCI-E link training */
757 pci_write_config(ntb->device, NTB_PPD_OFFSET, val | SOC_PPD_INIT_LINK,
760 ntb->reg_ofs.pdb = SOC_PDOORBELL_OFFSET;
761 ntb->reg_ofs.pdb_mask = SOC_PDBMSK_OFFSET;
762 ntb->reg_ofs.sbar2_xlat = SOC_SBAR2XLAT_OFFSET;
763 ntb->reg_ofs.sbar4_xlat = SOC_SBAR4XLAT_OFFSET;
764 ntb->reg_ofs.lnk_cntl = SOC_NTBCNTL_OFFSET;
765 ntb->reg_ofs.lnk_stat = SOC_LINK_STATUS_OFFSET;
766 ntb->reg_ofs.spad_local = SOC_SPAD_OFFSET;
767 ntb->reg_ofs.spci_cmd = SOC_PCICMD_OFFSET;
769 if (ntb->conn_type == NTB_CONN_B2B) {
770 ntb->reg_ofs.sdb = SOC_B2B_DOORBELL_OFFSET;
771 ntb->reg_ofs.spad_remote = SOC_B2B_SPAD_OFFSET;
772 ntb->limits.max_spads = SOC_MAX_SPADS;
774 ntb->reg_ofs.sdb = SOC_PDOORBELL_OFFSET;
775 ntb->reg_ofs.spad_remote = SOC_SPAD_OFFSET;
776 ntb->limits.max_spads = SOC_MAX_COMPAT_SPADS;
779 ntb->limits.max_db_bits = SOC_MAX_DB_BITS;
780 ntb->limits.msix_cnt = SOC_MSIX_CNT;
781 ntb->bits_per_vector = SOC_DB_BITS_PER_VEC;
784 * FIXME - MSI-X bug on early SOC HW, remove once internal issue is
785 * resolved. Mask transaction layer internal parity errors.
787 pci_write_config(ntb->device, 0xFC, 0x4, 4);
789 configure_soc_secondary_side_bars(ntb);
791 /* Enable Bus Master and Memory Space on the secondary side */
792 ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
793 PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
794 callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb);
800 configure_soc_secondary_side_bars(struct ntb_softc *ntb)
803 if (ntb->dev_type == NTB_DEV_USD) {
804 ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR);
805 ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_USD_ADDR);
806 ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_USD_ADDR);
807 ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_USD_ADDR);
809 ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR);
810 ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_DSD_ADDR);
811 ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_DSD_ADDR);
812 ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_DSD_ADDR);
817 configure_xeon_secondary_side_bars(struct ntb_softc *ntb)
820 if (ntb->dev_type == NTB_DEV_USD) {
821 ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR);
822 if (HAS_FEATURE(NTB_REGS_THRU_MW))
823 ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
826 ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
828 ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_USD_ADDR);
829 ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_USD_ADDR);
830 ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_USD_ADDR);
832 ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR);
833 if (HAS_FEATURE(NTB_REGS_THRU_MW))
834 ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
837 ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
839 ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_DSD_ADDR);
840 ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_DSD_ADDR);
841 ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_DSD_ADDR);
845 /* SOC does not have link status interrupt, poll on that platform */
847 ntb_handle_heartbeat(void *arg)
849 struct ntb_softc *ntb = arg;
851 int rc = ntb_check_link_status(ntb);
854 device_printf(ntb->device,
855 "Error determining link status\n");
856 /* Check to see if a link error is the cause of the link down */
857 if (ntb->link_status == NTB_LINK_DOWN) {
858 status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
859 if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) {
860 callout_reset(&ntb->lr_timer, 0, recover_soc_link,
866 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
867 ntb_handle_heartbeat, ntb);
871 soc_perform_link_restart(struct ntb_softc *ntb)
875 /* Driver resets the NTB ModPhy lanes - magic! */
876 ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0xe0);
877 ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x40);
878 ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x60);
879 ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0x60);
881 /* Driver waits 100ms to allow the NTB ModPhy to settle */
882 pause("ModPhy", hz / 10);
884 /* Clear AER Errors, write to clear */
885 status = ntb_reg_read(4, SOC_ERRCORSTS_OFFSET);
886 status &= PCIM_AER_COR_REPLAY_ROLLOVER;
887 ntb_reg_write(4, SOC_ERRCORSTS_OFFSET, status);
889 /* Clear unexpected electrical idle event in LTSSM, write to clear */
890 status = ntb_reg_read(4, SOC_LTSSMERRSTS0_OFFSET);
891 status |= SOC_LTSSMERRSTS0_UNEXPECTEDEI;
892 ntb_reg_write(4, SOC_LTSSMERRSTS0_OFFSET, status);
894 /* Clear DeSkew Buffer error, write to clear */
895 status = ntb_reg_read(4, SOC_DESKEWSTS_OFFSET);
896 status |= SOC_DESKEWSTS_DBERR;
897 ntb_reg_write(4, SOC_DESKEWSTS_OFFSET, status);
899 status = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET);
900 status &= SOC_IBIST_ERR_OFLOW;
901 ntb_reg_write(4, SOC_IBSTERRRCRVSTS0_OFFSET, status);
903 /* Releases the NTB state machine to allow the link to retrain */
904 status = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
905 status &= ~SOC_LTSSMSTATEJMP_FORCEDETECT;
906 ntb_reg_write(4, SOC_LTSSMSTATEJMP_OFFSET, status);
910 ntb_handle_link_event(struct ntb_softc *ntb, int link_state)
912 enum ntb_hw_event event;
915 if (ntb->link_status == link_state)
918 if (link_state == NTB_LINK_UP) {
919 device_printf(ntb->device, "Link Up\n");
920 ntb->link_status = NTB_LINK_UP;
921 event = NTB_EVENT_HW_LINK_UP;
923 if (ntb->type == NTB_SOC)
924 status = ntb_reg_read(2, ntb->reg_ofs.lnk_stat);
926 status = pci_read_config(ntb->device,
927 XEON_LINK_STATUS_OFFSET, 2);
928 ntb->link_width = (status & NTB_LINK_WIDTH_MASK) >> 4;
929 ntb->link_speed = (status & NTB_LINK_SPEED_MASK);
930 device_printf(ntb->device, "Link Width %d, Link Speed %d\n",
931 ntb->link_width, ntb->link_speed);
932 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
933 ntb_handle_heartbeat, ntb);
935 device_printf(ntb->device, "Link Down\n");
936 ntb->link_status = NTB_LINK_DOWN;
937 event = NTB_EVENT_HW_LINK_DOWN;
938 /* Do not modify link width/speed, we need it in link recovery */
941 /* notify the upper layer if we have an event change */
942 if (ntb->event_cb != NULL)
943 ntb->event_cb(ntb->ntb_transport, event);
947 recover_soc_link(void *arg)
949 struct ntb_softc *ntb = arg;
950 uint8_t speed, width;
954 soc_perform_link_restart(ntb);
955 pause("Link", SOC_LINK_RECOVERY_TIME * hz / 1000);
957 status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET);
958 if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0)
961 status32 = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET);
962 if ((status32 & SOC_IBIST_ERR_OFLOW) != 0)
965 status16 = ntb_reg_read(2, ntb->reg_ofs.lnk_stat);
966 width = (status16 & NTB_LINK_WIDTH_MASK) >> 4;
967 speed = (status16 & NTB_LINK_SPEED_MASK);
968 if (ntb->link_width != width || ntb->link_speed != speed)
971 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz,
972 ntb_handle_heartbeat, ntb);
976 callout_reset(&ntb->lr_timer, NTB_HB_TIMEOUT * hz, recover_soc_link,
981 ntb_check_link_status(struct ntb_softc *ntb)
987 if (ntb->type == NTB_SOC) {
988 ntb_cntl = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl);
989 if ((ntb_cntl & SOC_CNTL_LINK_DOWN) != 0)
990 link_state = NTB_LINK_DOWN;
992 link_state = NTB_LINK_UP;
994 status = pci_read_config(ntb->device, XEON_LINK_STATUS_OFFSET,
997 if ((status & NTB_LINK_STATUS_ACTIVE) != 0)
998 link_state = NTB_LINK_UP;
1000 link_state = NTB_LINK_DOWN;
1003 ntb_handle_link_event(ntb, link_state);
1009 * ntb_register_event_callback() - register event callback
1010 * @ntb: pointer to ntb_softc instance
1011 * @func: callback function to register
1013 * This function registers a callback for any HW driver events such as link
1014 * up/down, power management notices and etc.
1016 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1019 ntb_register_event_callback(struct ntb_softc *ntb, ntb_event_callback func)
1022 if (ntb->event_cb != NULL)
1025 ntb->event_cb = func;
1031 * ntb_unregister_event_callback() - unregisters the event callback
1032 * @ntb: pointer to ntb_softc instance
1034 * This function unregisters the existing callback from transport
1037 ntb_unregister_event_callback(struct ntb_softc *ntb)
1040 ntb->event_cb = NULL;
1044 * ntb_register_db_callback() - register a callback for doorbell interrupt
1045 * @ntb: pointer to ntb_softc instance
1046 * @idx: doorbell index to register callback, zero based
1047 * @func: callback function to register
1049 * This function registers a callback function for the doorbell interrupt
1050 * on the primary side. The function will unmask the doorbell as well to
1053 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1056 ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data,
1057 ntb_db_callback func)
1061 if (idx >= ntb->allocated_interrupts || ntb->db_cb[idx].callback) {
1062 device_printf(ntb->device, "Invalid Index.\n");
1066 ntb->db_cb[idx].callback = func;
1067 ntb->db_cb[idx].data = data;
1069 /* unmask interrupt */
1070 mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask);
1071 mask &= ~(1 << (idx * ntb->bits_per_vector));
1072 ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask);
1078 * ntb_unregister_db_callback() - unregister a callback for doorbell interrupt
1079 * @ntb: pointer to ntb_softc instance
1080 * @idx: doorbell index to register callback, zero based
1082 * This function unregisters a callback function for the doorbell interrupt
1083 * on the primary side. The function will also mask the said doorbell.
1086 ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx)
1090 if (idx >= ntb->allocated_interrupts || !ntb->db_cb[idx].callback)
1093 mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask);
1094 mask |= 1 << (idx * ntb->bits_per_vector);
1095 ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask);
1097 ntb->db_cb[idx].callback = NULL;
1101 * ntb_find_transport() - find the transport pointer
1102 * @transport: pointer to pci device
1104 * Given the pci device pointer, return the transport pointer passed in when
1105 * the transport attached when it was inited.
1107 * RETURNS: pointer to transport.
1110 ntb_find_transport(struct ntb_softc *ntb)
1113 return (ntb->ntb_transport);
1117 * ntb_register_transport() - Register NTB transport with NTB HW driver
1118 * @transport: transport identifier
1120 * This function allows a transport to reserve the hardware driver for
1123 * RETURNS: pointer to ntb_softc, NULL on error.
1126 ntb_register_transport(struct ntb_softc *ntb, void *transport)
1130 * TODO: when we have more than one transport, we will need to rewrite
1131 * this to prevent race conditions
1133 if (ntb->ntb_transport != NULL)
1136 ntb->ntb_transport = transport;
1141 * ntb_unregister_transport() - Unregister the transport with the NTB HW driver
1142 * @ntb - ntb_softc of the transport to be freed
1144 * This function unregisters the transport from the HW driver and performs any
1145 * necessary cleanups.
1148 ntb_unregister_transport(struct ntb_softc *ntb)
1152 if (ntb->ntb_transport == NULL)
1155 for (i = 0; i < ntb->allocated_interrupts; i++)
1156 ntb_unregister_db_callback(ntb, i);
1158 ntb_unregister_event_callback(ntb);
1159 ntb->ntb_transport = NULL;
1163 * ntb_get_max_spads() - get the total scratch regs usable
1164 * @ntb: pointer to ntb_softc instance
1166 * This function returns the max 32bit scratchpad registers usable by the
1169 * RETURNS: total number of scratch pad registers available
1172 ntb_get_max_spads(struct ntb_softc *ntb)
1175 return (ntb->limits.max_spads);
1179 * ntb_write_local_spad() - write to the secondary scratchpad register
1180 * @ntb: pointer to ntb_softc instance
1181 * @idx: index to the scratchpad register, 0 based
1182 * @val: the data value to put into the register
1184 * This function allows writing of a 32bit value to the indexed scratchpad
1185 * register. The register resides on the secondary (external) side.
1187 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1190 ntb_write_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val)
1193 if (idx >= ntb->limits.max_spads)
1196 ntb_reg_write(4, ntb->reg_ofs.spad_local + idx * 4, val);
1202 * ntb_read_local_spad() - read from the primary scratchpad register
1203 * @ntb: pointer to ntb_softc instance
1204 * @idx: index to scratchpad register, 0 based
1205 * @val: pointer to 32bit integer for storing the register value
1207 * This function allows reading of the 32bit scratchpad register on
1208 * the primary (internal) side.
1210 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1213 ntb_read_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val)
1216 if (idx >= ntb->limits.max_spads)
1219 *val = ntb_reg_read(4, ntb->reg_ofs.spad_local + idx * 4);
1225 * ntb_write_remote_spad() - write to the secondary scratchpad register
1226 * @ntb: pointer to ntb_softc instance
1227 * @idx: index to the scratchpad register, 0 based
1228 * @val: the data value to put into the register
1230 * This function allows writing of a 32bit value to the indexed scratchpad
1231 * register. The register resides on the secondary (external) side.
1233 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1236 ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val)
1239 if (idx >= ntb->limits.max_spads)
1242 if (HAS_FEATURE(NTB_REGS_THRU_MW))
1243 ntb_mw_write(4, XEON_SHADOW_SPAD_OFFSET + idx * 4, val);
1245 ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val);
1251 * ntb_read_remote_spad() - read from the primary scratchpad register
1252 * @ntb: pointer to ntb_softc instance
1253 * @idx: index to scratchpad register, 0 based
1254 * @val: pointer to 32bit integer for storing the register value
1256 * This function allows reading of the 32bit scratchpad register on
1257 * the primary (internal) side.
1259 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1262 ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val)
1265 if (idx >= ntb->limits.max_spads)
1268 if (HAS_FEATURE(NTB_REGS_THRU_MW))
1269 *val = ntb_mw_read(4, XEON_SHADOW_SPAD_OFFSET + idx * 4);
1271 *val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4);
1277 * ntb_get_mw_vbase() - get virtual addr for the NTB memory window
1278 * @ntb: pointer to ntb_softc instance
1279 * @mw: memory window number
1281 * This function provides the base virtual address of the memory window
1284 * RETURNS: pointer to virtual address, or NULL on error.
1287 ntb_get_mw_vbase(struct ntb_softc *ntb, unsigned int mw)
1290 if (mw >= NTB_NUM_MW)
1293 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].vbase);
1297 ntb_get_mw_pbase(struct ntb_softc *ntb, unsigned int mw)
1300 if (mw >= NTB_NUM_MW)
1303 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].pbase);
1307 * ntb_get_mw_size() - return size of NTB memory window
1308 * @ntb: pointer to ntb_softc instance
1309 * @mw: memory window number
1311 * This function provides the physical size of the memory window specified
1313 * RETURNS: the size of the memory window or zero on error
1316 ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw)
1319 if (mw >= NTB_NUM_MW)
1322 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].size);
1326 * ntb_set_mw_addr - set the memory window address
1327 * @ntb: pointer to ntb_softc instance
1328 * @mw: memory window number
1329 * @addr: base address for data
1331 * This function sets the base physical address of the memory window. This
1332 * memory address is where data from the remote system will be transfered into
1333 * or out of depending on how the transport is configured.
1336 ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr)
1339 if (mw >= NTB_NUM_MW)
1342 switch (NTB_MW_TO_BAR(mw)) {
1344 ntb_reg_write(8, ntb->reg_ofs.sbar2_xlat, addr);
1347 ntb_reg_write(8, ntb->reg_ofs.sbar4_xlat, addr);
1353 * ntb_ring_sdb() - Set the doorbell on the secondary/external side
1354 * @ntb: pointer to ntb_softc instance
1355 * @db: doorbell to ring
1357 * This function allows triggering of a doorbell on the secondary/external
1358 * side that will initiate an interrupt on the remote host
1360 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1363 ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db)
1366 if (ntb->type == NTB_SOC)
1367 ntb_reg_write(8, ntb->reg_ofs.sdb, (uint64_t) 1 << db);
1369 if (HAS_FEATURE(NTB_REGS_THRU_MW))
1370 ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET,
1371 ((1 << ntb->bits_per_vector) - 1) <<
1372 (db * ntb->bits_per_vector));
1374 ntb_reg_write(2, ntb->reg_ofs.sdb,
1375 ((1 << ntb->bits_per_vector) - 1) <<
1376 (db * ntb->bits_per_vector));
1380 * ntb_query_link_status() - return the hardware link status
1381 * @ndev: pointer to ntb_device instance
1383 * Returns true if the hardware is connected to the remote system
1385 * RETURNS: true or false based on the hardware link state
1388 ntb_query_link_status(struct ntb_softc *ntb)
1391 return (ntb->link_status == NTB_LINK_UP);
1395 save_bar_parameters(struct ntb_pci_bar_info *bar)
1398 rman_get_bustag(bar->pci_resource);
1399 bar->pci_bus_handle =
1400 rman_get_bushandle(bar->pci_resource);
1402 rman_get_start(bar->pci_resource);
1404 rman_get_size(bar->pci_resource);
1406 rman_get_virtual(bar->pci_resource);
1410 device_t ntb_get_device(struct ntb_softc *ntb)
1413 return (ntb->device);