linux-user-bde.c (61415B)
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 * Linux User BDE User Library 8 */ 9 #include <sched.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <assert.h> 14 #include <sched.h> 15 16 #include <fcntl.h> 17 #include <unistd.h> 18 #include <sys/mman.h> 19 #include <sys/ioctl.h> 20 #include <endian.h> 21 22 #include <sal/core/sync.h> 23 #include <sal/core/spl.h> 24 #include <sal/core/thread.h> 25 #include <sal/core/time.h> 26 #include <sal/core/alloc.h> 27 #include <soc/cmic.h> 28 #include <soc/devids.h> 29 #include <soc/drv.h> 30 #ifdef INCLUDE_CPU_I2C 31 #include <soc/i2c.h> 32 #endif 33 34 #ifdef LINUX_PLI_COMBO_BDE 35 /* Avoid name clash when using two BDEs */ 36 #define intr_int_context linux_intr_int_context 37 38 /* Must match name change in src/sal/core/unix/alloc.c */ 39 extern void * sal_sim_dma_alloc(size_t sz, char *s); 40 extern void sal_sim_dma_free(void *addr); 41 /* Get sim_path defined in systems/linux/user/common/socdiag.c */ 42 extern int bcm_sim_path_get(void); 43 #endif 44 45 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) 46 47 #ifdef __DUNE_LINUX_BCM_CPU_PCIE__ 48 #include <soc/dpp/SAND/Utils/sand_framework.h> 49 #else /* !__DUNE_LINUX_BCM_CPU_PCIE__ */ 50 #include <soc/i2c.h> 51 #if defined(BCM_DFE_SUPPORT) 52 #include <appl/diag/dfe/utils_fe1600_card.h> 53 #endif 54 #if (defined(__DUNE_GTO_BCM_CPU__) || defined(__DUNE_WRX_BCM_CPU__)) && defined(INCLUDE_I2C) 55 #define DUNE_GTO_I2C 56 #define GFA_BI_I2C_PCP_DEVICE_ADDR 0x40 57 #endif 58 #endif /* __DUNE_LINUX_BCM_CPU_PCIE__ */ 59 60 #endif /* defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) */ 61 62 #include <mpool.h> 63 #include <linux-bde.h> 64 65 #include "kernel/linux-user-bde.h" 66 67 #include <linux/version.h> 68 69 #ifdef KEYSTONE 70 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) 71 #include <linux/types.h> 72 #include <linux/spi/spidev.h> 73 74 #include <sal/core/libc.h> 75 #include <sal/appl/config.h> 76 77 #define LINUX_SPIDEV_SUPPORT 1 78 #else 79 #define LINUX_SPIDEV_SUPPORT 0 80 #endif 81 #else /* !KEYSTONE */ 82 83 #define LINUX_SPIDEV_SUPPORT 0 84 85 #endif /* KEYSTONE */ 86 87 #if defined(BCM_ESW_SUPPORT) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) 88 #define CMIC_SPI_SUPPORT 1 89 #endif 90 #ifndef CMIC_SPI_SUPPORT 91 #define CMIC_SPI_SUPPORT 0 92 #endif 93 94 #if CMIC_SPI_SUPPORT 95 #include <linux/spi/spidev.h> 96 97 /* 98 * The path to the spidev driver device file 99 */ 100 #define LINUX_USER_CMIC_SPIDEV_NAME "/dev/spidev0.0" 101 102 /* Data array to record Read/Wirte device through the Linux mdio device driver or not */ 103 static int cmic_spidev_linux[LINUX_BDE_MAX_SWITCH_DEVICES]; 104 105 /* 106 * Actual spi devices in our system 107 */ 108 static struct { 109 int unit; 110 int spidev_fd; /* CPU MDIO device descriptor */ 111 } _sys_cmic_spidevs[LINUX_BDE_MAX_SWITCH_DEVICES]; 112 113 static int cmic_spidev_log_on = 0; 114 115 #define CMIC_SPI_NORMAL 0 116 #define CMIC_SPI_FAST 1 117 #define CMIC_SPI_READ 0 118 #define CMIC_SPI_WRITE 1 119 #define CMIC_SPI_NORMAL_BITS_7_5 0x3 120 121 static unsigned int 122 _cmic_spidev_read(int dev, uint32 addr) 123 { 124 int i; 125 int ret; 126 int fd = _sys_cmic_spidevs[dev].spidev_fd; 127 unsigned int value; 128 uint8 tx[5]; 129 uint8 rx[4]; 130 struct spi_ioc_transfer tr[2]; 131 132 memset(&rx, 0, sizeof(rx)); 133 134 tx[0] = (CMIC_SPI_NORMAL_BITS_7_5 << 5) | (CMIC_SPI_NORMAL << 4) | \ 135 ((dev & 0x7) << 1) | CMIC_SPI_READ; 136 tx[1] = addr & 0x000000ff; 137 tx[2] = (addr & 0x0000ff00) >> 8; 138 tx[3] = (addr & 0x00ff0000) >> 16; 139 tx[4] = (addr & 0xff000000) >> 24; 140 141 memset(tr, 0, sizeof(tr)); 142 tr[0].tx_buf = (unsigned long)tx; 143 tr[0].len = sizeof(tx); 144 145 tr[1].rx_buf = (unsigned long)rx; 146 tr[1].len = sizeof(rx); 147 148 ret = ioctl(fd, SPI_IOC_MESSAGE(2), &tr); 149 if (ret < 1) { 150 printf("Can't send spi message: read(ret=%d)\n", ret); 151 } 152 153 value = 0; 154 for (i = 0; i < sizeof(rx); i++) { 155 value |= (rx[i] << i*8); 156 } 157 158 return value; 159 } 160 161 static int 162 _cmic_spidev_write(int dev, uint32 addr, uint32 data) 163 { 164 int ret; 165 int fd = _sys_cmic_spidevs[dev].spidev_fd; 166 uint8 tx1[9]; 167 struct spi_ioc_transfer tr[1]; 168 169 memset(tx1, 0, sizeof(tx1)); 170 171 tx1[0] = (CMIC_SPI_NORMAL_BITS_7_5 << 5) | (CMIC_SPI_NORMAL << 4) | \ 172 ((dev & 0x7) << 1) | CMIC_SPI_WRITE; 173 tx1[1] = addr & 0x000000ff; 174 tx1[2] = (addr & 0x0000ff00) >> 8; 175 tx1[3] = (addr & 0x00ff0000) >> 16; 176 tx1[4] = (addr & 0xff000000) >> 24; 177 178 tx1[5] = data & 0x000000ff; 179 tx1[6] = (data & 0x0000ff00) >> 8; 180 tx1[7] = (data & 0x00ff0000) >> 16; 181 tx1[8] = (data & 0xff000000) >> 24; 182 183 memset(&tr, 0, sizeof(tr)); 184 tr[0].tx_buf = (unsigned long)tx1; 185 tr[0].len = sizeof(tx1); 186 187 ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); 188 if (ret < 1) { 189 printf("Can't send spi message: write(ret=%d)\n", ret); 190 } 191 192 return ret; 193 } 194 195 /* 196 * Function: 197 * _sys_cmic_spidev_deinit 198 * Purpose: 199 * close linux spi dev driver device file 200 * Parameters: 201 * dev - device number 202 * Returns: 203 * void 204 */ 205 static void 206 linux_cmic_spidev_close(int dev) 207 { 208 int fd; 209 210 fd = _sys_cmic_spidevs[dev].spidev_fd; 211 close(fd); 212 } 213 214 static int 215 linux_cmic_spidev_open(int dev) 216 { 217 char *spidev_name = LINUX_USER_CMIC_SPIDEV_NAME; 218 int fd = 0; 219 220 221 /* Initialization */ 222 memset(cmic_spidev_linux, 0, sizeof(cmic_spidev_linux)); 223 224 fd = open(spidev_name, O_RDWR); 225 if (fd >= 0) { 226 _sys_cmic_spidevs[dev].unit = dev; 227 _sys_cmic_spidevs[dev].spidev_fd = fd; 228 cmic_spidev_linux[dev] = 1; 229 } 230 231 cmic_spidev_log_on = 1; 232 233 return 0; 234 235 } 236 #endif 237 238 #ifdef IPROC_CMICD 239 #include <soc/cmic.h> 240 #define LINUX_MDIODEV_SUPPORT 1 241 242 /* IOCTL commands */ 243 #define MDIO_IOC_MAGIC 'm' 244 struct mdio_ioc_transfer { 245 uint8 pa; /* phy address */ 246 uint8 ra; /* register address */ 247 uint16 tx_buf; /* buffer for write */ 248 uint16 rx_buf; /* buffer for read */ 249 }; 250 251 #define MDIO_MSGSIZE(N) \ 252 ((((N)*(sizeof (struct mdio_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ 253 ? ((N)*(sizeof (struct mdio_ioc_transfer))) : 0) 254 255 #define MDIO_IOC_MESSAGE(N) _IOW(MDIO_IOC_MAGIC, 0, char[MDIO_MSGSIZE(N)]) 256 257 #define MDIO_IOC_EXTERNAL_R_REG _IOWR(MDIO_IOC_MAGIC, 0, char[MDIO_MSGSIZE(1)]) 258 #define MDIO_IOC_EXTERNAL_W_REG _IOW(MDIO_IOC_MAGIC, 1, char[MDIO_MSGSIZE(1)]) 259 #define MDIO_IOC_LOCAL_R_REG _IOWR(MDIO_IOC_MAGIC, 2, char[MDIO_MSGSIZE(1)]) 260 #define MDIO_IOC_LOCAL_W_REG _IOW(MDIO_IOC_MAGIC, 3, char[MDIO_MSGSIZE(1)]) 261 262 #else 263 #define LINUX_MDIODEV_SUPPORT 0 264 #endif /* IPROC_CMICD */ 265 266 #ifdef SAL_BDE_32BIT_USER_64BIT_KERNEL 267 268 typedef struct sal_kernel64_ptr_s { 269 uint64 ptr64; 270 } *sal_kernel64_ptr_t; 271 272 #define SAL_SEM_REDIRECT 273 274 #ifndef PHYS_ADDRS_ARE_64BITS 275 #define PHYS_ADDRS_ARE_64BITS 276 #endif 277 #include <sys/mman.h> 278 #define MMAP mmap 279 typedef uint64 phys_addr_t; 280 281 #else /* SAL_BDE_32BIT_USER_64BIT_KERNEL */ 282 283 #ifdef PHYS_ADDRS_ARE_64BITS 284 #include <sys/mman.h> 285 #ifdef SAL_BDE_USE_MMAP64 286 #define MMAP mmap64 287 #else 288 #define MMAP mmap 289 #endif 290 typedef uint64 phys_addr_t; 291 #else 292 #define MMAP mmap 293 typedef uint32 phys_addr_t; 294 #endif /* PHYS_ADDRS_ARE_64BITS */ 295 296 #endif /* SAL_BDE_32BIT_USER_64BIT_KERNEL */ 297 298 #define _SWAP32(_x) \ 299 (((_x) << 24) | (((_x) & 0xff00) << 8) | \ 300 (((_x) & 0xff0000) >> 8) | ((_x) >> 24)) 301 302 /* 303 * The path to the driver device file 304 */ 305 #define LUBDE_DEVICE_NAME "/dev/" LINUX_USER_BDE_NAME 306 307 /* 308 * The path to the mem device file 309 */ 310 #define MEM_DEVICE_NAME "/dev/mem" 311 #define LKBDE_DEVICE_NAME "/dev/"LINUX_KERNEL_BDE_NAME 312 313 /* 314 * Device information structure 315 */ 316 typedef struct bde_dev_s { 317 int dev_id; /* HW (probed in kernel BDE) device id*/ 318 uint32 dev_type; /* Type of underlaying device */ 319 ibde_dev_t bde_dev; /* BDE device description */ 320 phys_addr_t pbase; /* Physical base address of the device */ 321 uint32 *vbase; /* Virtual base address of the device */ 322 uint32 *vbase1; /* Secondary virtual base address #1 */ 323 uint32 *vbase2; /* Secondary virtual base address #2 */ 324 #ifdef DUNE_GTO_I2C 325 int i2c_addr; /* I2C base address */ 326 CPU_I2C_BUS_LEN i2c_access_type; 327 #endif /*DUNE_GTO_I2C*/ 328 #ifdef INCLUDE_CPU_I2C 329 uint8 i2c_bus; /* The number of the CPU I2C bus the device is connected to */ 330 uint8 i2c_dev; /* the device slave address on the I2C bus */ 331 uint8 use_i2c_access; /* Use I2C access for the device instead of PCIe */ 332 uint32 i2c_base; /* Base address for the device's internal address space */ 333 #endif 334 } bde_dev_t; 335 336 static bde_dev_t* _devices[LINUX_BDE_MAX_DEVICES]; 337 static int _ndevices = 0; 338 static int _switch_ndevices = 0; 339 static int _ether_ndevices = 0; 340 static int _cpu_ndevices = 0; 341 static int _bde_version = -1; 342 343 /* 344 * instance information 345 */ 346 static unsigned int _inst_dev_mask = 0; 347 static unsigned int _inst_dma_size = 0; 348 349 /* 350 * Global DMA pool. 351 * 352 * One DMA memory pool is shared by all devices. 353 */ 354 static void *_dma_vbase = NULL; 355 /* cpu physical address for mmap */ 356 static phys_addr_t _cpu_pbase = 0; 357 /* 358 * DMA bus address, it is either identical to cpu physical address 359 * or another address(IOVA) translated by IOMMU. 360 */ 361 static phys_addr_t _dma_pbase = 0; 362 static ssize_t _dma_size = 0; 363 static mpool_handle_t _dma_pool; 364 365 /* 366 * Device File Descriptors 367 */ 368 static int _devfd = -1; 369 static int _memfd = -1; 370 static int _kdevfd = -1; 371 static int _use_kernel_bde_mmap = 0; 372 373 #ifndef BCM_PLX9656_LOCAL_BUS 374 #ifdef SAL_BDE_CACHE_DMA_MEM 375 /* 376 * Optionally use cached memory for DMA to improve performance. 377 * Should be enabled on cache-coherent platforms only to avoid 378 * data corruption and other fatal errors. 379 */ 380 static int _sync_flags = 0; 381 #else 382 static int _sync_flags = O_SYNC | O_DSYNC | O_RSYNC; 383 #endif /* SAL_BDE_CACHE_DMA_MEM */ 384 #endif /* BCM_PLX9656_LOCAL_BUS */ 385 386 #if LINUX_SPIDEV_SUPPORT 387 #endif /* LINUX_SPIDEV_SUPPORT */ 388 389 #if LINUX_MDIODEV_SUPPORT 390 #endif /* LINUX_MDIODEV_SUPPORT */ 391 392 #define IPROC_SUBWIN_MAX 8 393 #define IPROC_DEFAULT_SUBWIN 7 394 #define IPROC_PAXB_PAGE 0x18012000 395 #define IPROC_PAXB_IMAP0_ADDR (IPROC_PAXB_PAGE + 0xc00) 396 #define BAR0_PAXB_IMAP0_0 0x2c00 397 398 399 typedef struct _iproc_subwin_s { 400 uint32 addr_min; 401 uint32 addr_max; 402 } _iproc_subwin_t; 403 404 typedef struct _iproc_map_s { 405 _iproc_subwin_t subwin[IPROC_SUBWIN_MAX]; 406 } _iproc_map_t; 407 408 static _iproc_map_t iproc_map_default = { 409 { 410 { 0x18000000, 0x18000fff }, /* CCA */ 411 { 0x18030000, 0x18030fff }, /* CCB */ 412 { 0x18012000, 0x18012fff }, /* PAXB */ 413 { 0, 0 } 414 } 415 }; 416 417 static _iproc_map_t iproc_map[LINUX_BDE_MAX_DEVICES]; 418 419 sal_mutex_t iproc_map_lock; 420 421 static int 422 _devio_remap(unsigned int command, lubde_ioctl_t *pdevio) 423 { 424 int idx = 0; 425 426 if ((_inst_dev_mask == 0)||(_devices[0] == NULL)) { 427 return 0; 428 } 429 430 switch(command) { 431 case LUBDE_GET_DEVICE_STATE: 432 case LUBDE_GET_NUM_DEVICES : 433 case LUBDE_GET_DMA_INFO: 434 case LUBDE_ATTACH_INSTANCE: 435 case LUBDE_USLEEP: 436 case LUBDE_UDELAY: 437 case LUBDE_SEM_OP: 438 /* 439 * We don't need to do the remap for those devio.dev 440 * which is not used to identify the device id 441 */ 442 return 0; 443 } 444 445 idx = pdevio->dev; 446 pdevio->dev = _devices[idx]->dev_id; 447 448 return 0; 449 } 450 451 /* 452 * Function: _ioctl 453 * 454 * Purpose: 455 * Helper function for performing device ioctls 456 * Parameters: 457 * command - ioctl command code 458 * Returns: 459 * Asserts if ioctl() system call fails. 460 * Returns devio.rc value. 461 * Notes: 462 * You must program the devio structure with your parameters 463 * before calling this function. 464 */ 465 static int 466 _ioctl(unsigned int command, lubde_ioctl_t *pdevio) 467 { 468 pdevio->rc = -1; 469 _devio_remap(command, pdevio); 470 assert(ioctl(_devfd, command, pdevio) == 0); 471 return pdevio->rc; 472 } 473 474 /* 475 * Function: _mmap 476 * 477 * Purpose: 478 * Helper function for address mmapping. 479 * Parameters: 480 * p - physical address start 481 * size - size of region 482 * Returns: 483 * Pointer to mapped region, or NULL on failure. 484 */ 485 static void * 486 _mmap(phys_addr_t p, int size) 487 { 488 void *map; 489 phys_addr_t page_size, page_mask; 490 unsigned int offset; 491 phys_addr_t paddr; 492 sal_vaddr_t vmap; 493 int dev_fd = (_use_kernel_bde_mmap && /* device to use for mmap */ 494 (p < _cpu_pbase + _dma_size) && (p >= _cpu_pbase)) ? 495 _kdevfd : _memfd; 496 497 page_size = getpagesize(); 498 page_mask = ~(page_size - 1); 499 500 if (p & ~page_mask) { 501 /* 502 * If address (p) not aligned to page_size, we could not get the virtual 503 * address. So we make the paddr aligned with the page size. 504 * Get the _map by using the aligned paddr. 505 * Add the offset back to return the virtual mapped region of p. 506 */ 507 508 paddr = p & page_mask; 509 offset = p - paddr; 510 size += offset; 511 512 map = MMAP(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, dev_fd, paddr); 513 if ((map == MAP_FAILED) && (dev_fd == _kdevfd)) { 514 map = MMAP(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, _memfd, paddr); 515 } 516 if (map == MAP_FAILED) { 517 perror("aligned mmap failed: "); 518 map = NULL; 519 } 520 vmap = PTR_TO_UINTPTR(map) + offset; 521 return (void *)(vmap); 522 } 523 #ifdef SAL_BDE_USE_MMAP2 524 size += (p & ~page_mask); 525 map = (void *)syscall(4210, 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, (off_t)((p & page_mask) >> 12)); 526 if ((map == MAP_FAILED) && (dev_fd == _kdevfd)) { 527 map = (void *)syscall(4210, 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, _memfd, (off_t)((p & page_mask) >> 12)); 528 } 529 if (map == MAP_FAILED) { 530 perror("mmap2 failed: "); 531 map = NULL; 532 } else { 533 map = UINTPTR_TO_PTR(PTR_TO_UINTPTR(map) + PTR_TO_UINTPTR(p & ~page_mask)); 534 } 535 #else 536 map = MMAP(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, dev_fd, p); 537 if ((map == MAP_FAILED) && (dev_fd == _kdevfd)) { 538 map = MMAP(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, _memfd, p); 539 } 540 if (map == MAP_FAILED) { 541 perror("mmap failed: "); 542 map = NULL; 543 } 544 #endif 545 return map; 546 } 547 548 /* 549 * Function: _get_dma_info 550 * 551 * Purpose: 552 * Retrieve the size and base address of the DMA memory pool 553 * Parameters: 554 * cpu_pbase - (out) cpu physical address of the memory pool for mmap 555 * dma_pbase - (out) bus address of the memory pool 556 * size - (out) size of the memory pool 557 * Returns: 558 * 0 559 */ 560 static int 561 _get_dma_info(phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size) 562 { 563 lubde_ioctl_t devio; 564 565 /* Initialize the variable */ 566 memset(&devio, 0, sizeof(lubde_ioctl_t)); 567 568 devio.dev = _inst_dev_mask; 569 devio.d2 = 0; /* if we work with older kernel modules, this will make us behave properly */ 570 _ioctl(LUBDE_GET_DMA_INFO, &devio); 571 *dma_pbase = devio.d0; 572 *size = devio.d1; 573 _use_kernel_bde_mmap = devio.d2; 574 #ifdef PHYS_ADDRS_ARE_64BITS 575 *cpu_pbase = devio.dx.dw[1]; 576 *cpu_pbase <<= 32; 577 *cpu_pbase |= devio.dx.dw[0]; 578 #else 579 *cpu_pbase = devio.dx.dw[0]; 580 #endif 581 return 0; 582 } 583 584 static int 585 _bde_instance_attach(unsigned int dev_mask, unsigned int dma_size) 586 { 587 lubde_ioctl_t devio; 588 589 /* Initialize the variable */ 590 memset(&devio, 0, sizeof(lubde_ioctl_t)); 591 592 devio.d0 = dev_mask; 593 devio.d1 = dma_size; 594 595 _ioctl(LUBDE_ATTACH_INSTANCE, &devio); 596 597 return devio.rc; 598 599 } 600 601 /* 602 * Function: 603 * _get_dev_state 604 * Purpose: 605 * BDE get_dev_state function. Returns device state. 606 * (BDE_DEV_STATE_REMOVED/CHANGED) 607 * Parameters: 608 * d - device number 609 * Returns: 610 * state of underlaying device. 611 */ 612 static int 613 _get_dev_state(int d) 614 { 615 lubde_ioctl_t _devio; 616 617 /* Initialize the variable */ 618 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 619 620 assert(d >= 0 || d < _ndevices); 621 622 if (_bde_version > 0) { 623 /* LUBDE_GET_DEVICE_STATE support after BDE Version 1 */ 624 _devio.dev = d; 625 if (_ioctl(LUBDE_GET_DEVICE_STATE, &_devio) != 0) { 626 return -1; 627 } 628 return _devio.d0; 629 } 630 631 return -1; 632 } 633 634 /* 635 * Function: _open 636 * 637 * Purpose: 638 * Open device driver 639 * Initialize device structures 640 * Initialize DMA memory 641 * Parameters: 642 * None 643 * Returns: 644 * 0 on successfully initialization 645 * -1 on error. 646 */ 647 static int 648 _open(void) 649 { 650 lubde_ioctl_t devio; 651 phys_addr_t pbase; 652 int i, j, dev_no; 653 int linux24; 654 int procfd; 655 char procbuf[4]; 656 uint32 rval; 657 int num_devices; 658 int _dev_mask = 0; 659 #ifdef BCM_JERICHO_SUPPORT 660 int devknetfd = -1; 661 #endif 662 663 #ifndef NDEBUG 664 int _ioctl_LUBDE_GET_NUM_DEVICES; 665 int _ioctl_LUBDE_GET_DEVICE_TYPE; 666 int _ioctl_LUBDE_GET_DEVICE; 667 #endif /* !NDEBUG */ 668 669 if (_devfd >= 0) { 670 /* Already open */ 671 return 0; 672 } 673 674 /* Check Linux kernel version */ 675 linux24 = 0; 676 if ((procfd = open("/proc/sys/kernel/osrelease", O_RDONLY)) >= 0) { 677 if ((read(procfd, procbuf, sizeof(procbuf))) == 4) { 678 if (strncmp(procbuf, "2.4", 3) == 0) { 679 linux24 = 1; 680 } 681 } 682 close(procfd); 683 } 684 685 /* Open the device driver */ 686 if ((_devfd = open(LUBDE_DEVICE_NAME, 687 O_RDWR | O_SYNC | O_DSYNC | O_RSYNC)) < 0) { 688 /* Try inserting modules from the current directory */ 689 if (linux24) { 690 system("/sbin/insmod linux-kernel-bde.o"); 691 system("/sbin/insmod linux-user-bde.o"); 692 } else { 693 system("/sbin/insmod linux-kernel-bde.ko"); 694 system("/sbin/insmod linux-user-bde.ko"); 695 } 696 697 if ((_devfd = open(LUBDE_DEVICE_NAME, 698 O_RDWR | O_SYNC | O_DSYNC | O_RSYNC)) < 0) { 699 perror("open " LUBDE_DEVICE_NAME ": "); 700 return -1; 701 } 702 } 703 704 /* knet is only supported on jericho and qmx of DUNE */ 705 #ifdef BCM_JERICHO_SUPPORT 706 #ifdef INCLUDE_KNET 707 /* check if knet module exists */ 708 if ((devknetfd = open("/dev/linux-bcm-knet", O_RDONLY | O_NONBLOCK )) < 0) { 709 /* Try inserting knet module when KNET feature is enabled */ 710 if (linux24) { 711 /* no linux-bcm-knet.o */ 712 } else { 713 system("/sbin/insmod linux-bcm-knet.ko"); 714 } 715 } 716 #else 717 /* check if knet module exists */ 718 if ((devknetfd = open("/dev/linux-bcm-knet", O_RDONLY | O_NONBLOCK )) >= 0) { 719 close(devknetfd); 720 /* Try removing knet module when KNET feature is not eanbled*/ 721 if (linux24) { 722 /* no linux-bcm-knet.o */ 723 } else { 724 system("/sbin/rmmod linux_bcm_knet"); 725 } 726 } 727 #endif 728 #endif 729 730 if (_inst_dev_mask) { 731 if (_bde_instance_attach(_inst_dev_mask, _inst_dma_size) < 0) { 732 perror("fail to attach instance "); 733 close(_devfd); 734 return -1; 735 } 736 } 737 738 /* get dma pool information and its handling mode */ 739 _get_dma_info(&_cpu_pbase, &_dma_pbase, &_dma_size); 740 assert(_dma_size); 741 742 #ifndef BCM_PLX9656_LOCAL_BUS 743 if ((_memfd = open(MEM_DEVICE_NAME, O_RDWR | _sync_flags)) < 0) { 744 perror("open " MEM_DEVICE_NAME ": "); 745 close(_devfd); 746 return -1; 747 } 748 #else /* BCM_PLX9656_LOCAL_BUS */ 749 /* 750 * On 440GX board with 2.6 kernel, /dev/mem and mmap don't work well 751 * together. So we use /dev/linux-user-bde for mapping instead 752 * (see systems/linux/kernel/modules/shared/gmodule.c) -- hqian 8/15/07 753 */ 754 _memfd = _devfd; 755 #endif 756 if ( _use_kernel_bde_mmap && 757 (_kdevfd = open(LKBDE_DEVICE_NAME, O_RDWR | O_SYNC | O_DSYNC | O_RSYNC)) < 0) { 758 perror("open " LKBDE_DEVICE_NAME ": "); 759 close(_devfd); 760 #ifndef BCM_PLX9656_LOCAL_BUS 761 close(_memfd); 762 #endif 763 return -1; 764 } 765 766 /* Initialize the variable */ 767 memset(&devio, 0, sizeof(lubde_ioctl_t)); 768 769 /* Get BDE module version */ 770 if (_bde_version == -1) { 771 #ifndef NDEBUG 772 /* "assert" maps to NULL statement with NDEBUG */ 773 const int _ioctl_LUBDE_VERSION = 774 #endif /* !NDEBUG */ 775 _ioctl(LUBDE_VERSION, &devio); 776 assert(_ioctl_LUBDE_VERSION == 0); 777 _bde_version = devio.d0; 778 } 779 780 /* Get the availabled devices from the driver */ 781 memset(_devices, 0, sizeof(_devices)); 782 783 /* first, get all available devices */ 784 devio.dev = BDE_ALL_DEVICES; 785 #ifndef NDEBUG 786 _ioctl_LUBDE_GET_NUM_DEVICES = 787 #endif /* !NDEBUG */ 788 _ioctl(LUBDE_GET_NUM_DEVICES, &devio); 789 assert(_ioctl_LUBDE_GET_NUM_DEVICES == 0); 790 791 num_devices = devio.d0; 792 if (num_devices == 0) { 793 printf("linux-user-bde: no devices\n"); 794 } 795 _dev_mask = _inst_dev_mask; 796 if(_dev_mask == 0) { 797 /* Include all devices for non-instance mode */ 798 _dev_mask = ~0; 799 } 800 /* Initialize device structures for each device */ 801 for (dev_no = 0; dev_no < num_devices; dev_no++) { 802 uint32 dev_type; 803 uint32 dev_state; 804 805 dev_state = _get_dev_state(dev_no); 806 if (dev_state == BDE_DEV_STATE_REMOVED) { 807 printf("linux-user-bde: device was removed.\n"); 808 continue; 809 } else if (dev_state == -1){ 810 printf("linux-user-bde: hot-plug device state not supported " 811 "by kernel module.\n"); 812 } 813 814 if ((_dev_mask & (1 << dev_no)) == 0) { 815 continue; 816 } 817 /* i tracks devices belonging to this instance */ 818 i = _ndevices++; 819 820 _devices[i] = (bde_dev_t*)malloc(sizeof(bde_dev_t)); 821 memset(_devices[i], 0, sizeof(bde_dev_t)); 822 iproc_map[i] = iproc_map_default; 823 824 _devices[i]->dev_id = dev_no; 825 /* Get the type of device */ 826 devio.dev = i; 827 #ifndef NDEBUG 828 _ioctl_LUBDE_GET_DEVICE_TYPE= 829 #endif /* !NDEBUG */ 830 _ioctl(LUBDE_GET_DEVICE_TYPE, &devio); 831 assert(_ioctl_LUBDE_GET_DEVICE_TYPE == 0); 832 833 dev_type = devio.d0; 834 835 if (dev_type & BDE_SWITCH_DEV_TYPE) { 836 _switch_ndevices++; 837 } else if (dev_type & BDE_ETHER_DEV_TYPE){ 838 _ether_ndevices++; 839 } else if (dev_type & BDE_CPU_DEV_TYPE){ 840 _cpu_ndevices++; 841 } 842 843 /* Get the detail info of the device */ 844 devio.dev = i; 845 #ifndef NDEBUG 846 _ioctl_LUBDE_GET_DEVICE = 847 #endif /* !NDEBUG */ 848 _ioctl(LUBDE_GET_DEVICE, &devio); 849 assert(_ioctl_LUBDE_GET_DEVICE == 0); 850 851 _devices[i]->bde_dev.device = devio.d0; 852 _devices[i]->bde_dev.rev = devio.d1; 853 854 if (BDE_DEV_MEM_MAPPED(dev_type)) { 855 int size; 856 857 /* Default is 64K memory window */ 858 size = 64 * 1024; 859 if (dev_type & BDE_128K_REG_SPACE) { 860 size = 128 * 1024; 861 #if defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) 862 } else if (dev_type & BDE_8MB_REG_SPACE) { 863 size = 8 * 1024 * 1024; 864 #endif 865 } else if (dev_type & BDE_256K_REG_SPACE) { 866 size = 256 * 1024; 867 } else if (dev_type & BDE_320K_REG_SPACE) { 868 size = 320 * 1024; 869 } 870 871 /* Get physical devices address */ 872 #ifdef PHYS_ADDRS_ARE_64BITS 873 pbase = devio.d3; 874 pbase <<= 32; 875 pbase |= devio.d2; 876 #else 877 pbase = devio.d2; 878 #endif /* PHYS_ADDRS_ARE_64BITS */ 879 _devices[i]->pbase = pbase; 880 881 switch (_devices[i]->bde_dev.device) { 882 case GEDI_DEVICE_ID: 883 case ACP_PCI_DEVICE_ID: 884 size = 0x10000000; 885 dev_type |= BDE_BYTE_SWAP; 886 break; 887 default: 888 break; 889 } 890 { 891 _devices[i]->vbase = _mmap(pbase, size); 892 _devices[i]->bde_dev.base_address = (sal_vaddr_t)_devices[i]->vbase; 893 } 894 /* Check for additional device resources */ 895 devio.dev = i; 896 devio.d0 = 1; /* Resource number */ 897 if (_ioctl(LUBDE_DEV_RESOURCE, &devio) == 0) { 898 /* Get physical devices address */ 899 #ifdef PHYS_ADDRS_ARE_64BITS 900 pbase = devio.d3; 901 pbase <<= 32; 902 pbase |= devio.d2; 903 #else 904 pbase = devio.d2; 905 #endif /* PHYS_ADDRS_ARE_64BITS */ 906 #ifdef __DUNE_LINUX_BCM_CPU_PCIE__ 907 if (dev_type & BDE_256K_REG_SPACE) { 908 size = 0x8000; 909 } 910 #endif 911 iproc_map_lock = sal_mutex_create("iproc_map_mutex"); 912 if (iproc_map_lock == NULL) { 913 return -1; 914 } 915 916 if (pbase) { 917 _devices[i]->vbase1 = _mmap(pbase, size); 918 if (!(dev_type & BDE_NO_IPROC)) { 919 /* Cache IMAP0 registers from the current PAXB */ 920 for (j = 0; j < IPROC_SUBWIN_MAX; j++) { 921 rval = _devices[i]->vbase1[(BAR0_PAXB_IMAP0_0/sizeof(uint32))+j]; 922 if (rval & 1) { /* Valid Bit */ 923 iproc_map[i].subwin[j].addr_min = rval & ~(0xfff); 924 iproc_map[i].subwin[j].addr_max = rval | 0xfff; 925 } else { 926 iproc_map[i].subwin[j].addr_min = 0; 927 iproc_map[i].subwin[j].addr_max = 0; 928 } 929 } 930 if (iproc_map[i].subwin[2].addr_min & 0x1000) { 931 /* PAXB_1 */ 932 dev_type |= BDE_DEV_BUS_ALT; 933 } 934 } 935 } 936 } 937 } 938 _devices[i]->dev_type = dev_type; 939 940 #ifdef DUNE_GTO_I2C 941 _devices[i]->dev_type |= BDE_I2C_DEV_TYPE; 942 _devices[i]->dev_type &= ~BDE_PCI_DEV_TYPE; 943 switch (_devices[i]->bde_dev.device) { 944 case GEDI_DEVICE_ID: 945 _devices[i]->i2c_addr = GFA_BI_I2C_PCP_DEVICE_ADDR; 946 _devices[i]->i2c_access_type = CPU_I2C_ALEN_LONG_DLEN_LONG; 947 break; 948 949 case BCM88750_DEVICE_ID: 950 case BCM88753_DEVICE_ID: 951 case BCM88754_DEVICE_ID: 952 case BCM88755_DEVICE_ID: 953 #ifdef BCM_DFE_SUPPORT 954 case BCM88752_DEVICE_ID: 955 _devices[i]->i2c_addr = FE1600_CARD_I2C_FE1600_DEVICE_ADDR; 956 _devices[i]->i2c_access_type = CPU_I2C_ALEN_WORD_DLEN_LONG; 957 break; 958 #endif /* BCM_DFE_SUPPORT */ 959 case JERICHO_DEVICE_ID: 960 case BCM88670_DEVICE_ID: 961 case BCM88671_DEVICE_ID: 962 case BCM88671M_DEVICE_ID: 963 case BCM88672_DEVICE_ID: 964 case BCM88673_DEVICE_ID: 965 case BCM88674_DEVICE_ID: 966 case BCM88675M_DEVICE_ID: 967 case BCM88676_DEVICE_ID: 968 case BCM88676M_DEVICE_ID: 969 case BCM88677_DEVICE_ID: 970 case BCM88678_DEVICE_ID: 971 case BCM88679_DEVICE_ID: 972 case QMX_DEVICE_ID: 973 case BCM88370_DEVICE_ID: 974 case BCM88371_DEVICE_ID: 975 case BCM88371M_DEVICE_ID: 976 case BCM88376_DEVICE_ID: 977 case BCM88376M_DEVICE_ID: 978 case BCM88377_DEVICE_ID: 979 case BCM88378_DEVICE_ID: 980 case BCM88379_DEVICE_ID: 981 case BCM88680_DEVICE_ID: 982 case BCM88681_DEVICE_ID: 983 case BCM88682_DEVICE_ID: 984 case BCM88683_DEVICE_ID: 985 case BCM88684_DEVICE_ID: 986 case BCM88685_DEVICE_ID: 987 case BCM88380_DEVICE_ID: 988 case BCM88381_DEVICE_ID: 989 case BCM88800_DEVICE_ID: 990 case BCM88770_DEVICE_ID: 991 case BCM88773_DEVICE_ID: 992 case BCM88774_DEVICE_ID: 993 case BCM88775_DEVICE_ID: 994 case BCM88776_DEVICE_ID: 995 case BCM88777_DEVICE_ID: 996 case QAX_DEVICE_ID: 997 case BCM88470P_DEVICE_ID: 998 case BCM88471_DEVICE_ID: 999 case BCM88473_DEVICE_ID: 1000 case BCM88474_DEVICE_ID: 1001 case BCM88474H_DEVICE_ID: 1002 case BCM88476_DEVICE_ID: 1003 case BCM88477_DEVICE_ID: 1004 1005 case QUX_DEVICE_ID: 1006 case BCM88272_DEVICE_ID: 1007 case BCM88273_DEVICE_ID: 1008 case BCM88274_DEVICE_ID: 1009 case BCM88278_DEVICE_ID: 1010 case BCM88279_DEVICE_ID: 1011 case FLAIR_DEVICE_ID: 1012 case BCM88950_DEVICE_ID: 1013 case BCM88953_DEVICE_ID: 1014 case BCM88954_DEVICE_ID: 1015 case BCM88955_DEVICE_ID: 1016 case BCM88956_DEVICE_ID: 1017 case BCM88772_DEVICE_ID: 1018 case BCM88952_DEVICE_ID: 1019 _devices[i]->i2c_addr = 0x44; 1020 _devices[i]->i2c_access_type = CPU_I2C_ALEN_LONG_DLEN_LONG; 1021 break; 1022 default: 1023 break; 1024 } 1025 1026 /*All Jericho 2 devices from 0x8690 to 0x869F*/ 1027 if (SOC_IS_JERICHO_2_TYPE(_devices[i]->bde_dev.device)) { 1028 _devices[i]->i2c_addr = 0x44; 1029 _devices[i]->i2c_access_type = CPU_I2C_ALEN_LONG_DLEN_LONG; 1030 } 1031 1032 /*All Ramon devices from 0x8790 to 0x879F*/ 1033 if ((_devices[i]->bde_dev.device & BCM_DNXF_DEVID_MASK) == BCM88790_DEVICE_ID) { 1034 _devices[i]->i2c_addr = 0x44; 1035 _devices[i]->i2c_access_type = CPU_I2C_ALEN_LONG_DLEN_LONG; 1036 } 1037 #endif 1038 #ifdef INCLUDE_CPU_I2C 1039 /* Configure the device's I2C access information */ 1040 switch (_devices[i]->bde_dev.device & BCM_DNXF_DEVID_MASK) { 1041 case BCM88690_DEVICE_ID: 1042 case BCM88790_DEVICE_ID: 1043 _devices[i]->i2c_bus = cpu_i2c_bus_num_default; /* The number of the CPU I2C bus the device is connected to on Broadcom CPU cards */ 1044 _devices[i]->i2c_dev = 0x44; /* the device slave address on most Broadcom demo boards */ 1045 _devices[i]->use_i2c_access = 0; 1046 break; 1047 default: 1048 _devices[i]->i2c_bus = -1; 1049 _devices[i]->i2c_dev = -1; 1050 _devices[i]->use_i2c_access = 0; 1051 } 1052 #endif /* INCLUDE_CPU_I2C */ 1053 } 1054 /* Initialize DMA memory pool */ 1055 mpool_init(); 1056 assert(_dma_vbase = _mmap(_cpu_pbase, _dma_size)); 1057 printf("DMA pool size: %d\n", (int)_dma_size); 1058 assert(_dma_pool = mpool_create(_dma_vbase, _dma_size)); 1059 1060 /* calibrate */ 1061 sal_udelay(0); 1062 1063 return 0; 1064 } 1065 1066 /* 1067 * Function: _close 1068 * 1069 * Purpose: 1070 * close the driver 1071 * Parameters: 1072 * None 1073 * Returns: 1074 * 0 1075 */ 1076 static int 1077 _close(void) 1078 { 1079 if (_memfd >= 0 && _memfd != _devfd) { 1080 close(_memfd); 1081 } 1082 close(_devfd); 1083 if (_kdevfd >=0) { 1084 close(_kdevfd); 1085 } 1086 _kdevfd = _memfd = _devfd = -1; 1087 return 0; 1088 } 1089 1090 /* 1091 * Function: _enable_interrupts 1092 * 1093 * Purpose: 1094 * Enable interrupts on all devices in the driver 1095 * Parameters: 1096 * d - 0 the switching devices 1097 * others the ether device id of _devices. 1098 * Returns: 1099 * 0 1100 * Notes: 1101 * When a real device interrupt occurs, the driver masks all 1102 * interrupts and wakes up the interrupt thread. 1103 * It is assumed that the interrupt handler will unmask 1104 * interrupts upon exit. 1105 */ 1106 static int 1107 _enable_interrupts(int d) 1108 { 1109 lubde_ioctl_t devio; 1110 #ifndef NDEBUG 1111 /* "assert" maps to NULL statement with NDEBUG */ 1112 int _ioctl_irrupt_status; 1113 #endif /* !NDEBUG */ 1114 1115 /* Initialize the variable */ 1116 memset(&devio, 0, sizeof(lubde_ioctl_t)); 1117 1118 if (_switch_ndevices > 0 || _devices[d]->dev_type & BDE_ETHER_DEV_TYPE) { 1119 devio.dev = d; 1120 #ifndef NDEBUG 1121 _ioctl_irrupt_status = 1122 #endif 1123 _ioctl(LUBDE_ENABLE_INTERRUPTS, &devio); 1124 assert(_ioctl_irrupt_status == 0); 1125 } 1126 return 0; 1127 } 1128 1129 /* 1130 * Function: _disable_interrupts 1131 * 1132 * Purpose: 1133 * Disable interrupts on all devices in the driver 1134 * Parameters: 1135 * d - 0 the switching devices 1136 * others the ether device id of _devices. 1137 * Returns: 1138 * 0 1139 */ 1140 static int 1141 _disable_interrupts(int d) 1142 { 1143 lubde_ioctl_t devio; 1144 #ifndef NDEBUG 1145 /* "assert" maps to NULL statement with NDEBUG */ 1146 int _ioctl_irrupt_status; 1147 #endif /* !NDEBUG */ 1148 1149 /* Initialize the variable */ 1150 memset(&devio, 0, sizeof(lubde_ioctl_t)); 1151 1152 if (_switch_ndevices > 0 || _devices[d]->dev_type & BDE_ETHER_DEV_TYPE) { 1153 devio.dev = d; 1154 #ifndef NDEBUG 1155 _ioctl_irrupt_status = 1156 #endif 1157 _ioctl(LUBDE_DISABLE_INTERRUPTS, &devio); 1158 assert(_ioctl_irrupt_status == 0); 1159 } 1160 return 0; 1161 } 1162 1163 /* 1164 * Function: _pci_config_put32 1165 * 1166 * Purpose: 1167 * Write a PCI configuration register on the device 1168 * Parameters: 1169 * d - device number 1170 * offset - register offset 1171 * data - register data 1172 * Returns: 1173 * 0 1174 */ 1175 int 1176 _pci_config_put32(int d, unsigned int offset, unsigned int data) 1177 { 1178 lubde_ioctl_t devio; 1179 1180 /* Initialize the variable */ 1181 memset(&devio, 0, sizeof(lubde_ioctl_t)); 1182 1183 devio.dev = d; 1184 devio.d0 = offset; 1185 devio.d1 = data; 1186 _ioctl(LUBDE_PCI_CONFIG_PUT32, &devio); 1187 return 0; 1188 } 1189 1190 /* 1191 * Function: _pci_config_get32 1192 * 1193 * Purpose: 1194 * Read a PCI configuration register on the device 1195 * Parameters: 1196 * d - device number 1197 * offset - register offset 1198 * Returns: 1199 * register value 1200 */ 1201 unsigned int 1202 _pci_config_get32(int d, unsigned int offset) 1203 { 1204 lubde_ioctl_t devio; 1205 1206 /* Initialize the variable */ 1207 memset(&devio, 0, sizeof(lubde_ioctl_t)); 1208 1209 devio.dev = d; 1210 devio.d0 = offset; 1211 _ioctl(LUBDE_PCI_CONFIG_GET32, &devio); 1212 return devio.d0; 1213 } 1214 1215 /* 1216 * Function: _read 1217 * 1218 * Purpose: 1219 * Read a register 1220 * Parameters: 1221 * d - device number 1222 * addr - register address 1223 * Returns: 1224 * register value 1225 */ 1226 static unsigned int 1227 _read(int d, unsigned int addr) 1228 { 1229 lubde_ioctl_t _devio; 1230 unsigned int rv = 0; 1231 1232 /* Initialize the variable */ 1233 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 1234 1235 #if CMIC_SPI_SUPPORT 1236 if (_devices[d]->dev_type & BDE_SPI_DEV_TYPE) { 1237 return _cmic_spidev_read(d, addr); 1238 } 1239 #endif 1240 1241 if (_devices[d]->dev_type & BDE_DEV_BUS_RD_16BIT) { 1242 _devio.dev = d; 1243 _devio.d0 = addr; 1244 if (_ioctl(LUBDE_READ_REG_16BIT_BUS, &_devio) != 0) { 1245 printf("linux-user-bde: warning: " 1246 "eb_read from kernel failed unit=%d addr=%x", 1247 d, addr); 1248 return -1; 1249 } 1250 return _devio.d1; 1251 } 1252 1253 if (_devices[d]->dev_type & BDE_I2C_DEV_TYPE) { 1254 #ifdef DUNE_GTO_I2C 1255 int data = 0; 1256 assert(_devices[d]->i2c_addr); 1257 if (cpu_i2c_read(_devices[d]->i2c_addr, addr, 1258 _devices[d]->i2c_access_type, &data) != 0) { 1259 printf("linux-user-bde: warning: " 1260 "cpu_i2c_read failed unit=%d addr=0x%x ," 1261 "i2c_addr=0x%x , i2c_access_type=0x%x .\n", 1262 d, addr, _devices[d]->i2c_addr , _devices[d]->i2c_access_type); 1263 return -1; 1264 } 1265 return data; 1266 #endif 1267 } 1268 1269 assert(_devices[d]->vbase); 1270 rv = _devices[d]->vbase[addr/sizeof(uint32)]; 1271 if (_devices[d]->dev_type & BDE_BYTE_SWAP) { 1272 rv = _SWAP32(rv); 1273 } 1274 1275 return rv; 1276 } 1277 1278 /* 1279 * Function: _write 1280 * 1281 * Purpose: 1282 * Write a register 1283 * Parameters: 1284 * d - device number 1285 * addr - register address 1286 * data - register data 1287 * Returns: 1288 * 0 1289 */ 1290 static int 1291 _write(int d, uint32 addr, uint32 data) 1292 { 1293 lubde_ioctl_t _devio; 1294 1295 /* Initialize the variable */ 1296 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 1297 1298 #if CMIC_SPI_SUPPORT 1299 if (_devices[d]->dev_type & BDE_SPI_DEV_TYPE) { 1300 return _cmic_spidev_write(d, addr, data); 1301 } 1302 #endif 1303 1304 if (_devices[d]->dev_type & BDE_DEV_BUS_WR_16BIT) { 1305 _devio.dev = d; 1306 _devio.d0 = addr; 1307 _devio.d1 = data; 1308 if (_ioctl(LUBDE_WRITE_REG_16BIT_BUS, &_devio) != 0) { 1309 printf("linux-user-bde: warnning: " 1310 "eb_write failed unit=%d addr=%x", 1311 d, addr); 1312 return -1; 1313 } 1314 return 0; 1315 } 1316 1317 if (_devices[d]->dev_type & BDE_I2C_DEV_TYPE) { 1318 #ifdef DUNE_GTO_I2C 1319 assert(_devices[d]->i2c_addr); 1320 if (cpu_i2c_write(_devices[d]->i2c_addr, addr, 1321 _devices[d]->i2c_access_type, data) != 0) { 1322 printf("linux-user-bde: warning: " 1323 "cpu_i2c_write failed unit=%d addr=0x%x ," 1324 "i2c_addr=0x%x , i2c_access_type=0x%x .\n", 1325 d, addr , _devices[d]->i2c_addr , _devices[d]->i2c_access_type); 1326 return -1; 1327 } 1328 return 0; 1329 #endif 1330 } 1331 1332 assert(_devices[d]->vbase); 1333 if (_devices[d]->dev_type & BDE_BYTE_SWAP) { 1334 data = _SWAP32(data); 1335 } 1336 _devices[d]->vbase[addr/sizeof(uint32)] = data; 1337 1338 return 0; 1339 } 1340 1341 /* 1342 * Function: _salloc 1343 * 1344 * Purpose: 1345 * Allocate DMA memory 1346 * Parameters: 1347 * d - device number 1348 * size - size of block 1349 * name - name of block (debugging, unused) 1350 * Returns: 1351 * 0 1352 */ 1353 static uint32* 1354 _salloc(int d, int size, const char *name) 1355 { 1356 /* All devices use the same dma memory pool */ 1357 uint32 *tmp; 1358 tmp = mpool_alloc(_dma_pool, size); 1359 #if AGGRESSIVE_ALLOC_DEBUG_TESTING 1360 printf("DMA Alloc: %p. Descriptor: %s.\n", tmp, name); 1361 #endif 1362 return tmp; 1363 } 1364 1365 /* 1366 * Function: _sfree 1367 * 1368 * Purpose: 1369 * Free DMA memory 1370 * Parameters: 1371 * d - device number 1372 * ptr - ptr to memory to free 1373 * Returns: 1374 * 0 1375 */ 1376 static void 1377 _sfree(int d, void *ptr) 1378 { 1379 #if AGGRESSIVE_ALLOC_DEBUG_TESTING 1380 printf("DMA Free: %p.\n", ptr); 1381 #endif 1382 /* All devices use the same dma memory pool */ 1383 mpool_free(_dma_pool, ptr); 1384 } 1385 1386 1387 /* 1388 * Thread ID of the signal handler/interrupt thread 1389 */ 1390 static volatile sal_thread_t _intr_thread = NULL; 1391 1392 /* 1393 * Thread ID of the signal handler/interrupt thread for ethernet devices 1394 */ 1395 static volatile sal_thread_t _ether_intr_thread = NULL; 1396 1397 /* 1398 * Function: intr_int_context 1399 * 1400 * Purpose: 1401 * Used by the linux kernel SAL to implement sal_int_context(). 1402 * Parameters: 1403 * None 1404 * Returns: 1405 * When the current thread is the interrupt thread. 1406 */ 1407 int intr_int_context(void) 1408 { 1409 return ((_intr_thread == sal_thread_self()) || 1410 (_ether_intr_thread == sal_thread_self())); 1411 } 1412 1413 1414 /* 1415 * Client Interrrupt Management 1416 */ 1417 1418 typedef struct intr_handler_s { 1419 void *data; 1420 void (*handler)(void*); 1421 } intr_handler_t; 1422 1423 /* For switching devices */ 1424 static intr_handler_t _handlers[LINUX_BDE_MAX_SWITCH_DEVICES]; 1425 static int _handler_max = -1; 1426 static int _intr_thread_running = 0; 1427 1428 /* for ethernet devices */ 1429 static intr_handler_t _ether_handler; 1430 static int _ether_dev_handler = 0; /* device id for ethernet device */ 1431 1432 /* 1433 * Function: _run_intr_handlers 1434 * 1435 * Purpose: 1436 * Run application level interrupt handlers. 1437 * Parameters: 1438 * None 1439 * Returns: 1440 * Nothing 1441 */ 1442 static void 1443 _run_intr_handlers(void) 1444 { 1445 int i; 1446 int spl; 1447 1448 /* 1449 * Protect applications threads from interrupt thread. 1450 */ 1451 spl = sal_splhi(); 1452 1453 /* 1454 * Run all of the client interrupt handlers 1455 */ 1456 for (i = 0; i <= _handler_max; i++) { 1457 if (_handlers[i].handler) { 1458 _handlers[i].handler(_handlers[i].data); 1459 } 1460 } 1461 1462 /* 1463 * Restore spl 1464 */ 1465 sal_spl(spl); 1466 } 1467 static void 1468 _run_ether_intr_handlers(void) 1469 { 1470 int spl; 1471 1472 /* 1473 * Protect applications threads from interrupt thread. 1474 */ 1475 spl = sal_splhi(); 1476 1477 /* 1478 * Run all of the client interrupt handlers 1479 */ 1480 1481 _ether_handler.handler(_ether_handler.data); 1482 1483 1484 /* 1485 * Restore spl 1486 */ 1487 sal_spl(spl); 1488 } 1489 1490 #ifdef SAL_BDE_THREAD_PRIO_DEFAULT 1491 #else 1492 /* 1493 * Function: _set_thread_priority 1494 * 1495 * Purpose: 1496 * Raise the current thread's execution priority 1497 * from regular to realtime. 1498 * Parameters: 1499 * prio - The realtime scheduling priority (0 - 99) 1500 * Returns: 1501 * Nothing 1502 */ 1503 static void 1504 _set_thread_priority(int prio) 1505 { 1506 struct sched_param param; 1507 param.sched_priority = prio; 1508 if (sched_setscheduler(0, SCHED_RR, ¶m)) { 1509 perror("\ninterrupt priority set: "); 1510 } 1511 } 1512 #endif /* SAL_BDE_THREAD_PRIO_DEFAULT */ 1513 1514 1515 /* 1516 * Function: _interrupt_thread 1517 * 1518 * Purpose: 1519 * Provides a thread context for interrupt handling. 1520 * Parameters: 1521 * context - unused 1522 * Returns: 1523 * Nothing 1524 * Notes: 1525 */ 1526 static void 1527 _interrupt_thread(void *d) 1528 { 1529 lubde_ioctl_t devio; 1530 1531 /* Initialize the variable */ 1532 memset(&devio, 0, sizeof(lubde_ioctl_t)); 1533 1534 devio.dev = PTR_TO_INT(d); 1535 1536 /* We are the interrupt thread for intr_int_context() */ 1537 _intr_thread = sal_thread_self(); 1538 1539 #ifdef SAL_BDE_THREAD_PRIO_DEFAULT 1540 #else 1541 /* Increase our priority */ 1542 _set_thread_priority(90); 1543 #endif /* SAL_BDE_THREAD_PRIO_DEFAULT */ 1544 1545 while (_intr_thread_running) { 1546 devio.dev = PTR_TO_INT(d); 1547 _ioctl(LUBDE_WAIT_FOR_INTERRUPT, &devio); 1548 _run_intr_handlers(); 1549 } 1550 } 1551 1552 /* 1553 * Function: 1554 * _ether_interrupt_thread 1555 * Purpose: 1556 * Provides a thread context for ethernet interrupt handling. 1557 * Interrupts are signaled, it provides the 1558 * unique context needed by the signal handler. 1559 * Parameters: 1560 * d - the device id in _devices 1561 * Returns: 1562 * Nothing 1563 * Notes: 1564 */ 1565 1566 static void 1567 _ether_interrupt_thread(void* d) 1568 { 1569 lubde_ioctl_t devio; 1570 1571 /* Initialize the variable */ 1572 memset(&devio, 0, sizeof(lubde_ioctl_t)); 1573 1574 devio.dev = PTR_TO_INT(d); 1575 1576 /* We are the interrupt thread for intr_int_context() */ 1577 _ether_intr_thread = sal_thread_self(); 1578 1579 #ifdef SAL_BDE_THREAD_PRIO_DEFAULT 1580 #else 1581 /* Increase our priority */ 1582 _set_thread_priority(90); 1583 #endif /* SAL_BDE_THREAD_PRIO_DEFAULT */ 1584 1585 for (;;) { 1586 devio.dev = PTR_TO_INT(d); 1587 _ioctl(LUBDE_WAIT_FOR_INTERRUPT, &devio); 1588 _run_ether_intr_handlers(); 1589 } 1590 } 1591 1592 /* 1593 * Function: 1594 * _interrupt_connect 1595 * Purpose: 1596 * BDE vector for connecting client interrupts to the device. 1597 * Initialized the SW interrupt controller and registers the handler. 1598 * Parameters: 1599 * d - device number 1600 * handler - client interrupt handler 1601 * data - client interrupt handler data 1602 * Returns: 1603 * 0 1604 */ 1605 static int 1606 _interrupt_connect(int d, 1607 void (*handler)(void*), 1608 void *data) 1609 { 1610 if (d < 0 || d >= COUNTOF(_devices)) { 1611 return -1; 1612 } 1613 1614 if (_devices[d]->dev_type & BDE_ETHER_DEV_TYPE) { 1615 _ether_dev_handler = d; 1616 _ether_handler.handler = handler; 1617 _ether_handler.data = data; 1618 1619 /* Create the ethernet interrupt thread */ 1620 sal_thread_create("bcmEthINTR", 1621 8096, 0, 1622 (void (*)(void*))_ether_interrupt_thread, 1623 INT_TO_PTR(d)); 1624 /* Enable interrupts on the device */ 1625 _enable_interrupts(d); 1626 1627 return 0; 1628 } 1629 1630 if (d >= COUNTOF(_handlers)) { 1631 return -1; 1632 } 1633 1634 /* Do not process more devices than necessary */ 1635 if (d > _handler_max) { 1636 _handler_max = d; 1637 } 1638 1639 _handlers[d].handler = handler; 1640 _handlers[d].data = data; 1641 1642 /* 1643 * Start up interrupt processing if this is the first connect 1644 */ 1645 if (_intr_thread_running == 0) { 1646 _intr_thread_running = 1; 1647 sal_thread_create("bcmINTR", 1648 8096, 0, 1649 (void (*)(void*))_interrupt_thread, 1650 INT_TO_PTR(d)); 1651 } 1652 1653 /* Enable interrupts on the device */ 1654 _enable_interrupts(d); 1655 1656 return 0; 1657 } 1658 1659 /* 1660 * Function: _interrupt_disconnect 1661 * 1662 * Purpose: 1663 * BDE interrupt disconnect function 1664 * Parameters: 1665 * d - device number 1666 * Returns: 1667 * 0 1668 */ 1669 static int 1670 _interrupt_disconnect(int d) 1671 { 1672 int spl; 1673 1674 if (d < 0 || d >= COUNTOF(_devices)) { 1675 return -1; 1676 } 1677 1678 /* Ethernet devices */ 1679 if (d >= _switch_ndevices && d < _ndevices) { 1680 _disable_interrupts(d); 1681 return 0; 1682 } 1683 1684 if (d >= COUNTOF(_handlers)) { 1685 return -1; 1686 } 1687 1688 /* Switch devices */ 1689 if (d >= 0 && d < _switch_ndevices) { 1690 _disable_interrupts(d); 1691 spl = sal_splhi(); 1692 _handlers[d].handler = NULL; 1693 _handlers[d].data = NULL; 1694 sal_spl(spl); 1695 } 1696 return 0; 1697 } 1698 1699 /* 1700 * Function: _l2p 1701 * 1702 * Purpose: 1703 * BDE l2p function. Converts CPU virtual DMA addresses 1704 * to Device Physical DMA addresses. 1705 * Parameters: 1706 * d - device number 1707 * laddr - logical address to convert 1708 * Returns: 1709 * Physical address 1710 */ 1711 static sal_paddr_t 1712 _l2p(int d, void *laddr) 1713 { 1714 /* DMA memory is one contiguous block */ 1715 phys_addr_t pbase = _dma_pbase; 1716 1717 if (!laddr) return 0; 1718 1719 pbase = (phys_addr_t)(PTR_TO_UINTPTR(pbase) + (PTR_TO_UINTPTR(laddr) - PTR_TO_UINTPTR(_dma_vbase))); 1720 1721 return ((sal_paddr_t)pbase); 1722 } 1723 1724 /* 1725 * Function: _p2l 1726 * 1727 * Purpose: 1728 * BDE p2l function. Converts Device Physical DMA addresses 1729 * to CPU virtual DMA addresses. 1730 * Parameters: 1731 * d - device number 1732 * paddr - physical address to convert 1733 * Returns: 1734 * Virtual address 1735 */ 1736 static void * 1737 _p2l(int d, sal_paddr_t paddr) 1738 { 1739 /* DMA memory is one contiguous block */ 1740 sal_vaddr_t vbase = PTR_TO_UINTPTR(_dma_vbase); 1741 1742 if (!paddr) return 0; 1743 1744 vbase = vbase + ((phys_addr_t)paddr - _dma_pbase); 1745 1746 return ((void *)vbase); 1747 } 1748 1749 static uint32 1750 _iproc_offset(int d, uint32 addr) 1751 { 1752 _iproc_map_t *map; 1753 _iproc_subwin_t *subwin; 1754 volatile uint32 *bar0, *pv; 1755 int idx; 1756 1757 if (d >= LINUX_BDE_MAX_DEVICES) { 1758 return 0; 1759 } 1760 1761 map = &iproc_map[d]; 1762 for (idx = 0; idx < IPROC_SUBWIN_MAX; idx++) { 1763 subwin = &map->subwin[idx]; 1764 if (addr >= subwin->addr_min && addr <= subwin->addr_max) { 1765 return subwin->addr_min - (idx * 0x1000); 1766 } 1767 } 1768 1769 /* Not found. (Re)use the default Subwindow */ 1770 subwin = &map->subwin[IPROC_DEFAULT_SUBWIN]; 1771 if (addr < subwin->addr_min || addr > subwin->addr_max) { 1772 subwin->addr_min = addr & ~(0xfff); 1773 subwin->addr_max = addr | 0xfff; 1774 1775 bar0 = (volatile uint32 *)_devices[d]->vbase1; 1776 pv = &bar0[BAR0_PAXB_IMAP0_0 / sizeof(uint32)]; 1777 pv[IPROC_DEFAULT_SUBWIN] = (subwin->addr_min | 0x1); 1778 1779 /* Read back IMAP register to ensure the write completes before proceeding */ 1780 if (pv[IPROC_DEFAULT_SUBWIN] != (subwin->addr_min | 0x1)) { 1781 return 0; 1782 } 1783 } 1784 return subwin->addr_min - (IPROC_DEFAULT_SUBWIN * 0x1000); 1785 } 1786 1787 1788 static uint32 1789 _iproc_ihost_read(int d, uint32 addr) 1790 { 1791 lubde_ioctl_t _devio; 1792 1793 /* Initialize the variable */ 1794 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 1795 1796 _devio.dev = d; 1797 _devio.d0 = addr; 1798 if (_ioctl(LUBDE_IPROC_READ_REG, &_devio) != 0) { 1799 printf("BDE iproc_read failed at 0x%08x\n", addr); 1800 return -1; 1801 } 1802 1803 return _devio.d1; 1804 } 1805 1806 static int 1807 _iproc_ihost_write(int d, uint32 addr, uint32 data) 1808 { 1809 lubde_ioctl_t _devio; 1810 1811 /* Initialize the variable */ 1812 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 1813 1814 _devio.dev = d; 1815 _devio.d0 = addr; 1816 _devio.d1 = data; 1817 1818 if (_ioctl(LUBDE_IPROC_WRITE_REG, &_devio) != 0) { 1819 printf("BDE iproc_write failed at 0x%08x\n", addr); 1820 return -1; 1821 } 1822 1823 return 0; 1824 } 1825 1826 /* 1827 * Function: _iproc_read 1828 * 1829 * Purpose: 1830 * Read an iProc register 1831 * Parameters: 1832 * d - device number 1833 * addr - register address 1834 * Returns: 1835 * register value 1836 */ 1837 static unsigned int 1838 _iproc_read(int d, unsigned int addr) 1839 { 1840 uint32 offset; 1841 uint32 rval; 1842 1843 if (_devices[d]->dev_type & BDE_AXI_DEV_TYPE) { 1844 return _iproc_ihost_read(d, addr); 1845 } 1846 sal_mutex_take(iproc_map_lock, sal_mutex_FOREVER); 1847 1848 if (!(_devices[d]->dev_type & BDE_NO_IPROC)) { 1849 if ((offset = _iproc_offset(d, addr)) == 0) { 1850 sal_mutex_give(iproc_map_lock); 1851 return -1; 1852 } 1853 addr -= offset; 1854 } 1855 1856 assert(_devices[d]->vbase1); 1857 rval = _devices[d]->vbase1[addr/sizeof(uint32)]; 1858 sal_mutex_give(iproc_map_lock); 1859 return rval; 1860 } 1861 1862 /* 1863 * Function: _iproc_write 1864 * 1865 * Purpose: 1866 * Write an iProc register 1867 * Parameters: 1868 * d - device number 1869 * addr - register address 1870 * data - register data 1871 * Returns: 1872 * 0 1873 */ 1874 static int 1875 _iproc_write(int d, uint32 addr, uint32 data) 1876 { 1877 uint32 offset; 1878 1879 if (_devices[d]->dev_type & BDE_AXI_DEV_TYPE) { 1880 return _iproc_ihost_write(d, addr, data); 1881 } 1882 sal_mutex_take(iproc_map_lock, sal_mutex_FOREVER); 1883 1884 if (!(_devices[d]->dev_type & BDE_NO_IPROC)) { 1885 if ((offset = _iproc_offset(d, addr)) == 0) { 1886 sal_mutex_give(iproc_map_lock); 1887 return -1; 1888 } 1889 addr -= offset; 1890 } 1891 1892 assert(_devices[d]->vbase1); 1893 _devices[d]->vbase1[addr/sizeof(uint32)] = data; 1894 1895 sal_mutex_give(iproc_map_lock); 1896 1897 return 0; 1898 } 1899 1900 #ifdef INCLUDE_CPU_I2C 1901 /* 1902 * I2C operations on the Device, assuming it is connected by I2C to the CPU. 1903 */ 1904 1905 /* Write to the internal device Address space using I2C */ 1906 static int 1907 _i2c_device_read( 1908 int dev, /* The device ID to access */ 1909 uint32 addr, /* The address to access in the internal device address space */ 1910 uint32 *value) /* the value to be read. */ 1911 { 1912 return cpu_i2c_device_read(_devices[dev]->i2c_bus, _devices[dev]->i2c_dev, addr, value); 1913 } 1914 1915 /* Write to the internal device Address space using I2C */ 1916 static int 1917 _i2c_device_write( 1918 int dev, /* The device ID to access */ 1919 uint32 addr, /* The address to access in the internal device address space */ 1920 uint32 value) /* the value to be written. */ 1921 { 1922 return cpu_i2c_device_write(_devices[dev]->i2c_bus, _devices[dev]->i2c_dev, addr, value); 1923 } 1924 #endif /* INCLUDE_CPU_I2C */ 1925 1926 #if LINUX_SPIDEV_SUPPORT /* Linux spidev driver for switch register access */ 1927 1928 1929 #endif /* LINUX_SPIDEV_SUPPORT */ 1930 1931 1932 #if LINUX_MDIODEV_SUPPORT 1933 /* Linux mdio device driver for external PHY access */ 1934 1935 #endif /* LINUX_MDIODEV_SUPPORT */ 1936 1937 /* 1938 * Function: 1939 * _spi_read 1940 * Purpose: 1941 * BDE spi_read function. Issue spi read via SMP 1942 * Parameters: 1943 * d - device number 1944 * addr - register addr to read 1945 * buf - buffer addr to store the reading result 1946 * int - number bytes to read 1947 * Returns: 1948 * 0 - Success 1949 * -1 - Failed 1950 */ 1951 1952 static int 1953 _spi_read(int d, uint32 addr, uint8 *buf, int len) 1954 { 1955 lubde_ioctl_t _devio; 1956 1957 /* Initialize the variable */ 1958 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 1959 1960 #if LINUX_SPIDEV_SUPPORT 1961 #endif /* LINUX_SPIDEV_SUPPORT */ 1962 1963 #if LINUX_MDIODEV_SUPPORT 1964 #endif /* LINUX_MDIODEV_SUPPORT */ 1965 1966 _devio.dev = d; 1967 _devio.d0 = addr; 1968 _devio.d1 = len; 1969 memset(_devio.dx.buf, 0, sizeof(_devio.dx.buf)); 1970 1971 if (_ioctl(LUBDE_SPI_READ_REG, &_devio) != 0) { 1972 printf("linux-user-bde: warnning: spi_read failed \ 1973 unit=%d addr=%x, len=%d", d, addr, len); 1974 return -1; 1975 } 1976 1977 memcpy(buf, _devio.dx.buf, len); 1978 1979 return 0; 1980 } 1981 1982 /* 1983 * Function: 1984 * _spi_write 1985 * Purpose: 1986 * BDE spi_write function. Issue spi read via SMP 1987 * Parameters: 1988 * d - device number 1989 * addr - register addr to write 1990 * buf - buffer to write to spi 1991 * int - number bytes for write 1992 * Returns: 1993 * 0 - Success 1994 * -1 - Failed 1995 */ 1996 1997 static int 1998 _spi_write(int d, uint32 addr, uint8 *buf, int len) 1999 { 2000 lubde_ioctl_t _devio; 2001 2002 /* Initialize the variable */ 2003 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 2004 2005 #if LINUX_SPIDEV_SUPPORT 2006 #endif /* LINUX_SPIDEV_SUPPORT */ 2007 2008 #if LINUX_MDIODEV_SUPPORT 2009 #endif /* LINUX_MDIODEV_SUPPORT */ 2010 2011 _devio.dev = d; 2012 _devio.d0 = addr; 2013 _devio.d1 = len; 2014 memcpy(_devio.dx.buf, buf, len); 2015 2016 if (_ioctl(LUBDE_SPI_WRITE_REG, &_devio) != 0) { 2017 printf("linux-user-bde: warnning: spi_write failed \ 2018 unit=%d addr=%x, len=%d", d, addr, len); 2019 return -1; 2020 } 2021 2022 return 0; 2023 } 2024 2025 STATIC int 2026 _xdigit2i(int digit) 2027 { 2028 if (digit >= '0' && digit <= '9') return (digit - '0' ); 2029 if (digit >= 'a' && digit <= 'f') return (digit - 'a' + 10); 2030 if (digit >= 'A' && digit <= 'F') return (digit - 'A' + 10); 2031 return 0; 2032 } 2033 2034 /* 2035 * Function: 2036 * bde_icid_get 2037 * Purpose: 2038 * Read ICID. 2039 * Parameters: 2040 * d - device number 2041 * data - buffer to store the reading result 2042 * size - buffer size 2043 * Returns: 2044 * 0 - Success 2045 * -1 - Failed 2046 */ 2047 int 2048 bde_icid_get(int d, uint8 *data, int len) 2049 { 2050 int fd; 2051 int i; 2052 char *fname; 2053 int rv = 0; 2054 int length = 0; 2055 uint8 *buf; 2056 2057 fname = "/proc/device-tree/aliases/icid"; 2058 fd = open(fname, O_RDONLY); 2059 if (fd >= 0) { 2060 buf = malloc(len * 2); 2061 length = len * 2; /* actual read length */ 2062 if (length == read(fd, buf, length)) { 2063 for (i = 0; i < len; i++) { 2064 *(data + i) = (_xdigit2i(*(buf + (2 * i))) << 4) | \ 2065 _xdigit2i(*(buf + (2 * i + 1))); 2066 } 2067 } else { 2068 /* data count in the file is not correct */ 2069 rv = -1; 2070 } 2071 free(buf); 2072 close(fd); 2073 } else { 2074 rv = -1; 2075 } 2076 return rv; 2077 } 2078 2079 #ifdef BCM_SAND_SUPPORT 2080 int 2081 _cpu_write(int d, uint32 addr, uint32 *buf) 2082 { 2083 lubde_ioctl_t _devio; 2084 2085 /* Initialize the variable */ 2086 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 2087 2088 _devio.dev = d; 2089 _devio.d0 = addr; 2090 _devio.d1 = sizeof(uint32); 2091 memcpy(_devio.dx.buf, buf, sizeof(uint32)); 2092 2093 if (_ioctl(LUBDE_CPU_WRITE_REG, &_devio) != 0) { 2094 printf("linux-user-bde: warnning: _cpu_write failed unit=%d addr=0x%x, buf=%p, *buf=0x%x", d, addr, (void*)buf, *buf); 2095 return -1; 2096 } 2097 2098 return 0; 2099 } 2100 2101 int 2102 _cpu_read(int d, uint32 addr, uint32 *buf) 2103 { 2104 lubde_ioctl_t _devio; 2105 2106 /* Initialize the variable */ 2107 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 2108 2109 _devio.dev = d; 2110 _devio.d0 = addr; 2111 _devio.d1 = sizeof(uint32); 2112 memset(_devio.dx.buf, 0, sizeof(_devio.dx.buf)); 2113 2114 if (_ioctl(LUBDE_CPU_READ_REG, &_devio) != 0) { 2115 printf("linux-user-bde: warnning: _cpu_read failed unit=%d addr=%x", d, addr); 2116 return -1; 2117 } 2118 2119 memcpy(buf, _devio.dx.buf, sizeof(uint32)); 2120 2121 return 0; 2122 } 2123 2124 int 2125 _cpu_pci_register(int d) 2126 { 2127 lubde_ioctl_t _devio; 2128 2129 /* Initialize the variable */ 2130 memset(&_devio, 0, sizeof(lubde_ioctl_t)); 2131 2132 _devio.dev = d; 2133 2134 if (_ioctl(LUBDE_CPU_PCI_REGISTER, &_devio) != 0) { 2135 printf("linux-user-bde: warnning: _cpu_pci_register failed unit=%d\n", d); 2136 return -1; 2137 } 2138 2139 return 0; 2140 } 2141 2142 #endif 2143 2144 /* 2145 * Function: 2146 * _num_devices 2147 * Purpose: 2148 * BDE num_devices function. Returns the number of devices. 2149 * Parameters: 2150 * None 2151 * Returns: 2152 * number of devices in this bde 2153 */ 2154 static int 2155 _num_devices(int type) 2156 { 2157 switch (type) { 2158 case BDE_ALL_DEVICES: 2159 return _ndevices; 2160 case BDE_SWITCH_DEVICES: 2161 return _switch_ndevices; 2162 case BDE_ETHER_DEVICES: 2163 return _ether_ndevices; 2164 case BDE_CPU_DEVICES: 2165 return _cpu_ndevices; 2166 } 2167 return 0; 2168 } 2169 2170 /* 2171 * Function: _get_dev 2172 * 2173 * Purpose: 2174 * BDE get_dev function. Returns device information structure. 2175 * Parameters: 2176 * d - device number 2177 * Returns: 2178 * const pointer to BDE device information structure. 2179 */ 2180 static const ibde_dev_t* 2181 _get_dev(int d) 2182 { 2183 assert(d >= 0 || d < _ndevices); 2184 return &_devices[d]->bde_dev; 2185 } 2186 2187 /* 2188 * Function: 2189 * _get_dev_type 2190 * Purpose: 2191 * BDE get_dev_type function. Returns device type of BUS(PCI,SPI)/ 2192 * FUNCTIONALITY(SWITCH/ETHERNET). 2193 * Parameters: 2194 * d - device number 2195 * Returns: 2196 * unsigned dword ORed with capablities of underlaying device. 2197 */ 2198 static uint32 2199 _get_dev_type(int d) 2200 { 2201 assert(d >= 0 || d < _ndevices); 2202 return _devices[d]->dev_type; 2203 } 2204 2205 /* 2206 * Function: 2207 * _name 2208 * Purpose: 2209 * BDE name function. Returns the name of the BDE. 2210 * Parameters: 2211 * None 2212 * Returns: 2213 * Name of this BDE 2214 */ 2215 static const char* 2216 _name(void) 2217 { 2218 return LINUX_USER_BDE_NAME; 2219 } 2220 2221 2222 /* 2223 * Function: _bus_features 2224 * 2225 * Purpose: 2226 * BDE bus features function. Returns the endian features of the system bus. 2227 * Parameters: 2228 * be_pio - (out) returns the big endian pio bit. 2229 * be_packet - (out) returns the big endian packet bit. 2230 * be_other - (out) returns the big endian other bit. 2231 * Returns: 2232 * nothing 2233 * Notes: 2234 * This just uses the values passed in by the BDE creator. 2235 * See linux_bde_create(). 2236 */ 2237 static linux_bde_bus_t _bus; 2238 2239 static void 2240 _bus_features(int unit, int *be_pio, int *be_packet, int *be_other) 2241 { 2242 /* 2243 * XGS BCM 56xxx/53xxx devices get the endianness from compile flags 2244 * whereas SBX devices (BCM88020 and QE-2000) get it by querying 2245 * the kernel BDE (ioctl) 2246 */ 2247 if ((_devices[unit]->bde_dev.device & 0xFF00) != 0x5600 && 2248 (_devices[unit]->bde_dev.device & 0xF000) != 0xc000 && 2249 (_devices[unit]->bde_dev.device & 0xF000) != 0xb000 && 2250 (_devices[unit]->bde_dev.device & 0xF000) != 0x8000 && 2251 (_devices[unit]->bde_dev.device & 0xFFFF) != 0x0732 && 2252 (_devices[unit]->bde_dev.device & 0xFFF0) != 0x0230 && 2253 (_devices[unit]->bde_dev.device & 0xFFF0) != 0x0030 && 2254 (_devices[unit]->bde_dev.device & 0xFFF0) != 0xa440) { 2255 lubde_ioctl_t devio; 2256 2257 /* Initialize the variable */ 2258 memset(&devio, 0, sizeof(lubde_ioctl_t)); 2259 2260 devio.dev = unit; 2261 _ioctl(LUBDE_GET_BUS_FEATURES, &devio); 2262 *be_pio = devio.d0; 2263 *be_packet = devio.d1; 2264 *be_other = devio.d2; 2265 } else { 2266 *be_pio = _bus.be_pio; 2267 *be_packet = _bus.be_packet; 2268 *be_other = _bus.be_other; 2269 } 2270 } 2271 2272 /* 2273 * Our BDE interface structure 2274 */ 2275 static ibde_t _ibde = { 2276 _name, 2277 _num_devices, 2278 _get_dev, 2279 _get_dev_type, 2280 _pci_config_get32, 2281 _pci_config_put32, 2282 _bus_features, 2283 _read, 2284 _write, 2285 _salloc, 2286 _sfree, 2287 NULL, 2288 NULL, 2289 _interrupt_connect, 2290 _interrupt_disconnect, 2291 _l2p, 2292 _p2l, 2293 _spi_read, 2294 _spi_write, 2295 _iproc_read, 2296 _iproc_write, 2297 NULL, 2298 NULL, 2299 NULL, 2300 NULL, 2301 #ifdef INCLUDE_CPU_I2C 2302 _i2c_device_read, 2303 _i2c_device_write, 2304 #else 2305 NULL, 2306 NULL, 2307 #endif /* INCLUDE_CPU_I2C */ 2308 }; 2309 2310 #ifdef BCM_INSTANCE_SUPPORT 2311 int 2312 linux_bde_instance_attach(unsigned int dev_mask,unsigned int dma_size) 2313 { 2314 _inst_dev_mask = dev_mask; 2315 _inst_dma_size = dma_size; 2316 return 0; 2317 } 2318 #endif 2319 2320 /* 2321 * Function: linux_bde_create 2322 * 2323 * Purpose: 2324 * Creator function for this BDE interface. 2325 * Parameters: 2326 * bus - pointer to the bus features structure you want this 2327 * bde to export. Depends on the system. 2328 * ibde - pointer to a location to recieve the bde interface pointer. 2329 * Returns: 2330 * 0 on success 2331 * -1 on failure. 2332 * Notes: 2333 * This is the main BDE create function for this interface. 2334 * Used by the external system initialization code. 2335 */ 2336 int 2337 linux_bde_create(linux_bde_bus_t* bus, ibde_t** ibde) 2338 { 2339 static int _init = 0; 2340 2341 if (!_init) { 2342 if (_open() == -1) { 2343 *ibde = NULL; 2344 return -1; 2345 } 2346 _init = 1; 2347 } 2348 memset(&_bus, 0, sizeof(_bus)); 2349 if (bus) { 2350 _bus = *bus; 2351 } 2352 *ibde = &_ibde; 2353 2354 #if LINUX_SPIDEV_SUPPORT 2355 #endif /* LINUX_SPIDEV_SUPPORT */ 2356 2357 #if LINUX_MDIODEV_SUPPORT 2358 #endif /* LINUX_MDIODEV_SUPPORT */ 2359 2360 #if CMIC_SPI_SUPPORT 2361 linux_cmic_spidev_open(0); 2362 #endif 2363 return 0; 2364 } 2365 2366 /* 2367 * Function: linux_bde_destroy 2368 * 2369 * Purpose: 2370 * destroy this bde 2371 * Parameters: 2372 * BDE interface pointer 2373 * Returns: 2374 * 0 on success, < 0 on error. 2375 */ 2376 int 2377 linux_bde_destroy(ibde_t* ibde) 2378 { 2379 #if LINUX_SPIDEV_SUPPORT 2380 #endif /* LINUX_SPIDEV_SUPPORT */ 2381 2382 #if LINUX_MDIODEV_SUPPORT 2383 #endif /* LINUX_MDIODEV_SUPPORT */ 2384 2385 #if CMIC_SPI_SUPPORT 2386 linux_cmic_spidev_close(0); 2387 #endif 2388 return _close(); 2389 } 2390 2391 /* 2392 * Function: bde_irq_mask_set 2393 * 2394 * Purpose: 2395 * Set interrupt mask from user space interrupt handler 2396 * Parameters: 2397 * unit - unit number 2398 * addr - PCI address of interrupt mask register 2399 * mask - interrupt mask 2400 * Returns: 2401 * 0 on success, < 0 on error. 2402 */ 2403 int 2404 bde_irq_mask_set(int unit, uint32 addr, uint32 mask) 2405 { 2406 lubde_ioctl_t devio; 2407 2408 /* Initialize the variable */ 2409 memset(&devio, 0, sizeof(lubde_ioctl_t)); 2410 2411 devio.dev = unit; 2412 devio.d0 = addr; 2413 devio.d1 = mask; 2414 _ioctl(LUBDE_WRITE_IRQ_MASK, &devio); 2415 return devio.rc; 2416 } 2417 /* 2418 * Function: bde_hw_unit_get 2419 * 2420 * Purpose: 2421 * Get the hw or user unit map 2422 * Parameter: 2423 * unit (IN) : inverse == 0, unit = user unit 2424 * inverse != 0, unit = hw unit 2425 * inverse (IN): specify to get hw or user unip map 2426 * Returns: 2427 * hw unit (probed in kernel BDE) : when inverse == 0 2428 * user unit : when invers != 0 2429 */ 2430 int 2431 bde_hw_unit_get(int unit, int inverse) 2432 { 2433 int u = 0; 2434 if (inverse) { 2435 for (u = 0; u < _ndevices; u ++) { 2436 if (_devices[u]->dev_id == unit) { 2437 return u; 2438 } 2439 } 2440 } else { 2441 if ((unit >= 0) && (unit < _ndevices)) { 2442 u = _devices[unit]->dev_id; 2443 } else { 2444 u = _devices[0]->dev_id; 2445 } 2446 } 2447 return u; 2448 } 2449 2450 #ifdef LINUX_SAL_DMA_ALLOC_OVERRIDE 2451 2452 /* 2453 * Function: sal_dma_alloc 2454 * 2455 * Notes: 2456 * See src/sal/core/unix/alloc.c for details. 2457 */ 2458 void * 2459 sal_dma_alloc(unsigned int sz, char *name) 2460 { 2461 #ifdef LINUX_PLI_COMBO_BDE 2462 if (bcm_sim_path_get()) { 2463 return sal_sim_dma_alloc(sz, name); 2464 } 2465 #endif 2466 return _ibde.salloc(0, sz, name); 2467 } 2468 2469 /* 2470 * Function: sal_dma_free 2471 * 2472 * Notes: 2473 * See src/sal/core/unix/alloc.c for details. 2474 */ 2475 void 2476 sal_dma_free(void *ptr) 2477 { 2478 #ifdef LINUX_PLI_COMBO_BDE 2479 if (bcm_sim_path_get()) { 2480 sal_sim_dma_free(ptr); 2481 return; 2482 } 2483 #endif 2484 _ibde.sfree(0, ptr); 2485 } 2486 2487 #endif /* LINUX_SAL_DMA_ALLOC_OVERRIDE */ 2488 2489 int 2490 _dma_get_usage(void) 2491 { 2492 return mpool_usage(_dma_pool); 2493 } 2494