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