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

xgs.c (17842B)


      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  * File:        xgs.c
      8  * Purpose:     Simple XGS board programming support library
      9  */
     10 
     11 #include <shared/bsl.h>
     12 
     13 #include <sal/core/alloc.h>
     14 #include <sal/core/libc.h>
     15 #include <bcm/error.h>
     16 #include <bcm/stack.h>
     17 #include <board/board.h>
     18 #if defined(INCLUDE_LIB_STKTASK)
     19 #include <appl/stktask/topo_brd.h>
     20 #endif
     21 #if defined(INCLUDE_LIB_DISCOVER)
     22 #include <appl/discover/disc.h>
     23 #endif
     24 #include <board/manager.h>
     25 #include <board/stack.h>
     26 #include <board/xgs.h>
     27 #include <board_int/support.h>
     28 
     29 #ifndef MAX_DESCRIPTION
     30 #define MAX_DESCRIPTION 80
     31 #endif
     32 
     33 #define UNIT0 0
     34 
     35 STATIC int
     36 _board_xgs_modid_get(board_driver_t *driver, char *name, int *modid);
     37 STATIC int
     38 _board_xgs_modid_set(board_driver_t *driver, char *name, int modid);
     39 STATIC int
     40 _board_xgs_num_modid_get(board_driver_t *driver,
     41                          char *name, int *num_modid);
     42 
     43 #define PRIVATE(field) \
     44   (((board_xgs_data_t *)(driver->user_data))->field)
     45 
     46 board_attribute_t board_xgs_attrib[] = {
     47     {
     48         BOARD_ATTRIBUTE_MODID,
     49         _board_xgs_modid_get,
     50         _board_xgs_modid_set,
     51     },
     52     {
     53         BOARD_ATTRIBUTE_NUM_MODID,
     54         _board_xgs_num_modid_get,
     55         NULL
     56     }
     57 };
     58 
     59 
     60 
     61 /*
     62  * Function:
     63  *     _board_xgs_modid_get
     64  * Purpose:
     65  *     Get board modid
     66  * Parameters:
     67  *     driver  - (IN)  current driver
     68  *     name    - (IN)  attribute name (ignored)
     69  *     modid   - (OUT) modid
     70  * Returns:
     71  *     BCM_E_NONE - success
     72  *     BCM_E_XXX - failed
     73  */
     74 STATIC int
     75 _board_xgs_modid_get(board_driver_t *driver, char *name, int *modid)
     76 {
     77     if (!modid) {
     78         return BCM_E_PARAM;
     79     }
     80 
     81     *modid = PRIVATE(device[UNIT0].modid);
     82 
     83     return BCM_E_NONE;
     84 }
     85 
     86 /*
     87  * Function:
     88  *     _adjust_modid
     89  * Purpose:
     90  *     If the given modid does not match the mask constraint,
     91  *     adjust it so it does
     92  * Parameters:
     93  *     device - (IN)    device data
     94  *     modid  - (INOUT) modid
     95  * Returns:
     96  *     BCM_E_NONE - success
     97  *     BCM_E_XXX - failed
     98  */
     99 STATIC int
    100 _adjust_modid(board_xgs_device_data_t *device, int *modid)
    101 {
    102     if ((device->modid_mask & *modid) != *modid) {
    103         *modid = (device->modid_mask & *modid) + device->num_modid;
    104     }
    105     device->modid = *modid;
    106 
    107     return BCM_E_NONE;
    108 }
    109 
    110 /*
    111  * Function:
    112  *     _board_xgs_modid_set
    113  * Purpose:
    114  *     Set the board modid
    115  * Parameters:
    116  *     driver  - (IN)  current driver
    117  *     name    - (IN)  attribute name (ignored)
    118  *     modid   - (IN) modid
    119  * Returns:
    120  *     BCM_E_NONE - success
    121  *     BCM_E_XXX - failed
    122  */
    123 STATIC int
    124 _board_xgs_modid_set(board_driver_t *driver, char *name, int modid)
    125 {
    126     int unit;
    127     int current_modid;
    128 
    129     current_modid = modid;
    130 
    131     for (unit=0; unit < PRIVATE(num_device); unit++) {
    132         _adjust_modid(&PRIVATE(device[unit]), &current_modid);
    133         BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(unit, current_modid));
    134         PRIVATE(device[unit].modid) = current_modid;
    135         current_modid += PRIVATE(device[unit].num_modid);
    136     }
    137 
    138     return BCM_E_NONE;
    139 }
    140 
    141 /*
    142  * Function:
    143  *     _board_xgs_num_modid_get
    144  * Purpose:
    145  *     Get the number of modids required by this board
    146  * Parameters:
    147  *     driver  - (IN)  current driver (ignored)
    148  *     name    - (IN)  attribute name (ignored)
    149  *     modid   - (OUT) modid
    150  * Returns:
    151  *     BCM_E_NONE - success
    152  *     BCM_E_XXX - failed
    153  */
    154 STATIC int
    155 _board_xgs_num_modid_get(board_driver_t *driver,
    156                         char *name, int *num_modid)
    157 {
    158     int unit;
    159     int nm;
    160 
    161     if (!num_modid) {
    162         return BCM_E_PARAM;
    163     }
    164 
    165     nm = 0;
    166 
    167     for (unit=0; unit < PRIVATE(num_device); unit++) {
    168         nm += PRIVATE(device[unit].num_modid);
    169     }
    170 
    171     *num_modid = nm;
    172 
    173     return BCM_E_NONE;
    174 }
    175 
    176 #if defined(INCLUDE_LIB_CPUDB)
    177 
    178 /*
    179  * Function:
    180  *     _board_xgs_stack_init
    181  * Purpose:
    182  *     Initialize cpudb and required stacking subsystems
    183  * Parameters:
    184  *     driver  - (IN)  current driver
    185  *     db_ref  - (OUT) stack CPUDB
    186  * Returns:
    187  *     BCM_E_NONE - success
    188  *     BCM_E_XXX - failed
    189  */
    190 STATIC int
    191 _board_xgs_stack_init(board_driver_t *driver, cpudb_ref_t db_ref)
    192 {
    193     BCM_IF_ERROR_RETURN(board_cpudb_get(driver, db_ref));
    194 #if defined(INCLUDE_LIB_DISCOVER)
    195     disc_ttl_max_set(2);
    196 #endif
    197     return BCM_E_NONE;
    198 }
    199 
    200 /*
    201  * Function:
    202  *     _board_xgs_stack
    203  * Purpose:
    204  *     Manage stktask callbacks
    205  * Parameters:
    206  *     op        - (IN)     current driver
    207  *     db_ref    - (IN/OUT) stack CPUDB
    208  *     topo_cpu  - (IN)     stack TOPO_CPU (ignored)
    209  *     user_data - (IN)     user data
    210  * Returns:
    211  *     BCM_E_NONE - success
    212  *     BCM_E_XXX - failed
    213  */
    214 STATIC int
    215 _board_xgs_stack(topo_board_control_t op,
    216                  cpudb_ref_t db_ref,
    217                  topo_cpu_t *topo_cpu,
    218                  void *user_data)
    219 {
    220     int rv = BCM_E_PARAM;
    221     board_driver_t *driver = (board_driver_t *)user_data;
    222 
    223     switch (op) {
    224     case topoBoardInit:
    225         rv = _board_xgs_stack_init(driver, db_ref);
    226         break;
    227 
    228     case topoBoardProgram:
    229         rv = board_stack_program(db_ref, 0);
    230         break;
    231 
    232     default:
    233         break;
    234 
    235     }
    236 
    237     return rv;
    238 }
    239 #endif
    240 
    241 /*
    242  * Function:
    243  *     board_xgs_description
    244  * Purpose:
    245  *     Return the board description string
    246  * Parameters:
    247  *     driver - (IN)  current driver
    248  * Returns:
    249  *     BCM_E_NONE - success
    250  *     BCM_E_XXX - failed
    251  */
    252 char *
    253 board_xgs_description(board_driver_t *driver)
    254 {
    255     return PRIVATE(description);
    256 }
    257 
    258 /*
    259  * Function:
    260  *     board_xgs_probe
    261  * Purpose:
    262  *     Test if board devices are appropriate for this board.
    263  * Parameters:
    264  *      driver - (IN) board driver
    265  *      num    - (IN) number of devices; length of info array
    266  *      info   - (IN) array of bcm_info_t
    267  * Returns:
    268  *     BCM_E_NONE - success
    269  *     BCM_E_XXX - failed
    270  */
    271 int
    272 board_xgs_probe(board_driver_t *driver, int num, bcm_info_t *info)
    273 {
    274     int i,j,idx,rv,match;
    275 
    276     rv = BCM_E_FAIL;
    277 
    278     if (num == PRIVATE(num_device)) {
    279 
    280         /* The number of supported devices needs to be modulo the number
    281            of devices on the board. */
    282         if (PRIVATE(num_supported_device) % PRIVATE(num_device)) {
    283             LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    284                         (BSL_META("%s: devtab not modulo numdev\n"),
    285                          driver->name));
    286             return BCM_E_CONFIG;
    287         }
    288         for (i=0; i<PRIVATE(num_supported_device); i+=PRIVATE(num_device)) {
    289             match=0;
    290 
    291             /* Test successive num_device entries for a match */
    292             for (j=0; j<PRIVATE(num_device); j++) {
    293                 idx = i+j;
    294                 if ((PRIVATE(supported_device[idx]) ==
    295                                                 BOARD_DRIVER_ANY_DEVICE) ||
    296                     (PRIVATE(supported_device[idx]) == info[j].device)) {
    297                     match++;
    298                 } else {
    299                     /* No match, try next set of devices */
    300                     break;
    301                 }
    302             }
    303             if (match == PRIVATE(num_device)) {
    304                 /* Found something */
    305                 LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    306                             (BSL_META("%s: units match\n"),
    307                              driver->name));
    308                 rv = BCM_E_NONE;
    309                 break;
    310             }
    311         }
    312     }
    313 
    314     return rv;
    315 }
    316 
    317 /*
    318  * Function:
    319  *     _board_xgs_banner
    320  * Purpose:
    321  *     Setup the board description string
    322  * Parameters:
    323  *      driver - (IN) board driver
    324  * Returns:
    325  *     BCM_E_NONE - success
    326  *     BCM_E_XXX - failed
    327  */
    328 STATIC int
    329 _board_xgs_banner(board_driver_t *driver)
    330 {
    331     if (PRIVATE(description) == NULL) {
    332         PRIVATE(description) = sal_alloc(MAX_DESCRIPTION, driver->name);
    333         if (PRIVATE(description) == NULL) {
    334             return BCM_E_MEMORY;
    335         }
    336     }
    337 
    338     sal_sprintf(PRIVATE(description), "%s board driver", driver->name);
    339 
    340     return BCM_E_NONE;
    341 }
    342 
    343 /*
    344  * Function:
    345  *     _board_xgs_add_internal_connections
    346  * Purpose:
    347  *     Add internal connections to probed stackable ports to
    348  *     construct a merged connection list for this board
    349  * Parameters:
    350  *      driver - (IN) board driver
    351  *      count  - (IN) number of connections
    352  *      conn   - (IN) connection list
    353  * Returns:
    354  *     BCM_E_NONE - success
    355  *     BCM_E_XXX - failed
    356  * Notes:
    357  *     gports are not conveniently orderable, so merge with brute force
    358  */
    359 STATIC int
    360 _board_xgs_add_internal_connections(board_driver_t *driver,
    361                                     int *count, board_connection_t *conn)
    362 {
    363     int i,j,replace,end,d_idx;
    364     bcm_gport_t i_port;
    365     board_connection_t *internal = PRIVATE(internal_connection);
    366 
    367     end = *count;
    368     for (i=0; i<PRIVATE(num_internal_connection); i++) {
    369 
    370         replace = -1;
    371         d_idx = -1;
    372         for (j=0; j<end; j++) {
    373 
    374             i_port = BCM_GPORT_TYPE_NONE;
    375 
    376             /* If either internal port matches the current connection
    377                list .from port, copy the 'other' internal port to the
    378                connection list .to entry, and prepare to remove the
    379                other internal port from the connection list. This
    380                should always be found after the current connection
    381                list position. */
    382             if (conn[j].from == internal[i].from) {
    383                 i_port = internal[i].to;
    384             } else if (conn[j].from == internal[i].to) {
    385                 i_port = internal[i].from;
    386             }
    387 
    388             if (i_port != BCM_GPORT_TYPE_NONE) {
    389                 if (replace < 0) {
    390                     LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    391                                 (BSL_META("Adding internal connection %d to conn %d\n"),
    392                                  i, j));
    393                     /* if internal_connection.from matches conn.from */
    394                     conn[j].to = i_port;
    395                     replace = i;
    396                 } else {
    397                     /* one side of internal matched, delete other side */
    398                     d_idx = j;
    399                     break;
    400                 }
    401             }
    402         }
    403 
    404         if (d_idx >= 0) {
    405             /* move up entries over deleted entry */
    406             for (j=d_idx; j<end; j++) {
    407                 LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    408                             (BSL_META("Copying %d to %d\n"),
    409                              j+1, j));
    410                 conn[j] = conn[j+1];
    411             }
    412             end -= 1;
    413             LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    414                         (BSL_META("Delete, end now %d\n"),
    415                          end));
    416         } else if (replace < 0) {
    417             /* add the internal entry to the end of the list */
    418             LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    419                         (BSL_META("Copying internal %d to %d\n"),
    420                          i, end));
    421             sal_memcpy(&conn[end], &internal[i], sizeof(conn[end]));
    422             end += 1;
    423             LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    424                         (BSL_META("Add internal, end now %d\n"),
    425                          end));
    426         }
    427     }
    428 
    429     LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    430                 (BSL_META("Board: %d internal, %d stack connections\n"),
    431                  PRIVATE(num_internal_connection),
    432                  end - PRIVATE(num_internal_connection)));
    433 
    434     *count = end;
    435     return BCM_E_NONE;
    436 }
    437 
    438 
    439 
    440 /*
    441  * Function:
    442  *     _board_xgs_initialize_connections
    443  * Purpose:
    444  *     Create connections for board based on requested and probed data
    445  * Parameters:
    446  *      driver - (IN) board driver
    447  * Returns:
    448  *     BCM_E_NONE - success
    449  *     BCM_E_XXX - failed
    450  */
    451 STATIC int
    452 _board_xgs_initialize_connections(board_driver_t *driver)
    453 {
    454     board_connection_t *conn;
    455     int count;
    456     int rv = BCM_E_FAIL;
    457 
    458     /* create connection array with the largest possible length */
    459 
    460     count = PRIVATE(num_device) * BCM_PBMP_PORT_MAX;
    461     conn = sal_alloc(count * sizeof(*conn), driver->name);
    462 
    463     if (conn) {
    464         sal_memset(conn, 0, count * sizeof(*conn));
    465         rv = board_connection_stack_ports(count, conn, &count);
    466         if (BCM_SUCCESS(rv)) {
    467             /* Go though the internal connection list */
    468             rv = _board_xgs_add_internal_connections(driver, &count, conn);
    469         } else {
    470             sal_free(conn);
    471         }
    472     } else {
    473         rv = BCM_E_MEMORY;
    474     }
    475 
    476     if (BCM_SUCCESS(rv)) {
    477         /* Add connection list to driver structure */
    478         driver->connection = conn;
    479         driver->num_connection = count;
    480     }
    481     return rv;
    482 }
    483 
    484 /*
    485  * Function:
    486  *     _board_xgs_initialize
    487  * Purpose:
    488  *     Initialize driver data
    489  * Parameters:
    490  *     driver - (IN) board driver
    491  * Returns:
    492  *     BCM_E_NONE - success
    493  *     BCM_E_XXX - failed
    494  */
    495 STATIC int
    496 _board_xgs_initialize(board_driver_t *driver)
    497 {
    498     BCM_IF_ERROR_RETURN
    499         (board_connection_add_internal_stack_ports
    500          (PRIVATE(num_internal_connection),
    501           PRIVATE(internal_connection)));
    502     BCM_IF_ERROR_RETURN(_board_xgs_initialize_connections(driver));
    503     BCM_IF_ERROR_RETURN(board_connection_setup());
    504     return BCM_E_NONE;
    505 
    506 }
    507 
    508 /*
    509  * Function:
    510  *     _board_xgs_cold_boot
    511  * Purpose:
    512  *     Cold boot device
    513  * Parameters:
    514  *     driver - (IN) board driver
    515  *     unit   - (IN) BCM device number
    516  * Returns:
    517  *     BCM_E_NONE - success
    518  *     BCM_E_XXX - failed
    519  */
    520 STATIC int
    521 _board_xgs_cold_boot(board_driver_t *driver, int unit)
    522 {
    523     BCM_IF_ERROR_RETURN(board_device_init(unit));
    524     BCM_IF_ERROR_RETURN(board_port_init(unit));
    525 
    526     /* I2C devices are only on unit 0 */
    527     if (unit == UNIT0) {
    528 #if defined(INCLUDE_I2C)
    529         BCM_IF_ERROR_RETURN(board_i2c_device_init(unit));
    530 #endif
    531         
    532     }
    533 
    534     BCM_IF_ERROR_RETURN(bcm_info_get(unit, &PRIVATE(device[unit].info)));
    535 
    536     BCM_IF_ERROR_RETURN
    537         (bcm_stk_modid_count(unit, &PRIVATE(device[unit].num_modid)));
    538     
    539     PRIVATE(device[unit].modid_mask) =
    540         ~(PRIVATE(device[unit].num_modid) - 1);
    541 
    542     return BCM_E_NONE;
    543 }
    544 
    545 /*
    546 
    547 */
    548 /*
    549  * Function:
    550  *     _board_xgs_init_modid
    551  * Purpose:
    552  *     Initialize modid on all devices
    553  * Parameters:
    554  *     driver - (IN) board driver
    555  * Returns:
    556  *     BCM_E_NONE - success
    557  *     BCM_E_XXX - failed
    558  */
    559 STATIC int
    560 _board_xgs_init_modid(board_driver_t *driver)
    561 {
    562     int unit, modid, rv = BCM_E_NONE;
    563 
    564     for (unit=0; unit<PRIVATE(num_device); unit++) {
    565         rv = bcm_stk_my_modid_get(unit, &modid);
    566         if (BCM_SUCCESS(rv)) {
    567             rv = _board_xgs_modid_set(driver, NULL, modid);
    568         } else if (rv != BCM_E_UNAVAIL) {
    569             break; /* if the error is not UNAVAIL,
    570                       something bad is happening */
    571         }
    572     }
    573 
    574     return rv;
    575 }
    576 
    577 /*
    578  * Function:
    579  *     _board_xgs_warm_boot
    580  * Purpose:
    581  *     Warm Boot device
    582  * Parameters:
    583  *     driver - (IN) board driver
    584  *     unit   - (IN) BCM device number
    585  * Returns:
    586  *     BCM_E_NONE - success
    587  *     BCM_E_XXX - failed
    588  */
    589 STATIC int
    590 _board_xgs_warm_boot(board_driver_t *driver, int unit)
    591 {
    592     return BCM_E_UNAVAIL;
    593 }
    594 
    595 /*
    596  * Function:
    597  *     _board_xgs_clear
    598  * Purpose:
    599  *     Clear device
    600  * Parameters:
    601  *     driver - (IN) board driver
    602  *     unit   - (IN) BCM device number
    603  * Returns:
    604  *     BCM_E_NONE - success
    605  *     BCM_E_XXX - failed
    606  */
    607 STATIC int
    608 _board_xgs_clear(board_driver_t *driver, int unit)
    609 {
    610     return BCM_E_UNAVAIL;
    611 }
    612 
    613 
    614 /*
    615  * Function:
    616  *     board_xgs_start
    617  * Purpose:
    618  *     XGS Board driver start function
    619  * Parameters:
    620  *     driver - (IN) board driver
    621  *     flags  - (IN) start flags
    622  * Returns:
    623  *     BCM_E_NONE - success
    624  *     BCM_E_XXX - failed
    625  */
    626 int
    627 board_xgs_start(board_driver_t *driver, uint32 flags)
    628 {
    629     int unit;
    630 
    631     /* allocate device instance data */
    632     if (PRIVATE(device) == NULL) {
    633         PRIVATE(device) = sal_alloc
    634             (sizeof(PRIVATE(device[UNIT0])) * (PRIVATE(num_device)),
    635              driver->name);
    636         if (PRIVATE(device) == NULL) {
    637             return BCM_E_MEMORY;
    638         }
    639     }
    640 
    641     /* install attributes */
    642     driver->attribute = board_xgs_attrib;
    643     driver->num_attribute = COUNTOF(board_xgs_attrib);
    644 
    645     /* init all the units */
    646     for (unit=0; unit<PRIVATE(num_device); unit++) {
    647         if (flags & BOARD_START_F_WARM_BOOT) {
    648             BCM_IF_ERROR_RETURN(_board_xgs_warm_boot(driver, unit));
    649         } else if (flags & BOARD_START_F_CLEAR) {
    650             BCM_IF_ERROR_RETURN(_board_xgs_clear(driver, unit));
    651         } else {
    652             BCM_IF_ERROR_RETURN(_board_xgs_cold_boot(driver, unit));
    653         }
    654     }
    655 
    656     BCM_IF_ERROR_RETURN(_board_xgs_init_modid(driver));
    657 
    658     /* Hook into stacking */
    659 #if defined(INCLUDE_LIB_STKTASK) && defined(INCLUDE_LIB_CPUDB)
    660     BCM_IF_ERROR_RETURN
    661         (topo_board_register(_board_xgs_stack, (void *)driver));
    662 #endif
    663     BCM_IF_ERROR_RETURN(_board_xgs_initialize(driver));
    664     BCM_IF_ERROR_RETURN(_board_xgs_banner(driver));
    665 
    666     LOG_VERBOSE(BSL_LS_BOARD_COMMON,
    667                 (BSL_META_U(unit,
    668                 "%s\n"),
    669                  PRIVATE(description)));
    670 
    671     return BCM_E_NONE;
    672 }
    673 
    674 /*
    675  * Function:
    676  *     board_xgs_stop
    677  * Purpose:
    678  *     XGS Board driver stop function
    679  * Parameters:
    680  *     driver - (IN) board driver
    681  * Returns:
    682  *     BCM_E_NONE - success
    683  *     BCM_E_XXX - failed
    684  */
    685 int
    686 board_xgs_stop(board_driver_t *driver)
    687 {
    688     board_xgs_device_data_t *dev;
    689     char *str;
    690     int unit;
    691 
    692     /* deinit all the units */
    693     for (unit=0; unit<PRIVATE(num_device); unit++) {
    694         BCM_IF_ERROR_RETURN(board_port_deinit(unit));
    695         BCM_IF_ERROR_RETURN(board_device_deinit(unit));
    696     }
    697 
    698     /* Reset dynamic data */
    699     driver->num_connection = 0;
    700     if (driver->connection) {
    701         sal_free(driver->connection);
    702         driver->connection = NULL;
    703     }
    704 
    705     dev = PRIVATE(device);
    706     PRIVATE(device) = NULL;
    707     sal_free(dev);
    708 
    709     str = PRIVATE(description);
    710     PRIVATE(description) = NULL;
    711     sal_free(str);
    712 
    713     return BCM_E_NONE;
    714 }
    715 
    716