plibde.c (14571B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 */ 7 8 #ifdef LINUX_PLI_COMBO_BDE 9 /* Avoid name clash when using two BDEs */ 10 #define pci_config_getw pli_pci_config_getw 11 #endif 12 13 #ifdef LINUX_SAL_DMA_ALLOC_OVERRIDE 14 /* Must match name change in src/sal/core/unix/alloc.c */ 15 #define sal_dma_alloc sal_sim_dma_alloc 16 #define sal_dma_free sal_sim_dma_free 17 #endif 18 19 #include <shared/bsl.h> 20 21 #include "plibde.h" 22 23 #include <sal/types.h> 24 #include <sal/appl/pci.h> 25 #include <sal/appl/sal.h> 26 #include <soc/devids.h> 27 #include <soc/defs.h> 28 #include <sal/appl/io.h> 29 #include <sal/appl/config.h> 30 #include <sal/core/libc.h> 31 #include <sal/core/boot.h> 32 #include <sal/core/alloc.h> 33 #include <shared/util.h> 34 #include <stdio.h> 35 36 #ifdef SINGLE_MODE 37 #include <sim/pcid/pcid.h> 38 39 extern pcid_info_t pcid_info; 40 extern int _local_setup(pcid_info_t* pcid_info, char *chip_name, uint16 *dev_id, uint8 *rev_id); 41 #endif 42 43 /* 44 * PLI BDE 45 * 46 * Currently, the implementation is 47 * based directly on the old SAL architecture. 48 * As soon as the BDE migration is complete and tested, 49 * the old SAL architecture will be remove, 50 * and it will be implemented properly. 51 */ 52 #define PLI_PCI_MBAR0 0x00000000 53 #define PLI_PCI_ILINE(dev) (0 + (dev)) 54 55 typedef struct vxbde_dev_s { 56 ibde_dev_t bde_dev; 57 pci_dev_t pci_dev; 58 uint32 cmic_base; 59 } plibde_dev_t; 60 61 #if !defined(PLI_MAX_DEVICES) 62 #define PLI_MAX_DEVICES 16 63 #endif 64 65 static plibde_dev_t _devices[PLI_MAX_DEVICES]; 66 static int _n_devices = 0; 67 68 STATIC const char* 69 _cmodel_bde_name(void) 70 { 71 return "dpp-cmodel-bde"; 72 } 73 74 STATIC int 75 _cmodel_bde_num_devices(int type) 76 { 77 return 1; 78 } 79 80 STATIC const ibde_dev_t* 81 _cmodel_bde_get_dev(int d) 82 { 83 if(d < 0 || d > _n_devices) { 84 return NULL; 85 } 86 87 return &_devices[d].bde_dev; 88 } 89 90 STATIC uint32 91 _cmodel_bde_get_dev_type(int d) 92 { 93 if(d < 0 || d > _n_devices) { 94 return 0; 95 } 96 return BDE_PCI_DEV_TYPE; 97 } 98 99 STATIC uint32 100 _cmodel_bde_pci_config_read(int d, uint32 addr) 101 { 102 return (0xffffffff); /* not supported */ 103 } 104 105 STATIC int 106 _cmodel_bde_pci_config_write(int d, uint32 addr, uint32 data) 107 { 108 return (-1); /* not supported */ 109 } 110 111 STATIC void 112 _cmodel_bde_pci_bus_features(int unit, int* be_pio, int* be_packet, int* be_other) 113 { 114 *be_pio = 0; 115 *be_packet = 0; 116 *be_other = 0; 117 } 118 119 120 /* function for mock access to device BARs (iproc and CMIC) */ 121 STATIC uint32 122 _cmodel_bde_memory_read(int d, uint32 addr) 123 { 124 return 0; 125 } 126 127 /* function for mock access to device BARs (iproc and CMIC) */ 128 STATIC int 129 _cmodel_bde_memory_write(int d, uint32 addr, uint32 data) 130 { 131 return 0; 132 } 133 134 STATIC uint32* 135 _cmodel_bde_salloc(int d, int size, const char *name) 136 { 137 return sal_dma_alloc(size, (char *)name); 138 } 139 140 STATIC void 141 _cmodel_bde_sfree(int d, void* ptr) 142 { 143 sal_dma_free(ptr); 144 } 145 146 STATIC int 147 _cmodel_bde_sflush(int d, void* addr, int length) 148 { 149 sal_dma_flush(addr, length); 150 return 0; 151 } 152 153 STATIC int 154 _cmodel_bde_sinval(int d, void* addr, int length) 155 { 156 sal_dma_inval(addr, length); 157 return 0; 158 } 159 160 STATIC int 161 _cmodel_bde_interrupt_connect(int d, void (*isr)(void*), void* data) 162 { 163 return 0; 164 } 165 166 STATIC int 167 _cmodel_bde_interrupt_disconnect(int d) 168 { 169 return 0; 170 } 171 172 STATIC sal_paddr_t 173 _cmodel_bde_l2p(int d, void* laddr) 174 { 175 return PTR_TO_INT(laddr); 176 } 177 178 STATIC void* 179 _cmodel_bde_p2l(int d, sal_paddr_t paddr) 180 { 181 return INT_TO_PTR(paddr); 182 } 183 184 static ibde_t _cmodel_bde = { 185 _cmodel_bde_name, 186 _cmodel_bde_num_devices, 187 _cmodel_bde_get_dev, 188 _cmodel_bde_get_dev_type, 189 _cmodel_bde_pci_config_read, 190 _cmodel_bde_pci_config_write, 191 _cmodel_bde_pci_bus_features, 192 _cmodel_bde_memory_read, 193 _cmodel_bde_memory_write, 194 _cmodel_bde_salloc, 195 _cmodel_bde_sfree, 196 _cmodel_bde_sflush, 197 _cmodel_bde_sinval, 198 _cmodel_bde_interrupt_connect, 199 _cmodel_bde_interrupt_disconnect, 200 _cmodel_bde_l2p, 201 _cmodel_bde_p2l, 202 NULL, 203 NULL, 204 _cmodel_bde_memory_read, 205 _cmodel_bde_memory_write 206 }; 207 208 static const char* 209 _name(void) 210 { 211 return "pli-pci-bde"; 212 } 213 214 static int 215 _num_devices(int type) 216 { 217 switch (type) { 218 case BDE_ALL_DEVICES: 219 case BDE_SWITCH_DEVICES: 220 return _n_devices; 221 case BDE_ETHER_DEVICES: 222 return 0; 223 } 224 225 return 0; 226 } 227 228 static const ibde_dev_t* 229 _get_dev(int d) 230 { 231 if(d < 0 || d > _n_devices) { 232 return NULL; 233 } 234 return &_devices[d].bde_dev; 235 } 236 237 static uint32 238 _get_dev_type(int d) 239 { 240 return BDE_PCI_DEV_TYPE; 241 } 242 243 244 static uint32 245 _pci_read(int d, uint32 addr) 246 { 247 return pci_config_getw(&_devices[d].pci_dev, addr); 248 } 249 250 static int 251 _pci_write(int d, uint32 addr, uint32 data) 252 { 253 return pci_config_putw(&_devices[d].pci_dev, addr, data); 254 } 255 256 static void 257 _pci_bus_features(int unit, int* be_pio, int* be_packet, int* be_other) 258 { 259 #ifdef SYS_BE_PIO 260 *be_pio = SYS_BE_PIO; 261 #else 262 *be_pio = 0; 263 #endif 264 265 #ifdef SYS_BE_PACKET 266 *be_packet = SYS_BE_PACKET; 267 #else 268 *be_packet = (sal_boot_flags_get() & BOOT_F_RTLSIM) ? 1 : 0; 269 #endif 270 271 #ifdef SYS_BE_OTHER 272 *be_other = SYS_BE_OTHER; 273 #else 274 *be_other = 0; 275 #endif 276 } 277 278 279 static uint32 280 _read(int d, uint32 addr) 281 { 282 return pci_memory_getw(&_devices[d].pci_dev, 283 PLI_PCI_MBAR0 + _devices[d].cmic_base + addr); 284 } 285 286 static int 287 _write(int d, uint32 addr, uint32 data) 288 { 289 pci_memory_putw(&_devices[d].pci_dev, 290 PLI_PCI_MBAR0 + _devices[d].cmic_base + addr, data); 291 return 0; 292 } 293 294 static uint32* 295 _salloc(int d, int size, const char *name) 296 { 297 return sal_dma_alloc(size, (char *)name); 298 } 299 300 static void 301 _sfree(int d, void* ptr) 302 { 303 sal_dma_free(ptr); 304 } 305 306 static int 307 _sflush(int d, void* addr, int length) 308 { 309 sal_dma_flush(addr, length); 310 return 0; 311 } 312 313 static int 314 _sinval(int d, void* addr, int length) 315 { 316 sal_dma_inval(addr, length); 317 return 0; 318 } 319 320 static int 321 _interrupt_connect(int d, void (*isr)(void*), void* data) 322 { 323 return pci_int_connect(PLI_PCI_ILINE(d), isr, data); 324 } 325 326 static int 327 _interrupt_disconnect(int d) 328 { 329 return 0; 330 } 331 332 static sal_paddr_t 333 _l2p(int d, void* laddr) 334 { 335 return (sal_paddr_t)laddr; 336 } 337 338 static void * 339 _p2l(int d, sal_paddr_t paddr) 340 { 341 return (void *)paddr; 342 } 343 344 static uint32 345 _iproc_read(int d, uint32 addr) 346 { 347 return pci_memory_getw(&_devices[d].pci_dev, 348 PLI_PCI_MBAR0 + addr); 349 } 350 351 static int 352 _iproc_write(int d, uint32 addr, uint32 data) 353 { 354 pci_memory_putw(&_devices[d].pci_dev, 355 PLI_PCI_MBAR0 + addr, data); 356 return 0; 357 } 358 359 360 static ibde_t _ibde = { 361 _name, 362 _num_devices, 363 _get_dev, 364 _get_dev_type, 365 _pci_read, 366 _pci_write, 367 _pci_bus_features, 368 _read, 369 _write, 370 _salloc, 371 _sfree, 372 _sflush, 373 _sinval, 374 _interrupt_connect, 375 _interrupt_disconnect, 376 _l2p, 377 _p2l, 378 NULL, /* spi_read */ 379 NULL, /* spi_write */ 380 _iproc_read, 381 _iproc_write, 382 }; 383 384 static int 385 _setup(pci_dev_t* dev, 386 uint16 pciVenID, 387 uint16 pciDevID, 388 uint8 pciRevID) 389 { 390 plibde_dev_t* vxd; 391 uint32 tmp; 392 int devno; 393 394 if(pciVenID != BROADCOM_VENDOR_ID) { 395 return 0; 396 } 397 398 /* don't want to expose non 56XX devices */ 399 if (pciVenID == BROADCOM_VENDOR_ID) { 400 if(((pciDevID & 0xFF00) != 0x5600) && 401 ((pciDevID & 0xF000) != 0xc000) && 402 ((pciDevID & 0xFFF0) != 0x0230) && 403 ((pciDevID & 0xF000) != 0xb000) && 404 (pciDevID != BCM83207_DEVICE_ID) && 405 (pciDevID != BCM83208_DEVICE_ID) && 406 ((pciDevID & 0xFFF0) != BCM88650_DEVICE_ID) && 407 ((pciDevID & 0xFFFF) != BCM88675_DEVICE_ID) && 408 ((pciDevID & 0xFFFF) != BCM88375_DEVICE_ID) && 409 ((pciDevID & 0xFFFF) != BCM88680_DEVICE_ID) && 410 ((pciDevID & 0xFFFF) != BCM88690_DEVICE_ID) && 411 ((pciDevID & 0xFFF0) != BCM88800_DEVICE_ID) && 412 ((pciDevID & 0xFFFF) != BCM88470_DEVICE_ID) && 413 ((pciDevID & 0xFFFF) != BCM88270_DEVICE_ID) && 414 ((pciDevID & 0xFFFF) != BCM8206_DEVICE_ID) && 415 ((pciDevID & 0xFFF0) != BCM88750_DEVICE_ID) && 416 ((pciDevID & 0xFFF0) != BCM88950_DEVICE_ID) && 417 ((pciDevID & 0xFFF0) != BCM88790_DEVICE_ID) && 418 ((pciDevID & 0xFFF0) != BCM88660_DEVICE_ID) && 419 ((pciDevID & 0xFFF2) != BCM88202_DEVICE_ID) && 420 ((pciDevID & 0xFF00) != BCM53400_DEVICE_ID) && 421 ((pciDevID & 0xFFF0) != BCM53570_DEVICE_ID) && 422 ((pciDevID & 0xFFF0) != BCM53540_DEVICE_ID)) 423 { 424 return 0; 425 } 426 } 427 428 429 /* Pay dirt */ 430 devno = _n_devices++; 431 vxd = _devices + devno; 432 433 vxd->bde_dev.device = pciDevID; 434 vxd->bde_dev.rev = pciRevID; 435 vxd->bde_dev.base_address = 0; /* Device not memory accessible */ 436 vxd->pci_dev = *dev; 437 438 /* Configure PCI 439 * On PLI, to speed things up, we set these PCI config location to... 440 * 441 * latency timer : 32'h0000_100c = 48<<8 442 * enable fast back-to-back: 32'h0000_1004 = 32'h0000_0356 443 */ 444 445 446 /* Write control word (turns on parity detect) */ 447 pci_config_putw(dev, PCI_CONF_COMMAND, (PCI_CONF_COMMAND_BM | 448 PCI_CONF_COMMAND_MS | 449 PCI_CONF_COMMAND_PERR | 450 PCI_CONF_COMMAND_FBBE)); 451 /* Write base address */ 452 pci_config_putw(dev, PCI_CONF_BAR0, PLI_PCI_MBAR0); 453 454 /* read back */ 455 if((tmp = pci_config_getw(dev, PCI_CONF_BAR0) & PCI_CONF_BAR_MASK) != 456 PLI_PCI_MBAR0) { 457 cli_out("pli-bde: warning: read back of MBAR0 failed.\n"); 458 cli_out("pli-bde: warning: expected 0x%.8x, read 0x%.8x\n", 459 PLI_PCI_MBAR0, tmp); 460 } 461 462 /* Write something to int line */ 463 tmp = pci_config_getw(dev, PCI_CONF_INTERRUPT_LINE); 464 tmp = (tmp & ~0xff) | PLI_PCI_ILINE(devno); 465 pci_config_putw(dev, PCI_CONF_INTERRUPT_LINE, tmp); 466 467 /* Set latency timer to 48 */ 468 tmp = pci_config_getw(dev, PCI_CONF_CACHE_LINE_SIZE); 469 tmp |= (48 << 8); 470 pci_config_putw(dev, PCI_CONF_CACHE_LINE_SIZE, tmp); 471 472 switch (pciDevID) { 473 case BCM56340_DEVICE_ID: 474 case BCM56150_DEVICE_ID: 475 case BCM56450_DEVICE_ID: 476 case BCM56560_DEVICE_ID: 477 case BCM56670_DEVICE_ID: 478 case BCM56671_DEVICE_ID: 479 case BCM56672_DEVICE_ID: 480 case BCM56675_DEVICE_ID: 481 /* Ensure we work with BCMSIM */ 482 vxd->cmic_base = 0x48000000; 483 break; 484 default: 485 vxd->cmic_base = pci_config_getw(dev, PCI_CONF_BAR1) & PCI_CONF_BAR_MASK; 486 break; 487 } 488 cli_out("pli-bde: cmic_base = 0x%08x\n", vxd->cmic_base); 489 490 /* Have at it */ 491 return 0; 492 } 493 494 495 int 496 plibde_create(ibde_t** bde) 497 { 498 if(_n_devices == 0) { 499 pci_device_iter(_setup); 500 } 501 *bde = &_ibde; 502 return 0; 503 } 504 505 506 /* 507 * Perform a complete SCHANNEL operation. 508 * This is a backdoor into the simulator to 509 * improve performance. 510 */ 511 512 int 513 plibde_schan_op(int unit, 514 uint32* msg, 515 int dwc_write, int dwc_read) 516 { 517 /* in pli.c */ 518 extern int pli_schan(int devNo, uint32* words, int dw_write, int dw_read); 519 return pli_schan(unit, msg, dwc_write, dwc_read); 520 } 521 522 #define CMODEL_DEFAULT_DEVID 0x8470 523 #define CMODEL_DEVID_MAX_LENGTH 8 524 #define CMODEL_DEFAULT_REVID 0x1 525 #define CMODEL_REVID_MAX_LENGTH 8 526 extern char *getenv(const char*); 527 528 int 529 plibde_cmodel_create(ibde_t** bde) 530 { 531 char *dev_id_string, *rev_id_string; 532 /* Use +2 to leave space for the '0x' addition */ 533 char dev_id_hex_string[CMODEL_DEVID_MAX_LENGTH+2]; 534 char rev_id_hex_string[CMODEL_REVID_MAX_LENGTH+2]; 535 unsigned int dev_id = CMODEL_DEFAULT_DEVID; 536 unsigned int rev_id = CMODEL_DEFAULT_REVID; 537 538 _n_devices = 1; 539 540 dev_id_string = getenv("CMODEL_DEVID"); 541 rev_id_string = getenv("CMODEL_REVID"); 542 543 if (dev_id_string) 544 { 545 dev_id_hex_string[0]='0'; 546 dev_id_hex_string[1]='x'; 547 sal_memcpy(&(dev_id_hex_string[2]), dev_id_string, CMODEL_DEVID_MAX_LENGTH); 548 sscanf(dev_id_hex_string, "%x", &dev_id); 549 } 550 551 if (rev_id_string) 552 { 553 sal_memcpy(rev_id_hex_string, rev_id_string, CMODEL_REVID_MAX_LENGTH); 554 sscanf(rev_id_hex_string, "%x", &rev_id); 555 } 556 557 558 _devices[0].bde_dev.device = dev_id; 559 _devices[0].bde_dev.rev = rev_id; 560 561 *bde = &_cmodel_bde; 562 return 0; 563 } 564 565 #ifdef SINGLE_MODE 566 /********************************************************** 567 ********** SINGLE MODE FUNCTIONS 568 */ 569 570 static uint32 571 _local_pci_read(int d, uint32 addr) 572 { 573 return local_config_getw(&_devices[d].pci_dev, PLI_PCI_MBAR0 + _devices[d].cmic_base + addr); 574 } 575 576 static int 577 _local_pci_write(int d, uint32 addr, uint32 data) 578 { 579 return local_config_putw(&_devices[d].pci_dev, PLI_PCI_MBAR0 + _devices[d].cmic_base + addr, data); 580 } 581 582 static uint32 583 _local_read(int d, uint32 addr) 584 { 585 return local_memory_getw(&_devices[d].pci_dev, PLI_PCI_MBAR0 + _devices[d].cmic_base + addr); 586 } 587 588 static int 589 _local_write(int d, uint32 addr, uint32 data) 590 { 591 return local_memory_putw(&_devices[d].pci_dev, PLI_PCI_MBAR0 + _devices[d].cmic_base + addr, data); 592 } 593 594 static uint32 595 _local_iproc_read(int d, uint32 addr) 596 { 597 return local_memory_getw(&_devices[d].pci_dev, PLI_PCI_MBAR0 + addr); 598 } 599 600 static int 601 _local_iproc_write(int d, uint32 addr, uint32 data) 602 { 603 return local_memory_putw(&_devices[d].pci_dev, PLI_PCI_MBAR0 + addr, data); 604 } 605 606 static int 607 _local_interrupt_connect(int d, void (*isr)(void*), void* data) 608 { 609 return local_int_connect(PLI_PCI_ILINE(d), isr, data); 610 } 611 612 static ibde_t _local_ibde = { 613 _name, 614 _num_devices, 615 _get_dev, 616 _get_dev_type, 617 _local_pci_read, 618 _local_pci_write, 619 _pci_bus_features, 620 _local_read, 621 _local_write, 622 _salloc, 623 _sfree, 624 _sflush, 625 _sinval, 626 _local_interrupt_connect, 627 _interrupt_disconnect, 628 _l2p, 629 _p2l, 630 NULL, /* spi_read */ 631 NULL, /* spi_write */ 632 _local_iproc_read, 633 _local_iproc_write, 634 }; 635 636 int 637 plibde_local_create(ibde_t** bde) 638 { 639 char *chip_name; 640 uint16 dev_id; 641 uint8 rev_id; 642 643 _n_devices = 1; 644 645 chip_name = getenv("USE_LOCAL_SIM"); 646 _local_setup(&pcid_info, chip_name, &dev_id, &rev_id); 647 648 _devices[0].bde_dev.device = dev_id; 649 _devices[0].bde_dev.rev = rev_id; 650 651 *bde = &_local_ibde; 652 return 0; 653 } 654 #else 655 /* This is decleration of a dummy function that needed in case that SINGLE_MODE is not defined*/ 656 extern void single_mode_dummy_function(void); 657 #endif /* !SINGLE_MODE */