1/*- 2 * Copyright (C) 2013 Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/kernel.h> 32#include <sys/systm.h> 33#include <sys/bus.h> 34#include <sys/malloc.h> 35#include <sys/module.h> 36#include <sys/queue.h> 37#include <sys/rman.h> 38#include <vm/vm.h> 39#include <vm/pmap.h> 40#include <machine/bus.h> 41#include <machine/pmap.h> 42#include <machine/resource.h> 43#include <dev/pci/pcireg.h> 44#include <dev/pci/pcivar.h> 45 46#include "ntb_regs.h" 47#include "ntb_hw.h" 48 49/* 50 * The Non-Transparent Bridge (NTB) is a device on some Intel processors that 51 * allows you to connect two systems using a PCI-e link. 52 * 53 * This module contains the hardware abstraction layer for the NTB. It allows 54 * you to send and recieve interrupts, map the memory windows and send and 55 * receive messages in the scratch-pad registers. 56 * 57 * NOTE: Much of the code in this module is shared with Linux. Any patches may 58 * be picked up and redistributed in Linux with a dual GPL/BSD license. 59 */ 60 61#define NTB_CONFIG_BAR 0 62#define NTB_B2B_BAR_1 1 63#define NTB_B2B_BAR_2 2 64#define NTB_MAX_BARS 3 65#define NTB_MW_TO_BAR(mw) ((mw) + 1) 66 67#define MAX_MSIX_INTERRUPTS MAX(XEON_MAX_DB_BITS, SOC_MAX_DB_BITS) 68 69#define NTB_HB_TIMEOUT 1 /* second */ 70#define SOC_LINK_RECOVERY_TIME 500 71 72#define DEVICE2SOFTC(dev) ((struct ntb_softc *) device_get_softc(dev)) 73 74enum ntb_device_type { 75 NTB_XEON, 76 NTB_SOC 77}; 78 79/* Device features and workarounds */ 80#define HAS_FEATURE(feature) \ 81 ((ntb->features & (feature)) != 0) 82 83#define NTB_BAR_SIZE_4K (1 << 0) 84#define NTB_REGS_THRU_MW (1 << 1) 85 86struct ntb_hw_info { 87 uint32_t device_id; 88 const char *desc; 89 enum ntb_device_type type; 90 uint64_t features; 91}; 92 93struct ntb_pci_bar_info { 94 bus_space_tag_t pci_bus_tag; 95 bus_space_handle_t pci_bus_handle; 96 int pci_resource_id; 97 struct resource *pci_resource; 98 vm_paddr_t pbase; 99 void *vbase; 100 u_long size; 101}; 102 103struct ntb_int_info { 104 struct resource *res; 105 int rid; 106 void *tag; 107}; 108 109struct ntb_db_cb { 110 ntb_db_callback callback; 111 unsigned int db_num; 112 void *data; 113 struct ntb_softc *ntb; 114}; 115 116struct ntb_softc { 117 device_t device; 118 enum ntb_device_type type; 119 uint64_t features; 120 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; 124 125 struct callout heartbeat_timer; 126 struct callout lr_timer; 127 128 void *ntb_transport; 129 ntb_event_callback event_cb; 130 struct ntb_db_cb *db_cb; 131 132 struct { 133 uint32_t max_spads; 134 uint32_t max_db_bits; 135 uint32_t msix_cnt; 136 } limits; 137 struct { 138 uint32_t pdb; 139 uint32_t pdb_mask; 140 uint32_t sdb; 141 uint32_t sbar2_xlat; 142 uint32_t sbar4_xlat; 143 uint32_t spad_remote; 144 uint32_t spad_local; 145 uint32_t lnk_cntl; 146 uint32_t lnk_stat; 147 uint32_t spci_cmd; 148 } reg_ofs; 149 uint8_t conn_type; 150 uint8_t dev_type; 151 uint8_t bits_per_vector; 152 uint8_t link_status; 153 uint8_t link_width; 154 uint8_t link_speed; 155}; 156 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) 169 170typedef int (*bar_map_strategy)(struct ntb_softc *ntb, 171 struct ntb_pci_bar_info *bar); 172 173static int ntb_probe(device_t device); 174static int ntb_attach(device_t device); 175static int ntb_detach(device_t device); 176static int ntb_map_pci_bars(struct ntb_softc *ntb); 177static int map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy, 178 struct ntb_pci_bar_info *bar); 179static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar); 180static int map_memory_window_bar(struct ntb_softc *ntb, 181 struct ntb_pci_bar_info *bar); 182static void ntb_unmap_pci_bar(struct ntb_softc *ntb); 183static int ntb_setup_interrupts(struct ntb_softc *ntb); 184static void ntb_teardown_interrupts(struct ntb_softc *ntb); 185static void handle_soc_irq(void *arg); 186static void handle_xeon_irq(void *arg); 187static void handle_xeon_event_irq(void *arg); 188static void ntb_handle_legacy_interrupt(void *arg); 189static int ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors); 190static void ntb_free_callbacks(struct ntb_softc *ntb); 191static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id); 192static int ntb_initialize_hw(struct ntb_softc *ntb); 193static int ntb_setup_xeon(struct ntb_softc *ntb); 194static int ntb_setup_soc(struct ntb_softc *ntb); 195static void configure_soc_secondary_side_bars(struct ntb_softc *ntb); 196static void configure_xeon_secondary_side_bars(struct ntb_softc *ntb); 197static void ntb_handle_heartbeat(void *arg); 198static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state); 199static void recover_soc_link(void *arg); 200static int ntb_check_link_status(struct ntb_softc *ntb); 201static void save_bar_parameters(struct ntb_pci_bar_info *bar); 202 203static struct ntb_hw_info pci_ids[] = { 204 { 0x3C0D8086, "Xeon E5/Core i7 Non-Transparent Bridge B2B", NTB_XEON, 205 NTB_REGS_THRU_MW }, 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 } 210}; 211 212/* 213 * OS <-> Driver interface structures 214 */ 215MALLOC_DEFINE(M_NTB, "ntb_hw", "ntb_hw driver memory allocations"); 216 217static 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), 222 DEVMETHOD_END 223}; 224 225static driver_t ntb_pci_driver = { 226 "ntb_hw", 227 ntb_pci_methods, 228 sizeof(struct ntb_softc), 229}; 230 231static devclass_t ntb_devclass; 232DRIVER_MODULE(ntb_hw, pci, ntb_pci_driver, ntb_devclass, NULL, NULL); 233MODULE_VERSION(ntb_hw, 1); 234 235/* 236 * OS <-> Driver linkage functions 237 */ 238static int 239ntb_probe(device_t device) 240{ 241 struct ntb_hw_info *p = ntb_get_device_info(pci_get_devid(device)); 242 243 if (p != NULL) { 244 device_set_desc(device, p->desc); 245 return (0); 246 } else 247 return (ENXIO); 248} 249 250#define DETACH_ON_ERROR(func) \ 251 error = func; \ 252 if (error < 0) { \ 253 ntb_detach(device); \ 254 return (error); \ 255 } 256 257static int 258ntb_attach(device_t device) 259{ 260 struct ntb_softc *ntb = DEVICE2SOFTC(device); 261 struct ntb_hw_info *p = ntb_get_device_info(pci_get_devid(device)); 262 int error; 263 264 ntb->device = device; 265 ntb->type = p->type; 266 ntb->features = p->features; 267 268 /* Heartbeat timer for NTB_SOC since there is no link interrupt */ 269 callout_init(&ntb->heartbeat_timer, CALLOUT_MPSAFE); 270 callout_init(&ntb->lr_timer, CALLOUT_MPSAFE); 271 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)); 275 276 pci_enable_busmaster(ntb->device); 277 278 return (error); 279} 280 281static int 282ntb_detach(device_t device) 283{ 284 struct ntb_softc *ntb = DEVICE2SOFTC(device); 285 286 callout_drain(&ntb->heartbeat_timer); 287 callout_drain(&ntb->lr_timer); 288 ntb_teardown_interrupts(ntb); 289 ntb_unmap_pci_bar(ntb); 290 291 return (0); 292} 293 294static int 295ntb_map_pci_bars(struct ntb_softc *ntb) 296{ 297 int rc; 298 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]); 301 if (rc != 0) 302 return rc; 303 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]); 307 if (rc != 0) 308 return rc; 309 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]); 314 else 315 rc = map_pci_bar(ntb, map_memory_window_bar, 316 &ntb->bar_info[NTB_B2B_BAR_2]); 317 if (rc != 0) 318 return rc; 319 320 return (0); 321} 322 323static int 324map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy, 325 struct ntb_pci_bar_info *bar) 326{ 327 int rc; 328 329 rc = strategy(ntb, bar); 330 if (rc != 0) { 331 device_printf(ntb->device, 332 "unable to allocate pci resource\n"); 333 } else { 334 device_printf(ntb->device, 335 "Bar size = %lx, v %p, p %p\n", 336 bar->size, bar->vbase, 337 (void *)(bar->pbase)); 338 } 339 return (rc); 340} 341 342static int 343map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) 344{ 345 346 bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, 347 &bar->pci_resource_id, RF_ACTIVE); 348 349 if (bar->pci_resource == NULL) 350 return (ENXIO); 351 else { 352 save_bar_parameters(bar); 353 return (0); 354 } 355} 356 357static int 358map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) 359{ 360 int rc; 361 uint8_t bar_size_bits = 0; 362 363 bar->pci_resource = bus_alloc_resource_any(ntb->device, 364 SYS_RES_MEMORY, &bar->pci_resource_id, RF_ACTIVE); 365 366 if (bar->pci_resource == NULL) 367 return (ENXIO); 368 else { 369 save_bar_parameters(bar); 370 /* 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. 377 * 378 * Ideally I could have just specified the size when I allocated 379 * the resource like: 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. 385 */ 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); 390 else 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); 396 if (rc != 0 ) { 397 device_printf(ntb->device, 398 "unable to resize bar\n"); 399 return (rc); 400 } else 401 save_bar_parameters(bar); 402 } 403 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); 407 if (rc != 0) { 408 device_printf(ntb->device, "unable to mark bar as" 409 " WRITE_COMBINING\n"); 410 return (rc); 411 } 412 } 413 return (0); 414} 415 416static void 417ntb_unmap_pci_bar(struct ntb_softc *ntb) 418{ 419 struct ntb_pci_bar_info *current_bar; 420 int i; 421 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); 428 } 429} 430 431static int 432ntb_setup_interrupts(struct ntb_softc *ntb) 433{ 434 void (*interrupt_handler)(void *); 435 void *int_arg; 436 bool use_msix = 0; 437 uint32_t num_vectors; 438 int i; 439 440 ntb->allocated_interrupts = 0; 441 /* 442 * On SOC, disable all interrupts. On XEON, disable all but Link 443 * Interrupt. The rest will be unmasked as callbacks are registered. 444 */ 445 if (ntb->type == NTB_SOC) 446 ntb_reg_write(8, ntb->reg_ofs.pdb_mask, ~0); 447 else 448 ntb_reg_write(2, ntb->reg_ofs.pdb_mask, 449 ~(1 << ntb->limits.max_db_bits)); 450 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) 456 use_msix = TRUE; 457 } 458 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, 465 RF_ACTIVE); 466 if (ntb->int_info[i].res == NULL) { 467 device_printf(ntb->device, 468 "bus_alloc_resource failed\n"); 469 return (-1); 470 } 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]; 476 } else { 477 if (i == num_vectors - 1) { 478 interrupt_handler = 479 handle_xeon_event_irq; 480 int_arg = ntb; 481 } else { 482 interrupt_handler = 483 handle_xeon_irq; 484 int_arg = &ntb->db_cb[i]; 485 } 486 } 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"); 493 return (ENXIO); 494 } 495 } 496 } 497 else { 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"); 505 return (-1); 506 } 507 ntb->int_info[0].tag = NULL; 508 ntb->allocated_interrupts = 1; 509 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) { 513 514 device_printf(ntb->device, "bus_setup_intr failed\n"); 515 return (ENXIO); 516 } 517 } 518 519 return (0); 520} 521 522static void 523ntb_teardown_interrupts(struct ntb_softc *ntb) 524{ 525 struct ntb_int_info *current_int; 526 int i; 527 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, 532 current_int->tag); 533 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); 537 } 538 539 ntb_free_callbacks(ntb); 540 pci_release_msi(ntb->device); 541} 542 543static void 544handle_soc_irq(void *arg) 545{ 546 struct ntb_db_cb *db_cb = arg; 547 struct ntb_softc *ntb = db_cb->ntb; 548 549 ntb_reg_write(8, ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num); 550 551 if (db_cb->callback != NULL) 552 db_cb->callback(db_cb->data, db_cb->db_num); 553} 554 555static void 556handle_xeon_irq(void *arg) 557{ 558 struct ntb_db_cb *db_cb = arg; 559 struct ntb_softc *ntb = db_cb->ntb; 560 561 /* 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 565 * interrupts. 566 */ 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)); 570 571 if (db_cb->callback != NULL) 572 db_cb->callback(db_cb->data, db_cb->db_num); 573} 574 575/* Since we do not have a HW doorbell in SOC, this is only used in JF/JT */ 576static void 577handle_xeon_event_irq(void *arg) 578{ 579 struct ntb_softc *ntb = arg; 580 int rc; 581 582 rc = ntb_check_link_status(ntb); 583 if (rc != 0) 584 device_printf(ntb->device, "Error determining link status\n"); 585 586 /* bit 15 is always the link bit */ 587 ntb_reg_write(2, ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits); 588} 589 590static void 591ntb_handle_legacy_interrupt(void *arg) 592{ 593 struct ntb_softc *ntb = arg; 594 unsigned int i = 0; 595 uint64_t pdb64; 596 uint16_t pdb16; 597 598 if (ntb->type == NTB_SOC) { 599 pdb64 = ntb_reg_read(8, ntb->reg_ofs.pdb); 600 601 while (pdb64) { 602 i = ffs(pdb64); 603 pdb64 &= pdb64 - 1; 604 handle_soc_irq(&ntb->db_cb[i]); 605 } 606 } else { 607 pdb16 = ntb_reg_read(2, ntb->reg_ofs.pdb); 608 609 if ((pdb16 & XEON_DB_HW_LINK) != 0) { 610 handle_xeon_event_irq(ntb); 611 pdb16 &= ~XEON_DB_HW_LINK; 612 } 613 614 while (pdb16 != 0) { 615 i = ffs(pdb16); 616 pdb16 &= pdb16 - 1; 617 handle_xeon_irq(&ntb->db_cb[i]); 618 } 619 } 620 621} 622 623static int 624ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors) 625{ 626 int i; 627 628 ntb->db_cb = malloc(num_vectors * sizeof(struct ntb_db_cb), M_NTB, 629 M_ZERO | M_WAITOK); 630 for (i = 0; i < num_vectors; i++) { 631 ntb->db_cb[i].db_num = i; 632 ntb->db_cb[i].ntb = ntb; 633 } 634 635 return (0); 636} 637 638static void 639ntb_free_callbacks(struct ntb_softc *ntb) 640{ 641 int i; 642 643 for (i = 0; i < ntb->limits.max_db_bits; i++) 644 ntb_unregister_db_callback(ntb, i); 645 646 free(ntb->db_cb, M_NTB); 647} 648 649static struct ntb_hw_info * 650ntb_get_device_info(uint32_t device_id) 651{ 652 struct ntb_hw_info *ep = pci_ids; 653 654 while (ep->device_id) { 655 if (ep->device_id == device_id) 656 return (ep); 657 ++ep; 658 } 659 return (NULL); 660} 661 662static int 663ntb_initialize_hw(struct ntb_softc *ntb) 664{ 665 666 if (ntb->type == NTB_SOC) 667 return (ntb_setup_soc(ntb)); 668 else 669 return (ntb_setup_xeon(ntb)); 670} 671 672static int 673ntb_setup_xeon(struct ntb_softc *ntb) 674{ 675 uint8_t val, connection_type; 676 677 val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1); 678 679 connection_type = val & XEON_PPD_CONN_TYPE; 680 switch (connection_type) { 681 case NTB_CONN_B2B: 682 ntb->conn_type = NTB_CONN_B2B; 683 break; 684 case NTB_CONN_CLASSIC: 685 case NTB_CONN_RP: 686 default: 687 device_printf(ntb->device, "Connection type %d not supported\n", 688 connection_type); 689 return (ENXIO); 690 } 691 692 if ((val & XEON_PPD_DEV_TYPE) != 0) 693 ntb->dev_type = NTB_DEV_DSD; 694 else 695 ntb->dev_type = NTB_DEV_USD; 696 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; 705 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; 710 } else { 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; 714 } 715 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; 719 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); 724 725 /* Enable link training */ 726 ntb_reg_write(4, ntb->reg_ofs.lnk_cntl, 727 NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP); 728 729 return (0); 730} 731 732static int 733ntb_setup_soc(struct ntb_softc *ntb) 734{ 735 uint32_t val, connection_type; 736 737 val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4); 738 739 connection_type = (val & SOC_PPD_CONN_TYPE) >> 8; 740 switch (connection_type) { 741 case NTB_CONN_B2B: 742 ntb->conn_type = NTB_CONN_B2B; 743 break; 744 case NTB_CONN_RP: 745 default: 746 device_printf(ntb->device, "Connection type %d not supported\n", 747 connection_type); 748 return (ENXIO); 749 } 750 751 if ((val & SOC_PPD_DEV_TYPE) != 0) 752 ntb->dev_type = NTB_DEV_DSD; 753 else 754 ntb->dev_type = NTB_DEV_USD; 755 756 /* Initiate PCI-E link training */ 757 pci_write_config(ntb->device, NTB_PPD_OFFSET, val | SOC_PPD_INIT_LINK, 758 4); 759 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; 768 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; 773 } else { 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; 777 } 778 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; 782 783 /* 784 * FIXME - MSI-X bug on early SOC HW, remove once internal issue is 785 * resolved. Mask transaction layer internal parity errors. 786 */ 787 pci_write_config(ntb->device, 0xFC, 0x4, 4); 788 789 configure_soc_secondary_side_bars(ntb); 790 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); 795 796 return (0); 797} 798 799static void 800configure_soc_secondary_side_bars(struct ntb_softc *ntb) 801{ 802 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); 808 } else { 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); 813 } 814} 815 816static void 817configure_xeon_secondary_side_bars(struct ntb_softc *ntb) 818{ 819 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, 824 MBAR01_DSD_ADDR); 825 else 826 ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, 827 PBAR4XLAT_USD_ADDR); 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); 831 } else { 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, 835 MBAR01_USD_ADDR); 836 else 837 ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, 838 PBAR4XLAT_DSD_ADDR); 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); 842 } 843} 844 845/* SOC does not have link status interrupt, poll on that platform */ 846static void 847ntb_handle_heartbeat(void *arg) 848{ 849 struct ntb_softc *ntb = arg; 850 uint32_t status32; 851 int rc = ntb_check_link_status(ntb); 852 853 if (rc != 0) 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, 861 ntb); 862 return; 863 } 864 } 865 866 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz, 867 ntb_handle_heartbeat, ntb); 868} 869 870static void 871soc_perform_link_restart(struct ntb_softc *ntb) 872{ 873 uint32_t status; 874 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); 880 881 /* Driver waits 100ms to allow the NTB ModPhy to settle */ 882 pause("ModPhy", hz / 10); 883 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); 888 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); 893 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); 898 899 status = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET); 900 status &= SOC_IBIST_ERR_OFLOW; 901 ntb_reg_write(4, SOC_IBSTERRRCRVSTS0_OFFSET, status); 902 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); 907} 908 909static void 910ntb_handle_link_event(struct ntb_softc *ntb, int link_state) 911{ 912 enum ntb_hw_event event; 913 uint16_t status; 914 915 if (ntb->link_status == link_state) 916 return; 917 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; 922 923 if (ntb->type == NTB_SOC) 924 status = ntb_reg_read(2, ntb->reg_ofs.lnk_stat); 925 else 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); 934 } else { 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 */ 939 } 940 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); 944} 945 946static void 947recover_soc_link(void *arg) 948{ 949 struct ntb_softc *ntb = arg; 950 uint8_t speed, width; 951 uint32_t status32; 952 uint16_t status16; 953 954 soc_perform_link_restart(ntb); 955 pause("Link", SOC_LINK_RECOVERY_TIME * hz / 1000); 956 957 status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET); 958 if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) 959 goto retry; 960 961 status32 = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET); 962 if ((status32 & SOC_IBIST_ERR_OFLOW) != 0) 963 goto retry; 964 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) 969 goto retry; 970 971 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz, 972 ntb_handle_heartbeat, ntb); 973 return; 974 975retry: 976 callout_reset(&ntb->lr_timer, NTB_HB_TIMEOUT * hz, recover_soc_link, 977 ntb); 978} 979 980static int 981ntb_check_link_status(struct ntb_softc *ntb) 982{ 983 int link_state; 984 uint32_t ntb_cntl; 985 uint16_t status; 986 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; 991 else 992 link_state = NTB_LINK_UP; 993 } else { 994 status = pci_read_config(ntb->device, XEON_LINK_STATUS_OFFSET, 995 2); 996 997 if ((status & NTB_LINK_STATUS_ACTIVE) != 0) 998 link_state = NTB_LINK_UP; 999 else 1000 link_state = NTB_LINK_DOWN; 1001 } 1002 1003 ntb_handle_link_event(ntb, link_state); 1004 1005 return (0); 1006} 1007 1008/** 1009 * ntb_register_event_callback() - register event callback 1010 * @ntb: pointer to ntb_softc instance 1011 * @func: callback function to register 1012 * 1013 * This function registers a callback for any HW driver events such as link 1014 * up/down, power management notices and etc. 1015 * 1016 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1017 */ 1018int 1019ntb_register_event_callback(struct ntb_softc *ntb, ntb_event_callback func) 1020{ 1021 1022 if (ntb->event_cb != NULL) 1023 return (EINVAL); 1024 1025 ntb->event_cb = func; 1026 1027 return (0); 1028} 1029 1030/** 1031 * ntb_unregister_event_callback() - unregisters the event callback 1032 * @ntb: pointer to ntb_softc instance 1033 * 1034 * This function unregisters the existing callback from transport 1035 */ 1036void 1037ntb_unregister_event_callback(struct ntb_softc *ntb) 1038{ 1039 1040 ntb->event_cb = NULL; 1041} 1042 1043/** 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 1048 * 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 1051 * allow interrupt. 1052 * 1053 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1054 */ 1055int 1056ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data, 1057 ntb_db_callback func) 1058{ 1059 uint16_t mask; 1060 1061 if (idx >= ntb->allocated_interrupts || ntb->db_cb[idx].callback) { 1062 device_printf(ntb->device, "Invalid Index.\n"); 1063 return (EINVAL); 1064 } 1065 1066 ntb->db_cb[idx].callback = func; 1067 ntb->db_cb[idx].data = data; 1068 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); 1073 1074 return (0); 1075} 1076 1077/** 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 1081 * 1082 * This function unregisters a callback function for the doorbell interrupt 1083 * on the primary side. The function will also mask the said doorbell. 1084 */ 1085void 1086ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx) 1087{ 1088 unsigned long mask; 1089 1090 if (idx >= ntb->allocated_interrupts || !ntb->db_cb[idx].callback) 1091 return; 1092 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); 1096 1097 ntb->db_cb[idx].callback = NULL; 1098} 1099 1100/** 1101 * ntb_find_transport() - find the transport pointer 1102 * @transport: pointer to pci device 1103 * 1104 * Given the pci device pointer, return the transport pointer passed in when 1105 * the transport attached when it was inited. 1106 * 1107 * RETURNS: pointer to transport. 1108 */ 1109void * 1110ntb_find_transport(struct ntb_softc *ntb) 1111{ 1112 1113 return (ntb->ntb_transport); 1114} 1115 1116/** 1117 * ntb_register_transport() - Register NTB transport with NTB HW driver 1118 * @transport: transport identifier 1119 * 1120 * This function allows a transport to reserve the hardware driver for 1121 * NTB usage. 1122 * 1123 * RETURNS: pointer to ntb_softc, NULL on error. 1124 */ 1125struct ntb_softc * 1126ntb_register_transport(struct ntb_softc *ntb, void *transport) 1127{ 1128 1129 /* 1130 * TODO: when we have more than one transport, we will need to rewrite 1131 * this to prevent race conditions 1132 */ 1133 if (ntb->ntb_transport != NULL) 1134 return (NULL); 1135 1136 ntb->ntb_transport = transport; 1137 return (ntb); 1138} 1139 1140/** 1141 * ntb_unregister_transport() - Unregister the transport with the NTB HW driver 1142 * @ntb - ntb_softc of the transport to be freed 1143 * 1144 * This function unregisters the transport from the HW driver and performs any 1145 * necessary cleanups. 1146 */ 1147void 1148ntb_unregister_transport(struct ntb_softc *ntb) 1149{ 1150 int i; 1151 1152 if (ntb->ntb_transport == NULL) 1153 return; 1154 1155 for (i = 0; i < ntb->allocated_interrupts; i++) 1156 ntb_unregister_db_callback(ntb, i); 1157 1158 ntb_unregister_event_callback(ntb); 1159 ntb->ntb_transport = NULL; 1160} 1161 1162/** 1163 * ntb_get_max_spads() - get the total scratch regs usable 1164 * @ntb: pointer to ntb_softc instance 1165 * 1166 * This function returns the max 32bit scratchpad registers usable by the 1167 * upper layer. 1168 * 1169 * RETURNS: total number of scratch pad registers available 1170 */ 1171int 1172ntb_get_max_spads(struct ntb_softc *ntb) 1173{ 1174 1175 return (ntb->limits.max_spads); 1176} 1177 1178/** 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 1183 * 1184 * This function allows writing of a 32bit value to the indexed scratchpad 1185 * register. The register resides on the secondary (external) side. 1186 * 1187 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1188 */ 1189int 1190ntb_write_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) 1191{ 1192 1193 if (idx >= ntb->limits.max_spads) 1194 return (EINVAL); 1195 1196 ntb_reg_write(4, ntb->reg_ofs.spad_local + idx * 4, val); 1197 1198 return (0); 1199} 1200 1201/** 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 1206 * 1207 * This function allows reading of the 32bit scratchpad register on 1208 * the primary (internal) side. 1209 * 1210 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1211 */ 1212int 1213ntb_read_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) 1214{ 1215 1216 if (idx >= ntb->limits.max_spads) 1217 return (EINVAL); 1218 1219 *val = ntb_reg_read(4, ntb->reg_ofs.spad_local + idx * 4); 1220 1221 return (0); 1222} 1223 1224/** 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 1229 * 1230 * This function allows writing of a 32bit value to the indexed scratchpad 1231 * register. The register resides on the secondary (external) side. 1232 * 1233 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1234 */ 1235int 1236ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) 1237{ 1238 1239 if (idx >= ntb->limits.max_spads) 1240 return (EINVAL); 1241 1242 if (HAS_FEATURE(NTB_REGS_THRU_MW)) 1243 ntb_mw_write(4, XEON_SHADOW_SPAD_OFFSET + idx * 4, val); 1244 else 1245 ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val); 1246 1247 return (0); 1248} 1249 1250/** 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 1255 * 1256 * This function allows reading of the 32bit scratchpad register on 1257 * the primary (internal) side. 1258 * 1259 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1260 */ 1261int 1262ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) 1263{ 1264 1265 if (idx >= ntb->limits.max_spads) 1266 return (EINVAL); 1267 1268 if (HAS_FEATURE(NTB_REGS_THRU_MW)) 1269 *val = ntb_mw_read(4, XEON_SHADOW_SPAD_OFFSET + idx * 4); 1270 else 1271 *val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4); 1272 1273 return (0); 1274} 1275 1276/** 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 1280 * 1281 * This function provides the base virtual address of the memory window 1282 * specified. 1283 * 1284 * RETURNS: pointer to virtual address, or NULL on error. 1285 */ 1286void * 1287ntb_get_mw_vbase(struct ntb_softc *ntb, unsigned int mw) 1288{ 1289 1290 if (mw >= NTB_NUM_MW) 1291 return (NULL); 1292 1293 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].vbase); 1294} 1295 1296vm_paddr_t 1297ntb_get_mw_pbase(struct ntb_softc *ntb, unsigned int mw) 1298{ 1299 1300 if (mw >= NTB_NUM_MW) 1301 return (0); 1302 1303 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].pbase); 1304} 1305 1306/** 1307 * ntb_get_mw_size() - return size of NTB memory window 1308 * @ntb: pointer to ntb_softc instance 1309 * @mw: memory window number 1310 * 1311 * This function provides the physical size of the memory window specified 1312 * 1313 * RETURNS: the size of the memory window or zero on error 1314 */ 1315u_long 1316ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw) 1317{ 1318 1319 if (mw >= NTB_NUM_MW) 1320 return (0); 1321 1322 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].size); 1323} 1324 1325/** 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 1330 * 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. 1334 */ 1335void 1336ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr) 1337{ 1338 1339 if (mw >= NTB_NUM_MW) 1340 return; 1341 1342 switch (NTB_MW_TO_BAR(mw)) { 1343 case NTB_B2B_BAR_1: 1344 ntb_reg_write(8, ntb->reg_ofs.sbar2_xlat, addr); 1345 break; 1346 case NTB_B2B_BAR_2: 1347 ntb_reg_write(8, ntb->reg_ofs.sbar4_xlat, addr); 1348 break; 1349 } 1350} 1351 1352/** 1353 * ntb_ring_sdb() - Set the doorbell on the secondary/external side 1354 * @ntb: pointer to ntb_softc instance 1355 * @db: doorbell to ring 1356 * 1357 * This function allows triggering of a doorbell on the secondary/external 1358 * side that will initiate an interrupt on the remote host 1359 * 1360 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1361 */ 1362void 1363ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db) 1364{ 1365 1366 if (ntb->type == NTB_SOC) 1367 ntb_reg_write(8, ntb->reg_ofs.sdb, (uint64_t) 1 << db); 1368 else 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)); 1373 else 1374 ntb_reg_write(2, ntb->reg_ofs.sdb, 1375 ((1 << ntb->bits_per_vector) - 1) << 1376 (db * ntb->bits_per_vector)); 1377} 1378 1379/** 1380 * ntb_query_link_status() - return the hardware link status 1381 * @ndev: pointer to ntb_device instance 1382 * 1383 * Returns true if the hardware is connected to the remote system 1384 * 1385 * RETURNS: true or false based on the hardware link state 1386 */ 1387bool 1388ntb_query_link_status(struct ntb_softc *ntb) 1389{ 1390 1391 return (ntb->link_status == NTB_LINK_UP); 1392} 1393 1394static void 1395save_bar_parameters(struct ntb_pci_bar_info *bar) 1396{ 1397 bar->pci_bus_tag = 1398 rman_get_bustag(bar->pci_resource); 1399 bar->pci_bus_handle = 1400 rman_get_bushandle(bar->pci_resource); 1401 bar->pbase = 1402 rman_get_start(bar->pci_resource); 1403 bar->size = 1404 rman_get_size(bar->pci_resource); 1405 bar->vbase = 1406 rman_get_virtual(bar->pci_resource); 1407 1408} 1409 1410device_t ntb_get_device(struct ntb_softc *ntb) 1411{ 1412 1413 return (ntb->device); 1414} 1415