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

ledproc.c (49941B)


      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: 	ledproc.c
      8  * Purpose: 	LED Processor Support
      9  */
     10 
     11 #include <assert.h>
     12 #include <sal/core/libc.h>
     13 #include <shared/bsl.h>
     14 #include <bcm/error.h>
     15 #include <bcm/link.h>
     16 #include <soc/types.h>
     17 #include <appl/diag/system.h>
     18 
     19 #ifdef BCM_CMICM_SUPPORT
     20 #include <soc/cmicm.h>
     21 #endif
     22 
     23 #ifdef BCM_CMICX_SUPPORT
     24 #include <shared/cmicfw/cmicx_led.h>
     25 #endif /* BCM_CMICX_SUPPORT */
     26 
     27 #ifdef BCM_PETRA_SUPPORT
     28 #include <soc/dpp/mbcm.h>
     29 #endif
     30 
     31 #ifdef BCM_TRIDENT_SUPPORT
     32 #define TRIDENT_LEDUP_MAX              2
     33 #define TRIDENT_LEDUP0_PORT_MAX        36
     34 #define TRIUMPH3_LEDUP0_PORT_MAX       52
     35 #define HELIX4_LEDUP_PORT_MAX          64
     36 #define TRIDENT2_LEDUP0_PORT_MAX       64
     37 #define APACHE_LEDUP_PORT_MAX          36
     38 #define MONTEREY_LEDUP_PORT_MAX        64
     39 #endif /* BCM_TRIDENT_SUPPORT */
     40 
     41 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_SAND_SUPPORT)
     42 #define CMICD_V2_LEDUP_MAX             3
     43 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_PETRA_SUPPORT */
     44 
     45 #ifdef BCM_TOMAHAWK2_SUPPORT
     46 #define CMICD_V4_LEDUP_MAX             5
     47 #endif /* BCM_TOMAHAWK2_SUPPORT */
     48 
     49 #ifdef BCM_SABER2_SUPPORT
     50 #define SABER2_LEDUP_MAX                2
     51 #endif
     52 
     53 #ifdef BCM_GREYHOUND2_SUPPORT
     54 #define GREYHOUND2_LEDUP_MAX              2
     55 #define GREYHOUND2_LEDUP0_PORT_MAX        57
     56 #endif /* BCM_GREYHOUND2_SUPPORT */
     57 
     58 typedef struct led_info_s {
     59     uint32 ctrl;
     60     uint32 status;
     61     uint32 pram_base;
     62     uint32 dram_base;
     63 } led_info_t;
     64 
     65 static led_info_t led_info_gen[] = {
     66     {CMIC_LED_CTRL,CMIC_LED_STATUS,CMIC_LED_PROGRAM_RAM_BASE,
     67      CMIC_LED_DATA_RAM_BASE}
     68 };
     69 
     70 #ifdef BCM_TRIDENT_SUPPORT
     71 static led_info_t led_info_tri[] = {
     72     {CMICE_LEDUP0_CTRL,CMICE_LEDUP0_STATUS,CMICE_LEDUP0_PROGRAM_RAM_BASE,
     73      CMICE_LEDUP0_DATA_RAM_BASE},
     74     {CMICE_LEDUP1_CTRL,CMICE_LEDUP1_STATUS,CMICE_LEDUP1_PROGRAM_RAM_BASE,
     75      CMICE_LEDUP1_DATA_RAM_BASE}
     76 };
     77 #endif /* BCM_TRIDENT_SUPPORT */
     78 
     79 #ifdef BCM_CMICM_SUPPORT
     80 static led_info_t led_info_cmicm[] = {
     81     {CMIC_LEDUP0_CTRL_OFFSET,CMIC_LEDUP0_STATUS_OFFSET,CMIC_LEDUP0_PROGRAM_RAM_OFFSET,
     82      CMIC_LEDUP0_DATA_RAM_OFFSET},
     83     {CMIC_LEDUP1_CTRL_OFFSET,CMIC_LEDUP1_STATUS_OFFSET,CMIC_LEDUP1_PROGRAM_RAM_OFFSET,
     84      CMIC_LEDUP1_DATA_RAM_OFFSET}
     85 };
     86 #endif /* BCM_CMICM_SUPPORT */
     87 
     88 /*
     89  * Change 'led info' clause: This was for BCM_PETRA_SUPPORT (Arad and Jericho
     90  * family)and was changed to (BCM_PETRA_SUPPORT || BCM_DNX_SUPPORT) (Jericho-2 family, DNX) to
     91  * enable using a similar configuration file (For DNX: dnx.doc)
     92  * In the future, this may be changed as per actual DNX board details.
     93  */
     94 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT)
     95 static led_info_t led_info_cmicd_v2[] = {
     96     {CMIC_LEDUP0_CTRL_OFFSET,CMIC_LEDUP0_STATUS_OFFSET,CMIC_LEDUP0_PROGRAM_RAM_OFFSET,
     97      CMIC_LEDUP0_DATA_RAM_OFFSET},
     98     {CMIC_LEDUP1_CTRL_OFFSET,CMIC_LEDUP1_STATUS_OFFSET,CMIC_LEDUP1_PROGRAM_RAM_OFFSET,
     99      CMIC_LEDUP1_DATA_RAM_OFFSET},
    100     {CMIC_LEDUP2_CTRL_OFFSET,CMIC_LEDUP2_STATUS_OFFSET,CMIC_LEDUP2_PROGRAM_RAM_OFFSET,
    101      CMIC_LEDUP2_DATA_RAM_OFFSET}
    102 };
    103 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_PETRA_SUPPORT */
    104 
    105 #ifdef BCM_TOMAHAWK2_SUPPORT
    106 static led_info_t led_info_cmicd_v4[] = {
    107     {CMIC_LEDUP0_CTRL_OFFSET,CMIC_LEDUP0_STATUS_OFFSET,CMIC_LEDUP0_PROGRAM_RAM_OFFSET,
    108      CMIC_LEDUP0_DATA_RAM_OFFSET},
    109     {CMIC_LEDUP1_CTRL_OFFSET,CMIC_LEDUP1_STATUS_OFFSET,CMIC_LEDUP1_PROGRAM_RAM_OFFSET,
    110      CMIC_LEDUP1_DATA_RAM_OFFSET},
    111     {CMIC_LEDUP2_CTRL_OFFSET,CMIC_LEDUP2_STATUS_OFFSET,CMIC_LEDUP2_PROGRAM_RAM_OFFSET,
    112      CMIC_LEDUP2_DATA_RAM_OFFSET},
    113     {CMIC_LEDUP3_CTRL_OFFSET,CMIC_LEDUP3_STATUS_OFFSET,CMIC_LEDUP3_PROGRAM_RAM_OFFSET,
    114      CMIC_LEDUP3_DATA_RAM_OFFSET},
    115     {CMIC_LEDUP4_CTRL_OFFSET,CMIC_LEDUP4_STATUS_OFFSET,CMIC_LEDUP4_PROGRAM_RAM_OFFSET,
    116      CMIC_LEDUP4_DATA_RAM_OFFSET}
    117 };
    118 #endif /* BCM_TOMAHAWK2_SUPPORT */
    119 
    120 #ifdef BCM_CMICX_SUPPORT
    121 #define CMICX_LED 1
    122 #endif /* BCM_CMICX_SUPPORT */
    123 
    124 /*
    125  * Function:	ledproc_load
    126  * Purpose:	Load a program into the LED microprocessor from a buffer
    127  * Parameters:	unit - StrataSwitch unit #
    128  *		program - Array of up to 256 program bytes
    129  *		bytes - Number of bytes in array
    130  * Notes:	Also clears the LED processor data RAM from 0x80-0xff
    131  *		so the LED program has a known state at startup.
    132  */
    133 
    134 STATIC void
    135 ledproc_load(int unit, uint8 *program, int bytes, led_info_t *led_ptr)
    136 {
    137     int		offset;
    138 
    139     for (offset = 0; offset < CMIC_LED_PROGRAM_RAM_SIZE; offset++) {
    140 	soc_pci_write(unit,
    141 		      led_ptr->pram_base + CMIC_LED_REG_SIZE * offset,
    142 		      (offset < bytes) ? (uint32) program[offset] : 0);
    143     }
    144 
    145     for (offset = 0x80; offset < CMIC_LED_DATA_RAM_SIZE; offset++) {
    146 	soc_pci_write(unit,
    147 		      led_ptr->dram_base + CMIC_LED_REG_SIZE * offset,
    148 		      0);
    149     }
    150 }
    151 
    152 #ifndef NO_FILEIO
    153 STATIC cmd_result_t
    154 ledproc_load_fp(int unit, char *cmd, char *file, FILE *f,
    155                 led_info_t *led_ptr)
    156 /*
    157  * Function:	ledproc_load_fp
    158  * Purpose:	Load a program into the LED microprocessor from a file
    159  * Parameters:	unit - StrataSwitch unit #
    160  *		cmd - Name of command for error printing
    161  *		file - Name of file for error printing
    162  *		f - Open stdio file file pointer containing program
    163  * Returns:	CMD_XXX
    164  *
    165  * Notes:	File format (ASCII FILE)
    166  *	00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
    167  *	10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
    168  *	... for a total of 256 bytes, white space ignored.
    169  */
    170 {
    171     uint8	program[CMIC_LED_PROGRAM_RAM_SIZE];
    172     char        input[256], *cp = NULL, *error = NULL;
    173     int         bytes = 0, line = 0;
    174     int         offset_size = 0;
    175 
    176     while (!error && (cp = sal_fgets(input, sizeof(input) - 1, f))) {
    177         line++;
    178 
    179         while (*cp) {
    180             if (isspace((unsigned)(*cp))) { /* Skip whitespace */
    181                 cp++;
    182             } else {
    183                 if (!isxdigit((unsigned)*cp) ||
    184                     !isxdigit((unsigned)*(cp+1))) {
    185                     error = "Invalid hex digit";
    186                     break;
    187                 }
    188                 offset_size = sizeof(program);
    189                 if (bytes >= offset_size) {
    190                     error = "Program memory exceeded";
    191                     break;
    192                 }
    193                 program[bytes++] = (xdigit2i(*cp) << 4) | xdigit2i(*(cp + 1));
    194                 cp += 2;
    195             }
    196         }
    197     }
    198 
    199     if (error) {
    200         cli_out("%s: Error loading file %s line %d: %s\n",
    201                 cmd, file, line, error);
    202         return(CMD_FAIL);
    203     }
    204 
    205     cli_out("%s: Loading %d bytes into LED program memory\n",
    206             cmd, bytes);
    207 
    208     ledproc_load(unit, program, bytes,led_ptr);
    209 
    210     return(CMD_OK);
    211 }
    212 #endif /* NO_FILEIO */
    213 /*
    214  * Function:	ledproc_load_args
    215  * Purpose:	Load a program into the LED microprocessor from an args_t
    216  * Parameters:	unit - StrataSwitch unit #
    217  *		a - Remainder of command line containing raw hex data
    218  * Returns:	CMD_XXX
    219  * Notes:	Input strings are concatenated and parsed the
    220  *		same way as ledproc_load_fp.
    221  */
    222 STATIC cmd_result_t
    223 ledproc_load_args(int unit, args_t *a, led_info_t *led_ptr)
    224 /*
    225  * Notes:	Args format
    226  *	00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
    227  *	10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
    228  *	...
    229  * White space optional.
    230  */
    231 {
    232     uint8	program[CMIC_LED_PROGRAM_RAM_SIZE];
    233     int		bytes = 0;
    234     char	*cp;
    235     int         offset_size = 0;
    236 
    237     sal_memset(program, 0, sizeof (program));
    238 
    239     while ((cp = ARG_GET(a)) != NULL) {
    240 	while (*cp) {
    241 	    if (isspace((int)(*cp))) {
    242 		cp++;
    243 	    } else {
    244 		if (!isxdigit((unsigned)*cp) ||
    245 		    !isxdigit((unsigned)*(cp+1))) {
    246 		    cli_out("%s: Invalid character\n", ARG_CMD(a));
    247 		    return(CMD_FAIL);
    248 		}
    249 
    250                 offset_size = sizeof(program);
    251 		if (bytes >= offset_size) {
    252 		    cli_out("%s: Program memory exceeded\n", ARG_CMD(a));
    253 		    return(CMD_FAIL);
    254 		}
    255 		program[bytes++] = (xdigit2i(*cp) << 4) | xdigit2i(*(cp + 1));
    256 		cp += 2;
    257 	    }
    258 	}
    259     }
    260 
    261     ledproc_load(unit, program, bytes,led_ptr);
    262 
    263     return(CMD_OK);
    264 }
    265 
    266 /*
    267  * Function: ledproc_linkscan_cb
    268  * Purpose: Call back function for LEDs on link change.
    269  * Parameters: unit - unit number
    270  *             port - callback from this port
    271  *             info - pointer to structure giving status
    272  * Returns: nothing
    273  * Notes:   Each port has one byte of data at address (0x80 + portnum).
    274  *          For devices which fall under soc_feature_led_data_offset_a0
    275  *          the offset begins from 0xa0 instead of 0x80
    276  *      In each byte, bit 0 is used for link status.
    277  *      In each byte, bit 7 is used for turbo mode indication.
    278  */
    279 STATIC void
    280 ledproc_linkscan_cb(int unit, soc_port_t port, bcm_port_info_t *info)
    281 {
    282     uint32	portdata = 0;
    283     int		byte = LS_LED_DATA_OFFSET + port;
    284     led_info_t *led_info;
    285     int led_ix;
    286     soc_info_t *si;
    287     int phy_port = 0;  /* physical port number */
    288 
    289     si = &SOC_INFO(unit);
    290     led_info = led_info_gen;
    291     led_ix = 0;
    292 
    293 #ifdef BCM_TUCANA_SUPPORT
    294     if (SOC_IS_TUCANA(unit)) {
    295         byte = LS_TUCANA_LED_DATA_OFFSET + port;
    296     }
    297 #endif
    298 
    299 #ifdef BCM_RAVEN_SUPPORT
    300     if (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
    301         byte = LS_RAVEN_LED_DATA_OFFSET + port;
    302     }
    303 #endif
    304 
    305 #ifdef BCM_RAPTOR1_SUPPORT
    306     if (SOC_IS_RAPTOR(unit)) {
    307         byte = LS_RAPTOR_LED_DATA_OFFSET + port;
    308     }
    309 #endif
    310 
    311 #ifdef BCM_TRIUMPH_SUPPORT
    312     if (SOC_IS_TRIUMPH(unit)) {
    313         byte = LS_TR_VL_LED_DATA_OFFSET + port;
    314     }
    315 #endif
    316 
    317 #ifdef BCM_VALKYRIE_SUPPORT
    318     if (SOC_IS_VALKYRIE(unit)) {
    319         byte = LS_TR_VL_LED_DATA_OFFSET + port;
    320     }
    321 #endif
    322 
    323 #ifdef BCM_SCORPION_SUPPORT
    324     if (SOC_IS_SC_CQ(unit)) {
    325         byte = LS_SC_CQ_LED_DATA_OFFSET + port;
    326     }
    327 #endif
    328 
    329     if (soc_feature(unit, soc_feature_led_data_offset_a0)) {
    330         byte = LS_LED_DATA_OFFSET_A0 + port;
    331     }
    332 
    333     if (soc_feature(unit, soc_feature_logical_port_num)) {
    334         if (port >= 0 && port < SOC_MAX_NUM_PORTS) { /* safety check */
    335             phy_port = si->port_l2p_mapping[port];
    336             if (soc_feature(unit, soc_feature_led_data_offset_a0)) {
    337                 byte = LS_LED_DATA_OFFSET_A0 + phy_port;
    338             } else {
    339                 byte = LS_LED_DATA_OFFSET + phy_port;
    340             }
    341         }
    342     }
    343 
    344 #ifdef BCM_CMICX_SUPPORT
    345     if (soc_feature(unit, soc_feature_cmicx)) {
    346 #if CMICX_LED
    347         soc_led_link_status_t led_link_sts;
    348         soc_led_port_speed_t led_speed;
    349         int speed = 0, rv = BCM_E_NONE;
    350 
    351         led_link_sts.link_sts = (info->linkstatus == BCM_PORT_LINK_STATUS_UP);
    352         if (soc_feature(unit, soc_feature_logical_port_num)) {
    353             led_link_sts.port = phy_port;
    354         } else {
    355             led_link_sts.port = port;
    356         }
    357 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
    358 #ifdef BCM_TRIDENT3_SUPPORT
    359         /* LED processor captures the state for the two managment ports in
    360          * entries 128 and 130 in the accumulation RAM.  The first management
    361          * port will always have port number [66,129] in the SDK.  This is
    362          * decremented by one in the LED firmware, so there is no issue.  The
    363          * second management port reuses port [130,128] in the SDK, which can
    364          * also be used for PM31, subport 3.  This code differentiates that
    365          * special case and provides the needed por number for the second
    366          * management port
    367          */
    368 
    369         if (SOC_IS_TRIDENT3X(unit) && port == 130) {
    370             if (IS_MANAGEMENT_PORT(unit, port)) {
    371                 led_link_sts.port = 131;
    372             }
    373         }
    374 #endif /* BCM_TRIDENT3_SUPPORT */
    375 
    376 #ifdef BCM_TOMAHAWK3_SUPPORT
    377 
    378        /* Mapping xe1 (physical port 258) link status
    379         * to accumulation entry of physical port 259.
    380         * User should get port status/speed of xe1 (physical port 258) from the
    381         * entry of physical port 259 in accumulation RAM and speed array.
    382         */
    383         if (SOC_IS_TOMAHAWK3(unit) && phy_port == 258) {
    384             led_link_sts.port = 259;
    385         }
    386 #endif /* BCM_TOMAHAWK3_SUPPORT */
    387 
    388         soc_cmicx_led_link_status(unit, &led_link_sts);
    389 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
    390         /* Send port speed info when link goes UP */
    391         if (led_link_sts.link_sts) {
    392             /* Use logical port number here */
    393 #if defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT)
    394             if (SOC_IS_DNX(unit)) {
    395                 bcm_port_resource_t resource;
    396                 rv = bcm_port_resource_get(unit, port, &resource);
    397                 speed = resource.speed;
    398             } else
    399 #endif
    400             {
    401                 rv = bcm_port_speed_get(unit, port, &speed);
    402             }
    403             if (rv != BCM_E_NONE) {
    404                 cli_out("Error rv %d: Unable to get speed for port %d\n", rv, port);
    405             }
    406             led_speed.port = led_link_sts.port;
    407             led_speed.speed = speed;
    408             if (led_speed.speed) {
    409 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT)
    410                 soc_cmicx_led_speed(unit, &led_speed);
    411 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
    412             }
    413         }
    414 
    415 #endif /* CMICX_LED */
    416 
    417         /* CMICx-LED port update complete. */
    418         return;
    419     }
    420 #endif  /* BCM_CMICX_SUPPORT */
    421 
    422 
    423 #ifdef BCM_PETRA_SUPPORT
    424     if (SOC_IS_QAX(unit)) {
    425         uint32 physical_phy;
    426         bcm_error_t ret;
    427         if (port < 0 || port >= SOC_MAX_NUM_PORTS) { /* safety check */
    428             return;
    429         }
    430         if (soc_feature(unit, soc_feature_logical_port_num)) {
    431             ret = MBCM_DPP_DRIVER_CALL(unit, mbcm_dpp_qsgmii_offsets_remove,
    432             (unit, phy_port , &physical_phy));
    433             if (ret != BCM_E_NONE) {
    434                 return;
    435             }
    436             phy_port = physical_phy;
    437             byte = LS_LED_DATA_OFFSET_A0 + phy_port;
    438         }
    439     } else if (SOC_IS_JERICHO(unit)) {
    440 
    441         if (port < 0 || port >= SOC_MAX_NUM_PORTS) { /* safety check */
    442             return;
    443         }
    444 
    445         /* LED processor 0 - handles ports  1-24.  port 1  resides in index 1 in data ram */
    446         /* LED processor 1 - handles ports 25-84.  port 25 resides in index 1 in data ram */
    447         /* LED processor 2 - handles ports 85-144. port 85 resides in index 1 in data ram */
    448 
    449         if (soc_feature(unit, soc_feature_logical_port_num)) {
    450             if (phy_port <= 24) {
    451                 led_ix = 0;
    452             } else if (phy_port >= 25 && phy_port <= 84) {
    453                 led_ix = 1;
    454                 phy_port -= 24;
    455             } else if (phy_port > 84) {
    456                 led_ix = 2;
    457                 phy_port -= 84;
    458             }
    459             byte = LS_LED_DATA_OFFSET_A0 + phy_port;
    460         }
    461 
    462     }
    463 #endif /* BCM_PETRA_SUPPORT */
    464 
    465 
    466 #ifdef BCM_TRIDENT_SUPPORT
    467     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) {
    468         /* trident first 36 ports in ledproc0, the other 36 ports in ledproc1 */
    469         /* triumph3 first 52 ports are in ledproc0, the other ports are in ledproc1 */
    470         /* Helix4: Port 1-48 and 53-64 are in ledproc0, rest are in ledproc1 - Adjustment made later */
    471         int ledup0_pmax = SOC_IS_TD_TT(unit) ? TRIDENT_LEDUP0_PORT_MAX :
    472                           (SOC_IS_HELIX4(unit) ? HELIX4_LEDUP_PORT_MAX : TRIUMPH3_LEDUP0_PORT_MAX);
    473 
    474         if ((SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) && !SOC_IS_APACHE(unit)) {
    475             ledup0_pmax = TRIDENT2_LEDUP0_PORT_MAX;
    476         }
    477 
    478         if (SOC_IS_APACHE(unit)) {
    479 
    480             ledup0_pmax = APACHE_LEDUP_PORT_MAX;
    481         }
    482 
    483         if (SOC_IS_MONTEREY(unit)) {
    484 
    485             ledup0_pmax = MONTEREY_LEDUP_PORT_MAX;
    486         }
    487         if (port < 0 || port >= SOC_MAX_NUM_PORTS) { /* safety check */
    488             return;
    489         }
    490 
    491         led_info = led_info_tri;
    492         phy_port = si->port_l2p_mapping[port];
    493 
    494         if ((phy_port > ledup0_pmax) && (!SOC_IS_TOMAHAWKX(unit))) {
    495             /* For Helix4 this condition should never be true */
    496             phy_port -= ledup0_pmax;
    497             led_ix = 1;
    498         }
    499 
    500         if (soc_feature(unit, soc_feature_led_data_offset_a0)) {
    501             if (SOC_IS_HELIX4(unit)) {
    502                 if (phy_port > 48 && phy_port < 53) {
    503                     led_ix = 1;
    504                     phy_port -= 48;
    505                 } else if (phy_port > 52) {
    506                     phy_port -= 4;
    507                 }
    508                 byte = LS_LED_DATA_OFFSET_A0 + phy_port;
    509             } else if (SOC_IS_TRIUMPH3(unit)) {
    510                 if (led_ix) {
    511                     byte = LS_LED_DATA_OFFSET_A0 + phy_port + 4;
    512                 } else {
    513                     byte = LS_LED_DATA_OFFSET_A0 + phy_port;
    514                     if (phy_port == 37) {
    515                         byte += 12;
    516                     } else if (phy_port >= 38) {
    517                         byte -= 4;
    518                     }
    519                 }
    520             } else if ((SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) && !SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
    521                 int i, skip_count = 0;
    522                 for (i=1; i<phy_port; i++) {
    523                     skip_count += ((si->port_p2l_mapping[i+(led_ix*TRIDENT2_LEDUP0_PORT_MAX)] == -1) ? 1: 0);
    524                 }
    525                 byte = LS_LED_DATA_OFFSET_A0 + phy_port - skip_count;
    526                 if (SOC_IS_TRIDENT2(unit)) {
    527                     /*offset begin from 0xA0 */
    528                     byte -= 1;
    529                 }
    530             } else if (SOC_IS_APACHE(unit)) {
    531                 byte = LS_LED_DATA_OFFSET_A0 + phy_port - 1; /* Start from the A0 offset */
    532                 if (phy_port > 36 && !SOC_IS_MONTEREY(unit)) { /* Ports 37-72 in ledproc1 */
    533                     phy_port -= APACHE_LEDUP_PORT_MAX;
    534                     led_ix = 1;
    535                 }
    536             } else
    537 #ifdef BCM_TOMAHAWK_SUPPORT
    538             if (SOC_IS_TOMAHAWK(unit)) {
    539                 /* Tomahawk: Port 1-32 and 97-128 are in ledproc0
    540                  *           Port 33-96 are in ledproc1
    541                  *           Port 129 & 131 are in ledproc2
    542                  */
    543                 if (phy_port > 32 && phy_port < 97) {
    544                     led_ix = 1;
    545                     phy_port -=  32;
    546                 } else if (phy_port == 129 ) {
    547                     led_ix = 2;
    548                     phy_port = 1;
    549                 } else if (phy_port == 131 ) {
    550                     led_ix = 2;
    551                     phy_port = 2;
    552                 } else if (phy_port > 32) {
    553                     phy_port -= 64;
    554                 }
    555                 byte = LS_LED_DATA_OFFSET_A0 + phy_port - 1;
    556             } else
    557 #ifdef BCM_TOMAHAWK2_SUPPORT
    558             if (SOC_IS_TOMAHAWK2(unit)) {
    559                 if (259 == phy_port) {
    560                     led_ix = (phy_port - 1) / 64;
    561                     byte = LS_LED_DATA_OFFSET_A0 + 1;
    562                 } else {
    563                     led_ix = (phy_port - 1) / 64;
    564                     phy_port = (phy_port - 1) % 64 + 1;
    565                     byte = LS_LED_DATA_OFFSET_A0 + phy_port - 1;
    566                 }
    567             } else
    568 #endif /* BCM_TOMAHAWK2_SUPPORT */
    569 #endif /* BCM_TOMAHAWK_SUPPORT */
    570             {
    571                 byte = LS_LED_DATA_OFFSET_A0 + phy_port;
    572             }
    573         } else {
    574             byte = LS_LED_DATA_OFFSET + phy_port;
    575         }
    576     }
    577 #endif /* BCM_TRIDENT_SUPPORT */
    578 
    579 #ifdef BCM_GREYHOUND2_SUPPORT
    580     if (SOC_IS_GREYHOUND2(unit)) {
    581         if (phy_port > GREYHOUND2_LEDUP0_PORT_MAX) {
    582             led_ix = 1;
    583             /* ledup1 physical port shifted value is GREYHOUND2_LEDUP0_PORT_MAX - 1. */
    584             phy_port -= (GREYHOUND2_LEDUP0_PORT_MAX - 1);
    585         }
    586         byte = LS_LED_DATA_OFFSET_A0 + phy_port;
    587     }
    588 #endif /* BCM_GREYHOUND2_SUPPORT */
    589 
    590 #ifdef BCM_CMICM_SUPPORT
    591     if (soc_feature(unit, soc_feature_cmicm)) {
    592         led_info = led_info_cmicm;
    593     }
    594 #endif /* BCM_CMICM_SUPPORT */
    595 
    596 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_PETRA_SUPPORT)
    597     if (soc_feature(unit, soc_feature_led_cmicd_v2)) {
    598         led_info = led_info_cmicd_v2;
    599     }
    600 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_PETRA_SUPPORT */
    601 
    602 #ifdef BCM_TOMAHAWK2_SUPPORT
    603     if (soc_feature(unit, soc_feature_led_cmicd_v4)) {
    604         led_info = led_info_cmicd_v4;
    605     }
    606 #endif /* BCM_TOMAHAWK2_SUPPORT */
    607 
    608     /* coverity[OVERRUN-LOCAL: FALSE] */
    609     portdata = soc_pci_read(unit,
    610                      led_info[led_ix].dram_base + CMIC_LED_REG_SIZE * byte);
    611 
    612     if (info->linkstatus == BCM_PORT_LINK_STATUS_UP) {
    613         portdata |= 0x01;
    614     } else {
    615         portdata &= ~0x01;
    616     }
    617 
    618     portdata &= ~0x80;
    619 
    620     soc_pci_write(unit, led_info[led_ix].dram_base + CMIC_LED_REG_SIZE * byte,
    621                       portdata);
    622 }
    623 
    624 
    625 char ledproc_usage[] =
    626     "Parameters: [num] [status | start | stop | load <file.hex> |\n\t"
    627     "            [auto [on | off]] | prog <hexdata> | dump\n\t"
    628     "Load the LED Microprocessor with the program specified in <file.hex>.\n\t"
    629     "Option 'auto' turns on (by default) or off automatic linkscan\n\t"
    630     "    updates to the LED processor.\n\t"
    631     "Option 'num' selects the specific LED processor. The default is 0\n";
    632 
    633 cmd_result_t
    634 ledproc_cmd(int unit, args_t *a)
    635 /*
    636  * Function: 	sh_led
    637  * Purpose:	Load a led program and start it.
    638  * Parameters:	unit - unit
    639  *		a - args, each of the files to be displayed.
    640  * Returns:	CMD_OK/CMD_FAIL/CMD_USAGE
    641  */
    642 {
    643     VOL cmd_result_t		rv = CMD_OK;
    644 #ifndef NO_FILEIO
    645 #ifndef NO_CTRL_C
    646     jmp_buf			ctrl_c;
    647 #endif
    648     FILE * volatile		f = NULL;
    649 #endif
    650     char			*c;
    651     volatile uint32		led_ctrl, led_status;
    652     volatile int		auto_on;
    653     int led_max;
    654     led_info_t *led_info;
    655     led_info_t *led_info_cur;
    656     int ix;
    657     int phy_port_map = 0, led_up_instance = 0;
    658     int skip_force_link_check = FALSE;
    659 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_PETRA_SUPPORT)) && defined(BCM_WARM_BOOT_SUPPORT)
    660     uint32  boot_flags;
    661 #endif
    662     if (!sh_check_attached("ledproc", unit)) {
    663         return(CMD_FAIL);
    664     }
    665 
    666     if (!soc_feature(unit, soc_feature_led_proc)) {
    667         cli_out("%s: LED Micro-controller not available on %s\n",
    668                 ARG_CMD(a),
    669                 soc_dev_name(unit));
    670         return(CMD_FAIL);
    671     }
    672 
    673     led_info = led_info_gen;
    674     led_max = 1;
    675 
    676 #ifdef BCM_TRIDENT_SUPPORT
    677     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) {
    678         led_info = led_info_tri;
    679         led_max = TRIDENT_LEDUP_MAX;
    680     }
    681 #endif /* BCM_TRIDENT_SUPPORT */
    682 
    683 #ifdef BCM_GREYHOUND2_SUPPORT
    684     if (SOC_IS_GREYHOUND2(unit)){
    685         led_max = GREYHOUND2_LEDUP_MAX;
    686     }
    687 #endif /* BCM_GREYHOUND2_SUPPORT */
    688 
    689 #ifdef BCM_CMICM_SUPPORT
    690     if (soc_feature(unit, soc_feature_cmicm)) {
    691         led_info = led_info_cmicm;
    692 #if defined(BCM_SABER2_SUPPORT)
    693         led_max = SABER2_LEDUP_MAX;
    694 #endif
    695     }
    696 #endif /* BCM_CMICM_SUPPORT */
    697 
    698 /*
    699  * Change 'led info' clause: This was for BCM_PETRA_SUPPORT (Arad and Jericho
    700  * family)and was changed to (BCM_PETRA_SUPPORT || BCM_DNX_SUPPORT) (Jericho-2 family, DNX) to
    701  * enable using a similar configuration file (For DNX: dnx.doc)
    702  * In the future, this may be changed as per actual DNX board details.
    703  */
    704 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT)
    705     if(soc_feature(unit, soc_feature_led_cmicd_v2)) {
    706         led_info = led_info_cmicd_v2;
    707         led_max = CMICD_V2_LEDUP_MAX;
    708     }
    709 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_PETRA_SUPPORT */
    710 
    711 #ifdef BCM_TOMAHAWK2_SUPPORT
    712     if(soc_feature(unit, soc_feature_led_cmicd_v4)) {
    713         led_info = led_info_cmicd_v4;
    714         led_max = CMICD_V4_LEDUP_MAX;
    715     }
    716 #endif /* BCM_TOMAHAWK2_SUPPORT */
    717 
    718 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_PETRA_SUPPORT)) && defined(BCM_WARM_BOOT_SUPPORT)
    719     boot_flags = sal_boot_flags_get();
    720     if ((boot_flags & BOOT_F_WARM_BOOT) &&
    721         (!SOC_IS_ESW(unit) || SOC_IS_TOMAHAWK(unit))) {
    722         skip_force_link_check = TRUE;
    723     }
    724 #endif
    725 
    726     if (bcm_linkscan_unregister(unit, ledproc_linkscan_cb) < 0) {
    727         auto_on = FALSE;
    728     } else {
    729         (void)bcm_linkscan_register(unit, ledproc_linkscan_cb);
    730         auto_on = TRUE;
    731     }
    732 
    733     if (ARG_CNT(a) == 0) {
    734 #ifdef BCM_CMICX_SUPPORT
    735             if (soc_feature(unit, soc_feature_cmicx)) {
    736 #if CMICX_LED
    737                 cli_out("LED M0 FW is %s Init DONE; "
    738                         "auto updating is %s.\n",
    739                         (SOC_CONTROL(unit)->led_fw_enabled) ? "ON" : "OFF",
    740                         auto_on ? "ON" : "OFF");
    741 #endif /* CMICX_LED */
    742                 return(CMD_OK);
    743             }
    744 #endif  /* BCM_CMICX_SUPPORT */
    745         for (ix = 0; ix < led_max; ix++) {
    746             led_ctrl = soc_pci_read(unit, led_info[ix].ctrl);
    747             led_status = soc_pci_read(unit, led_info[ix].status);
    748             cli_out("%s: LED%d Micro-controller is %s (PC=0x%x State=%s%s); "
    749                     "auto updating is %s.\n",
    750                     ARG_CMD(a),
    751                     ix,
    752                     (led_ctrl & LC_LED_ENABLE) ? "ON" : "OFF",
    753                     (led_status & LS_LED_PC),
    754                     (led_status & LS_LED_INIT) ? "INIT," : "",
    755                     (led_status & LS_LED_RUN) ? "RUN" : "SLEEP",
    756                     auto_on ? "ON" : "OFF");
    757         }
    758         return(CMD_OK);
    759     }
    760 
    761     ix = 0;
    762     c = ARG_GET(a);
    763 
    764     /* check if command has processor number specified */
    765     if (isint(c)) {
    766         ix = parse_integer(c);
    767         if (ix > (led_max - 1)) {
    768             cli_out("Invalid uProcessor number: %d, set to 0\n",ix);
    769             ix = led_max - 1;
    770         }
    771         c = ARG_GET(a);
    772     }
    773 
    774     led_info_cur = led_info+ix;
    775 
    776 #ifdef BCM_CMICX_SUPPORT
    777     if (!soc_feature(unit, soc_feature_cmicx))
    778 #endif /* BCM_CMICX_SUPPORT */
    779     {
    780         /* Not for CMICx-LED. */
    781         led_ctrl = soc_pci_read(unit, led_info_cur->ctrl);
    782     }
    783 
    784     if (!sal_strcasecmp(c, "status")) {
    785         int     port;
    786         uint32	portdata = 0;
    787         int phy_port;
    788 #ifdef BCM_TRIDENT_SUPPORT
    789         uint32 portdata1 = 0;
    790 #endif
    791 #ifdef BCM_CMICX_SUPPORT
    792 #if CMICX_LED
    793 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
    794         int rv = SOC_E_NONE;
    795         soc_led_port_status_t led_status;
    796 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
    797 #endif /* CMICX_LED */
    798 #endif  /* BCM_CMICX_SUPPORT */
    799 
    800         /* coverity[overrun-local] */
    801         PBMP_PORT_ITER(unit, port) {
    802 
    803 #ifdef BCM_CMICX_SUPPORT
    804             if (soc_feature(unit, soc_feature_cmicx)) {
    805 #if CMICX_LED
    806                 if (!SOC_CONTROL(unit)->led_fw_enabled) {
    807                     cli_out("LED FW not running\n");
    808                     break;
    809                 }
    810 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
    811                 if (soc_feature(unit, soc_feature_logical_port_num)) {
    812                     led_status.port = SOC_INFO(unit).port_l2p_mapping[port];
    813                 } else {
    814                     led_status.port = port;
    815                 }
    816 
    817                 /* Display LED output ram status for the port */
    818                 led_status.bank = LED_SEND_RAM_BANK;
    819 
    820                 rv = soc_cmicx_led_status_get(unit, &led_status);
    821 
    822                 if (rv != SOC_E_NONE) {
    823                     cli_out("Error: Unable to get LED status\n");
    824                     return(CMD_FAIL);
    825                 } else {
    826                     cli_out("Port %d led status 0x%x\n", port, led_status.status);
    827                     continue;
    828                 }
    829 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
    830 #else
    831                 continue;
    832 #endif /* CMICX_LED */
    833             }
    834 #endif  /* BCM_CMICX_SUPPORT */
    835 
    836 #ifdef BCM_PETRA_SUPPORT
    837             /* SOC_IS_ARAD includes also later DNX fap devices */
    838             if (SOC_IS_ARAD(unit)) {
    839                 /* skipping over sfi ports */
    840                 if(IS_SFI_PORT(unit,port)) {
    841                     continue;
    842                 }
    843             }
    844 #endif
    845 
    846             if (soc_feature(unit, soc_feature_logical_port_num)) {
    847                 if (port >= SOC_MAX_NUM_PORTS) { /* safety check */
    848                     break;
    849                 }
    850                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    851             } else {
    852                 phy_port = port;
    853             }
    854 
    855 #ifdef BCM_PETRA_SUPPORT
    856             if (SOC_IS_QAX(unit)) {
    857                 uint32 physical_phy;
    858                 bcm_error_t ret;
    859                 ret = MBCM_DPP_DRIVER_CALL(unit, mbcm_dpp_qsgmii_offsets_remove,
    860                 (unit, phy_port , &physical_phy));
    861                 if (ret != BCM_E_NONE) {
    862                     continue;
    863                 }
    864                 phy_port = physical_phy;
    865 
    866             } else if (SOC_IS_JERICHO(unit)) {
    867 
    868                 /* LED processor 0 - will handle ports  1-24.  port 1  resides in index 1 in data ram */
    869                 /* LED processor 1 - will handle ports 25-84.  port 25 resides in index 1 in data ram */
    870                 /* LED processor 2 - will handle ports 85-144. port 85 resides in index 1 in data ram */
    871 
    872                 if (phy_port <= 24) {
    873                     led_up_instance = 0;
    874                 } else if (phy_port >= 25 && phy_port <= 84) {
    875                     led_up_instance = 1;
    876                     phy_port -= 24;
    877                 } else if (phy_port > 84) {
    878                     led_up_instance = 2;
    879                     phy_port -= 84;
    880                 }
    881                 led_info_cur = led_info + led_up_instance;
    882             }
    883 #endif /* BCM_PETRA_SUPPORT */
    884 
    885 
    886 #ifdef BCM_TRIDENT_SUPPORT
    887             if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) {
    888                 /* trident first 36 ports in ledproc0, the other 36 ports in ledproc1*/
    889                 /* triumph3 first 52 ports are in ledproc0, the other ports are in ledproc1 */
    890                 int ledup0_pmax = SOC_IS_TD_TT(unit) ? TRIDENT_LEDUP0_PORT_MAX :
    891                                   (SOC_IS_HELIX4(unit) ? HELIX4_LEDUP_PORT_MAX : TRIUMPH3_LEDUP0_PORT_MAX);
    892                 if ((SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) && !SOC_IS_APACHE(unit)) {
    893                     ledup0_pmax = TRIDENT2_LEDUP0_PORT_MAX;
    894                 }
    895 
    896                 if (SOC_IS_APACHE(unit)) {
    897                     ledup0_pmax = APACHE_LEDUP_PORT_MAX;
    898                 }
    899                 if (SOC_IS_MONTEREY(unit)) {
    900                     ledup0_pmax = MONTEREY_LEDUP_PORT_MAX;
    901                 }
    902 
    903 #ifdef BCM_TOMAHAWK_SUPPORT
    904                 if (SOC_IS_TOMAHAWK(unit)) {
    905                     /* Tomahawk: Port 1-32 and 97-128 are in ledproc0
    906                      *           Port 33-96 are in ledproc1
    907                      *           Port 129 & 131 are in ledproc2
    908                      */
    909                     if (phy_port == 129) {
    910                         led_info_cur = led_info + 2;
    911                         phy_port = 1;
    912                         led_up_instance = 2;
    913                     } else if (phy_port == 131) {
    914                         led_info_cur = led_info + 2;
    915                         phy_port = 2;
    916                         led_up_instance = 2;
    917                     } else if (phy_port > 32 && phy_port < 97) {
    918                         led_info_cur = led_info + 1;
    919                         phy_port -= 32;
    920                         led_up_instance = 1;
    921                     } else if (phy_port > 32) {
    922                         phy_port -= 64;
    923                         led_info_cur = led_info;
    924                         led_up_instance = 0;
    925                     }
    926                 } else
    927 #ifdef BCM_TOMAHAWK2_SUPPORT
    928                 if (SOC_IS_TOMAHAWK2(unit)) {
    929                     led_up_instance = (phy_port - 1) / 64;
    930                     led_info_cur = led_info + led_up_instance;
    931                     phy_port = (phy_port - 1) % 64 + 1;
    932                 } else
    933 #endif /* BCM_TOMAHAWK2_SUPPORT */
    934 #endif /* BCM_TOMAHAWK_SUPPORT */
    935                     if (phy_port > ledup0_pmax) {
    936                         phy_port -= ledup0_pmax;
    937                         led_info_cur = led_info+1;
    938                         led_up_instance = 1;
    939                     } else {
    940                         led_info_cur = led_info;
    941                         led_up_instance = 0;
    942                     }
    943                 if ((SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) && !SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
    944                     int i, skip_count = 0;
    945                     for (i=1; i < phy_port; i++) {
    946                         skip_count += ((SOC_INFO(unit).port_p2l_mapping[i+(led_up_instance*TRIDENT2_LEDUP0_PORT_MAX)] == -1) ? 1: 0);
    947                     }
    948                     phy_port -= skip_count;
    949                 }
    950             }
    951 #endif /* BCM_TRIDENT_SUPPORT */
    952 
    953             /* Portmap */
    954             phy_port_map = phy_port;
    955             if (SOC_IS_TRIUMPH3(unit)) {
    956                 if (led_up_instance) {
    957                     phy_port_map = phy_port + 4;
    958                 } else {
    959                     phy_port_map = phy_port;
    960                     if (phy_port == 37) {
    961                         phy_port_map += 12;
    962                     } else if (phy_port >= 38) {
    963                         phy_port_map -= 4;
    964                     }
    965                 }
    966             }
    967 #ifdef BCM_KATANA2_SUPPORT
    968             if (SOC_IS_KATANA2(unit)) {
    969                 /* For Kt2 we start status from 1, not 0 */
    970                 phy_port_map += 1;
    971             }
    972 
    973             /* phy_port_map ranges from 1 to 64, while status bits range from 0 to 63 */
    974 #endif /* BCM_CMICM_SUPPORT */
    975 
    976 
    977 #ifdef BCM_TRIDENT_SUPPORT
    978             if (SOC_IS_TD_TT(unit)) {
    979                 uint32 byte;
    980 #ifdef BCM_TOMAHAWK_SUPPORT
    981                 if (SOC_IS_TOMAHAWKX(unit)) {
    982                     /* link status is kept current in bit 0 of
    983                        data RAM byte (0xA0 + portnum) */
    984                     byte = LS_LED_DATA_OFFSET_A0 + phy_port_map - 1;
    985                     portdata1 = soc_pci_read(unit,
    986                             led_info_cur->dram_base + CMIC_LED_REG_SIZE * byte);
    987 
    988                     /* HW Port status in data RAM (0x00 + portnum) */
    989                     portdata = soc_pci_read(unit, led_info_cur->dram_base
    990                             + CMIC_LED_REG_SIZE * 2 * (phy_port_map - 1));
    991                     if (portdata1 & 0x1) {
    992                         portdata |= 0x80;
    993                     } else {
    994                         portdata &= ~0x80;
    995                     }
    996                 } else
    997 #endif /* BCM_TOMAHAWK_SUPPORT */
    998                 {
    999                     if (soc_feature(unit, soc_feature_led_data_offset_a0)) {
   1000                         byte = LS_LED_DATA_OFFSET_A0 + phy_port_map;
   1001                         if (SOC_IS_TRIDENT2(unit) || SOC_IS_APACHE(unit)) {
   1002                             /*offset begin from 0xA0 */
   1003                             byte -= 1;
   1004                         }
   1005                     } else {
   1006                         byte = LS_LED_DATA_OFFSET + phy_port_map;
   1007                     }
   1008 
   1009                     /* read tx/rx activity */
   1010                     portdata1 = soc_pci_read(unit,
   1011                                              led_info_cur->dram_base + CMIC_LED_REG_SIZE * byte);
   1012 
   1013                     if (portdata1 & 0x1) {
   1014                         portdata |= 0x80;
   1015                     } else {
   1016                         portdata &= ~0x80;
   1017                     }
   1018                     if (portdata1 & 0x10) {
   1019                         portdata |= 0x2;
   1020                     } else {
   1021                         portdata &= ~0x2;
   1022                     }
   1023                     if (portdata1 & 0x20) {
   1024                         portdata |= 0x1;
   1025                     } else {
   1026                         portdata &= ~0x1;
   1027                     }
   1028 
   1029                     if (SOC_IS_TRIDENT2PLUS(unit)) {
   1030                         phy_port_map -= 1;
   1031                     }
   1032 
   1033                     portdata1 = soc_pci_read(unit,
   1034                                              led_info_cur->dram_base + CMIC_LED_REG_SIZE * (phy_port_map * 2 + 1));
   1035                     portdata1 &= 0xFF;
   1036                     portdata1 <<= 8;
   1037                     portdata1 |= 0xFF & soc_pci_read(unit,
   1038                                                       led_info_cur->dram_base + CMIC_LED_REG_SIZE * 2 * phy_port_map);
   1039                 }
   1040             }
   1041 #endif /* BCM_TRIDENT_SUPPORT */
   1042 
   1043 #ifdef BCM_PETRA_SUPPORT
   1044             if (SOC_IS_ARAD(unit)) {
   1045 
   1046                 uint32 byte;
   1047                 uint32 portdata1;
   1048 
   1049                 /* link status is kept current in bit 0 of data RAM byte (0xA0 + portnum) */
   1050                 byte = LS_LED_DATA_OFFSET_A0 + phy_port_map;
   1051                 portdata1 = soc_pci_read(unit,
   1052                                          led_info_cur->dram_base + CMIC_LED_REG_SIZE * byte);
   1053 
   1054                 /* HW Port status in data RAM (0x00 + portnum) */
   1055                 portdata = soc_pci_read(unit, led_info_cur->dram_base
   1056                                         + CMIC_LED_REG_SIZE * 2 * (phy_port_map));
   1057                 if (portdata1 & 0x1) {
   1058                     portdata |= 0x80;
   1059                 } else {
   1060                     portdata &= ~0x80;
   1061                 }
   1062             }
   1063 #endif /* BCM_PETRA_SUPPORT */
   1064 
   1065 
   1066             /* coverity[overrun-local] */
   1067             if (soc_feature(unit, soc_feature_unimac) &&
   1068                     ((IS_FE_PORT(unit, port)) || (IS_GE_PORT(unit, port)))) {
   1069 #ifdef BCM_TRIDENT_SUPPORT
   1070                 if (SOC_IS_TD_TT(unit)) {
   1071                     int speed = (portdata1 & 0x18) >> 3;
   1072                     cli_out("%2d %4s %s %s %s %s %s %s %s %d:%d\n",
   1073                             port,
   1074                             SOC_PORT_VALID(unit, port) ?
   1075                             SOC_PORT_NAME(unit, port) :"    ",
   1076                             (portdata & 0x0001) ? "RX"  : "  " ,
   1077                             (portdata & 0x0002) ? "TX"  : "  " ,
   1078                             (portdata & 0x0080) ? "LI"  : "  " ,
   1079                             (portdata1 & 0x0100)? "LE"  : "  " ,
   1080                             (portdata1 & 0x0004)? "COL" : "   ",
   1081                             (speed == 0) ? "10M  "  :
   1082                             (speed == 1) ? "100M " :
   1083                             (speed == 2) ? "1G   "   :
   1084                             (speed == 3) ? ">=10G" : "    ",
   1085                             (portdata1 & 0x0020) ? "HD"  : "FD" ,
   1086                             led_up_instance, phy_port_map
   1087                            );
   1088                 } else
   1089 #endif
   1090                 {
   1091                     cli_out("%2d %4s %s %s %s %s %s %s %s %s %d:%d\n",
   1092                           port,
   1093                           SOC_PORT_VALID(unit, port) ?
   1094                           SOC_PORT_NAME(unit, port) :"    ",
   1095                           (portdata & 0x0001) ? "RX"  : "  " ,
   1096                           (portdata & 0x0002) ? "TX"  : "  " ,
   1097                           (portdata & 0x0080) ? "LI"  : "  " ,
   1098                           (portdata & 0x0100) ? "LE"  : "  " ,
   1099                           (portdata & 0x0004) ? "COL" : "   ",
   1100                           (portdata & 0x0008) ? "100" : "   ",
   1101                           (portdata & 0x0010) ? "1G"  : "  " ,
   1102                           (portdata & 0x0020) ? "HD"  : "FD" ,
   1103                           led_up_instance, phy_port_map
   1104                          );
   1105                 }
   1106             } else
   1107 #ifdef BCM_TOMAHAWK_SUPPORT
   1108                 if(SOC_IS_TOMAHAWKX(unit)) {
   1109                     cli_out("%2d %4s %s %s %s %s %s %s %s %d:%d\n",
   1110                             port,
   1111                             SOC_PORT_VALID(unit, port) ?
   1112                             SOC_PORT_NAME(unit, port) :"    ",
   1113                             (portdata & 0x0001) ? "RX"  : "  " ,
   1114                             (portdata & 0x0002) ? "TX"  : "  " ,
   1115                             (portdata & 0x0080) ? "LI"  : "  " ,
   1116                             (portdata & 0x0100) ? "LE"  : "  " ,
   1117                             (portdata & 0x0004) ? "COL" : "   ",
   1118                             (portdata & 0x0018) ? "10G" : "   ",
   1119                             (portdata & 0x0020) ? "HD"  : "FD" ,
   1120                             led_up_instance, phy_port_map
   1121                            );
   1122              } else
   1123 #endif /* BCM_TOMAHAWK_SUPPORT */
   1124 #ifdef BCM_TRIDENT_SUPPORT
   1125                 if (SOC_IS_TD_TT(unit)) {
   1126                         int speed = (portdata1 & 0x18) >> 3;
   1127                         cli_out("%2d %4s %s %s %s %s %s %s %s %d:%d\n",
   1128                                 port,
   1129                                 SOC_PORT_VALID(unit, port) ?
   1130                                 SOC_PORT_NAME(unit, port) :"    ",
   1131                                 (portdata  & 0x0001) ? "RX"  : "  " ,
   1132                                 (portdata  & 0x0002) ? "TX"  : "  " ,
   1133                                 (portdata  & 0x0080) ? "LI"  : "  " ,
   1134                                 (portdata1 & 0x0100) ? "LE"  : "  " ,
   1135                                 (portdata1 & 0x0004) ? "COL" : "   ",
   1136                                 (speed == 0) ? "10M  "  :
   1137                                 (speed == 1) ? "100M " :
   1138                                 (speed == 2) ? "1G   "   :
   1139                                 (speed == 3) ? ">=10G" : "    ",
   1140                                 (portdata1 & 0x0020) ? "FD"  : "HD" ,
   1141                                 led_up_instance, phy_port_map
   1142                         );
   1143                  } else
   1144 #endif /* BCM_TRIDENT_SUPPORT */
   1145                  {
   1146                     cli_out("%2d %4s %s %s %s %s %s %s %s %s %d:%d\n",
   1147                             port,
   1148                             SOC_PORT_VALID(unit, port) ?
   1149                             SOC_PORT_NAME(unit, port) :"    ",
   1150                             (portdata & 0x0001) ? "RX"  : "  " ,
   1151                             (portdata & 0x0002) ? "TX"  : "  " ,
   1152                             (portdata & 0x0080) ? "LI"  : "  " ,
   1153                             (portdata & 0x0100) ? "LE"  : "  " ,
   1154                             (portdata & 0x0004) ? "COL" : "   ",
   1155                             (portdata & 0x0008) ? "100" : "   ",
   1156                             (portdata & 0x0010) ? "1G"  : "  " ,
   1157                             (portdata & 0x0020) ? "FD"  : "HD" ,
   1158                             led_up_instance, phy_port_map
   1159                            );
   1160                  }
   1161             }
   1162         } else if (!sal_strcasecmp(c, "start")) {
   1163         int		offset;
   1164 
   1165 #if defined (BCM_CMICX_SUPPORT)
   1166         if (soc_feature(unit, soc_feature_cmicx)) {
   1167 #if CMICX_LED
   1168             int rv = SOC_E_NONE;
   1169 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
   1170             rv = soc_cmicx_led_enable(unit, LED_START);
   1171 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
   1172             if (rv != SOC_E_NONE) {
   1173                 cli_out("Error:Unable to start LED FW\n");
   1174                 return(CMD_FAIL);
   1175             } else {
   1176                 return(CMD_OK);
   1177             }
   1178 #else /* CMICX_LED */
   1179             return(CMD_OK);
   1180 #endif /* CMICX_LED */
   1181         }
   1182 #endif /* BCM_CMICX_SUPPORT */
   1183 
   1184         /* The LED data area should be clear whenever program starts */
   1185 
   1186         soc_pci_write(unit, led_info_cur->ctrl, led_ctrl & ~LC_LED_ENABLE);
   1187 
   1188         for (offset = 0x80; offset < CMIC_LED_DATA_RAM_SIZE; offset++) {
   1189             soc_pci_write(unit,
   1190                     led_info_cur->dram_base + CMIC_LED_REG_SIZE * offset,
   1191                     0);
   1192         }
   1193 
   1194         led_ctrl |= LC_LED_ENABLE;
   1195 
   1196         soc_pci_write(unit, led_info_cur->ctrl, led_ctrl);
   1197 
   1198         if (auto_on && !skip_force_link_check) {
   1199             (void)bcm_link_change(unit, PBMP_PORT_ALL(unit));
   1200         }
   1201 
   1202         return(CMD_OK);
   1203     } else if (!sal_strcasecmp(c, "stop")) {
   1204 
   1205 #if defined (BCM_CMICX_SUPPORT)
   1206         if (soc_feature(unit, soc_feature_cmicx)) {
   1207 #if CMICX_LED
   1208             int rv = SOC_E_NONE;
   1209 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
   1210             rv = soc_cmicx_led_enable(unit, LED_STOP);
   1211 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT || BCM_DNX_SUPPORT */
   1212             if (rv != SOC_E_NONE) {
   1213                 cli_out("Error:Unable to stop LED FW\n");
   1214                 return(CMD_FAIL);
   1215             } else {
   1216                 return(CMD_OK);
   1217             }
   1218 #else /* CMICX_LED */
   1219             return(CMD_OK);
   1220 #endif /* CMICX_LED */
   1221         }
   1222 #endif /* BCM_CMICX_SUPPORT */
   1223 
   1224         led_ctrl &= ~LC_LED_ENABLE;
   1225         soc_pci_write(unit, led_info_cur->ctrl, led_ctrl);
   1226 
   1227         return(CMD_OK);
   1228     } else if (!sal_strcasecmp(c, "load")) {
   1229         /*
   1230          * Try to catch ^C to avoid leaving file open if ^C'd.
   1231          * There are still a number of unlikely race conditions here.
   1232          * Temporarily stop LED processor if it is currently running.
   1233          */
   1234 #ifdef NO_FILEIO
   1235         cli_out("no filesystem\n");
   1236 #else
   1237         led_info_t *led_info_saved;
   1238         led_info_saved = led_info_cur;
   1239         soc_pci_write(unit, led_info_saved->ctrl, led_ctrl & ~LC_LED_ENABLE);
   1240         if (
   1241 #ifndef NO_CTRL_C
   1242                 !setjmp(ctrl_c)
   1243 #else
   1244                 TRUE
   1245 #endif
   1246            ) {
   1247 #ifndef NO_CTRL_C
   1248             sh_push_ctrl_c(&ctrl_c);
   1249 #endif
   1250 
   1251             if ((c = ARG_GET(a)) != NULL) {
   1252                 f = sal_fopen(c, "r");
   1253                 if (!f) {
   1254                     cli_out("%s: Error: Unable to open file: %s\n",
   1255                             ARG_CMD(a), c);
   1256                     rv = CMD_FAIL;
   1257                 } else {
   1258                     rv = ledproc_load_fp(unit, ARG_CMD(a), c,
   1259                             (FILE *)f,led_info_saved);
   1260                     sal_fclose((FILE *)f); /* Cast for un-volatile */
   1261                     f = NULL;
   1262                 }
   1263             } else {
   1264                 cli_out("%s: Error: No file specified\n", ARG_CMD(a));
   1265                 rv = CMD_USAGE;
   1266             }
   1267         } else if (f) {
   1268             sal_fclose((FILE *)f);
   1269             f = NULL;
   1270             rv = CMD_INTR;
   1271         }
   1272         /* Restore LED processor if it was running */
   1273         soc_pci_write(unit, led_info_saved->ctrl, led_ctrl);
   1274 
   1275         if (auto_on && !skip_force_link_check) {
   1276             (void)bcm_link_change(unit, PBMP_PORT_ALL(unit));
   1277         }
   1278 
   1279 #ifndef NO_CTRL_C
   1280         sh_pop_ctrl_c();
   1281 #endif
   1282 #endif /* NO_FILEIO */
   1283     } else if (!sal_strcasecmp(c, "prog")) {
   1284         if (ARG_CUR(a) == NULL) {
   1285             return(CMD_USAGE);
   1286         }
   1287 
   1288         led_ctrl &= ~LC_LED_ENABLE;
   1289         soc_pci_write(unit, led_info_cur->ctrl, led_ctrl);
   1290 
   1291         return ledproc_load_args(unit, a, led_info_cur);
   1292     } else if (!sal_strcasecmp(c, "auto")) {
   1293         int new_auto = 1;
   1294 
   1295         if ((c = ARG_GET(a)) != NULL) {
   1296             if (!sal_strcasecmp(c, "off")) {
   1297                 new_auto = 0;
   1298             } else if (!sal_strcasecmp(c, "on")) {
   1299                 new_auto = 1;
   1300             } else {
   1301                 return CMD_USAGE;
   1302             }
   1303         }
   1304 
   1305         if (new_auto && !auto_on) {
   1306             (void)bcm_linkscan_register(unit, ledproc_linkscan_cb);
   1307         }
   1308 
   1309         if (!new_auto && auto_on) {
   1310             (void)bcm_linkscan_unregister(unit, ledproc_linkscan_cb);
   1311         }
   1312 
   1313         if (new_auto && !skip_force_link_check) {
   1314             (void)bcm_link_change(unit, PBMP_PORT_ALL(unit));
   1315         }
   1316 
   1317     } else if (!sal_strcasecmp(c, "dump")) {
   1318         int		offset, max;
   1319 
   1320         for (max = CMIC_LED_PROGRAM_RAM_SIZE - 1; max >= 0; max--) {
   1321             if (soc_pci_read(unit,
   1322                         led_info_cur->pram_base + CMIC_LED_REG_SIZE * max) != 0) {
   1323                 break;
   1324             }
   1325         }
   1326 
   1327         for (offset = 0; offset <= max; offset++) {
   1328             cli_out(" %02x", soc_pci_read(unit,
   1329                         led_info_cur->pram_base + CMIC_LED_REG_SIZE * offset));
   1330             if ((offset % 16) == 15) {
   1331                 cli_out("\n");
   1332             }
   1333         }
   1334 
   1335         if (offset % 16 != 0) {
   1336             cli_out("\n");
   1337         }
   1338 #ifdef BCM_CMICX_SUPPORT
   1339     } else if (!sal_strcasecmp(c, "setstatus")) {
   1340             if (soc_feature(unit, soc_feature_cmicx)) {
   1341 #if CMICX_LED
   1342 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
   1343                 int rv = SOC_E_NONE;
   1344                 soc_led_port_status_t led_status;
   1345 
   1346                 if ((c = ARG_GET(a)) != NULL) {
   1347                     led_status.port = sal_ctoi(c, 0);
   1348                 }
   1349 
   1350                 if ((c = ARG_GET(a)) != NULL) {
   1351                     led_status.status = sal_ctoi(c, 0);
   1352                 }
   1353                 rv = soc_cmicx_led_status_set(unit, &led_status);
   1354                 if (rv != SOC_E_NONE) {
   1355                     cli_out("Error: Unable to set led status\n");
   1356                     return(CMD_FAIL);
   1357                 }
   1358 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
   1359  #endif /* CMICX_LED */
   1360         } else {
   1361             cli_out("Unsupported LED CLI command\n");
   1362             return(CMD_FAIL);
   1363         }
   1364     } else if (!sal_strcasecmp(c, "accustatus")) {
   1365             if (soc_feature(unit, soc_feature_cmicx)) {
   1366 #if CMICX_LED
   1367 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
   1368                 int rv = SOC_E_NONE, port;
   1369                 soc_led_port_status_t led_status;
   1370 
   1371                 if (!SOC_CONTROL(unit)->led_fw_enabled) {
   1372                     cli_out("LED FW not running\n");
   1373                     return(CMD_FAIL);
   1374                 }
   1375 
   1376                 /* coverity[overrun-local] */
   1377                 PBMP_PORT_ITER(unit, port) {
   1378                     if (soc_feature(unit, soc_feature_logical_port_num)) {
   1379                         led_status.port = SOC_INFO(unit).port_l2p_mapping[port];
   1380                     } else {
   1381                         led_status.port = port;
   1382                     }
   1383 
   1384                     /* Display LED accu_ram bank status for the port */
   1385                     led_status.bank = LED_ACCU_RAM_BANK;
   1386                     rv = soc_cmicx_led_status_get(unit, &led_status);
   1387                     if (rv != SOC_E_NONE) {
   1388                         cli_out("Error: Unable to get LED status\n");
   1389                         return(CMD_FAIL);
   1390                     } else {
   1391                         cli_out("Port %d led accu ram status 0x%x\n", port, led_status.status);
   1392                         continue;
   1393                     }
   1394                 }
   1395 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
   1396  #endif /* CMICX_LED */
   1397         } else {
   1398             cli_out("Unsupported LED CLI command\n");
   1399             return(CMD_FAIL);
   1400         }
   1401 #endif  /* BCM_CMICX_SUPPORT */
   1402     } else {
   1403         return(CMD_USAGE);
   1404     }
   1405 
   1406     return(rv);
   1407 }