openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 */