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

custom_led.c (9668B)


      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 /******************************************************************************
      9 CMICX LED Interface has two RAM Banks, as shown below, Bank0(ACCUMULATION RAM)
     10 for accumulation of status from ports and Bank1(PATTERN RAM) for writing
     11 LED pattern. Both Bank0 and Bank1 are of 1024x16-bit, each row representing
     12 one port.
     13 
     14          ACCUMULATION RAM (Bank 0)                Pattern RAM (Bank1)
     15          15                         0          15                         0
     16         ------------------------------         -----------------------------
     17 Row 0   |  Port1 status              |         |  Port1 LED Pattern        |
     18         ------------------------------         -----------------------------
     19 Row 1   |  Port2 status              |         |  Port2 LED Pattern        |
     20         ------------------------------         -----------------------------
     21         |                            |         |                           |
     22         ------------------------------         -----------------------------
     23         |                            |         |                           |
     24         ------------------------------         -----------------------------
     25         |                            |         |                           |
     26         ------------------------------         -----------------------------
     27         |                            |         |                           |
     28         ------------------------------         -----------------------------
     29         |                            |         |                           |
     30         ------------------------------         -----------------------------
     31 Row 127 |  Port128 status            |         |  Port128 LED Pattern      |
     32         ------------------------------         -----------------------------
     33 Row 128 |                            |         |                           |
     34         ------------------------------         -----------------------------
     35         |                            |         |                           |
     36         ------------------------------         -----------------------------
     37         |                            |         |                           |
     38         ------------------------------         -----------------------------
     39 Row x   |  Port(x+1) status          |         |  Port(x+1) LED Pattern    |
     40         ------------------------------         -----------------------------
     41         |                            |         |                           |
     42         ------------------------------         -----------------------------
     43         |                            |         |                           |
     44         ------------------------------         -----------------------------
     45 Row 1022|  Port1023 status           |         |  Port1023 LED Pattern     |
     46         ------------------------------         -----------------------------
     47 Row 1023|  Port1024 status           |         |  Port1024 LED Pattern     |
     48         ------------------------------         -----------------------------
     49 
     50 Format of Accumulation RAM:
     51 
     52 
     53 Bits    15:9        8       7         6        5       4:3     2    1    0
     54      ------------------------------------------------------------------------
     55      | Reserved | Link  | Link Up |  Flow  | Duplex | Speed | Col | Tx | Rx |
     56      |          | Enable| Status  | Control|        |       |     |    |    |
     57      ------------------------------------------------------------------------
     58 
     59 The custom handler in this file should read port status, for each port used,
     60 from accumulation ram, and form required LED bit pattern in the Bank1 RAM
     61 (pattern RAM) location corresponding to the port of interest. Note that
     62 physical port numbers may differ from row number of LED RAM Banks. For
     63 Trident3, Physical port numbers spread from 1 to 128 in 128x25G configuration
     64  and corresponding LED rows spread from Row 0 to Row 127.
     65 
     66 There are five LED interfaces in CMICX based devices. Although single
     67 interface can be used to output LED pattern for all ports, it is possible
     68 that more than one interface can be used in the end system, e.g., LEDs for
     69 some ports are connected to one LED interface-0 (i.e LED_CLK and LED_DATA),
     70 while the rest of the ports are connected to LED interface-1. Accordingly,
     71 custom handler MUST fill in start port, end port and width of pattern in the
     72 soc_led_custom_handler_ctrl_t structure passsed to custom handler. The
     73 example custom handler provided in this file has reference code for forming
     74 two different LED patterns. Please refer to these patterns before writing your
     75 own custom handler code.
     76 
     77 The soc_led_custom_handler_ctrl_t structure definition is available in
     78 $SDK/include/shared/cmicfw/cmicx_led_public.h
     79 
     80 soc_led_custom_handler_ctrl_t structure also carries a point to array
     81 port_speed[] of size equal to maximum ports in the system, e.g 128 in Trident3.
     82 This array would have port speed for each port, as per bit mapping defined in
     83 "soc_led_speed_t" in $SDK/include/shared/cmicfw/cmicx_led_public.h file.
     84 
     85 Here is an exception, please keep in mind:
     86 1. For TH3, port status/speed of  xe1 (physical port 258) is located in the 
     87    accumulation entry/speed array  of physical port 259.
     88  */
     89 #include <shared/cmicfw/cmicx_led_public.h>
     90 
     91 #define ACTIVITY_TICKS 2
     92 #define READ_LED_ACCU_DATA(base, port) (*((uint16 *)(base + ((port - 1) * sizeof(uint32)))))
     93 #define WRITE_LED_SEND_DATA(base, port, val)  (*((uint16 *)(base + ((port - 1) * sizeof(uint32)))) = val)
     94 
     95 #define SELECT_BRCM_PATTERN 1
     96 
     97 /*
     98  * Function:
     99  *      custom_led_handler
    100  * Purpose:
    101  *      Timer event handler to accumulate, process and transmit led status
    102  * Parameters:
    103  *      param - parameter added while registering the timer event.
    104  * Returns:
    105  *      0 on success
    106  *      Error code on failure
    107  */
    108 void custom_led_handler(soc_led_custom_handler_ctrl_t *ctrl, uint32 activity_count)
    109 {
    110     unsigned short accu_val = 0, send_val = 0;
    111     unsigned short port, intf;
    112 
    113 #if SELECT_BRCM_PATTERN
    114     /* Pattern for Broadcom SVK with 128x25G configuration */
    115     /* Port 1 to 64 connected to LED interface 0 */
    116     /* Port 65 to 128 connected to LED interface 1 */
    117     /* Pattern: b[1-0] - Link status: 10 - UP, 00 - DOWN */
    118     /*          b[3-2] - Activity: 01 - Tx/Rx activity */
    119 
    120     /* Physical port numbers to be used */
    121     for(port = 1; port <= 128; port++) {
    122         /* Read value from led_ram bank0 */
    123         accu_val = READ_LED_ACCU_DATA(ctrl->accu_ram_base, port);
    124 
    125         send_val = 0x0; /* Default Off - b'0000 */
    126 
    127         if (accu_val & LED_OUTPUT_LINK_UP) {
    128             send_val = 0x2;
    129         }
    130 
    131         if ((accu_val & LED_OUTPUT_LINK_UP) &&
    132             ((accu_val & LED_OUTPUT_RX) || (accu_val & LED_OUTPUT_TX)) &&
    133              (activity_count & ACTIVITY_TICKS)) {
    134             send_val |= (0x1 << 2);
    135         }
    136 
    137         /* Write value to led_ram bank1 */
    138         WRITE_LED_SEND_DATA(ctrl->pat_ram_base, port, send_val);
    139     } /* for */
    140 
    141     /* Send the pattern over LED interface 0 for ports 1 - 64*/
    142     ctrl->intf_ctrl[0].valid = 1;
    143     ctrl->intf_ctrl[0].start_row = 0;
    144     ctrl->intf_ctrl[0].end_row = 63;
    145     ctrl->intf_ctrl[0].pat_width = 4;
    146 
    147     ctrl->intf_ctrl[1].valid = 1;
    148     ctrl->intf_ctrl[1].start_row = 64;
    149     ctrl->intf_ctrl[1].end_row = 127;
    150     ctrl->intf_ctrl[1].pat_width = 4;
    151 
    152     /* Invalidate rest of the interfaces */
    153     ctrl->intf_ctrl[2].valid = 0;
    154     ctrl->intf_ctrl[3].valid = 0;
    155     ctrl->intf_ctrl[4].valid = 0;
    156 
    157 #else
    158     /* Alternate reference pattern */
    159     /* For every port toggle between 3'b111 and
    160        100/011/010/001/000 based on port speed */
    161     /* Send pattern over single LED interface */
    162     for(port = 1; port <= 128; port++) {
    163         /* Read value from led_ram bank0 */
    164         accu_val = READ_LED_ACCU_DATA(ctrl->accu_ram_base, port);
    165 
    166         send_val = 0x7; /* Default Off - b'111 */
    167 
    168         if (accu_val & LED_OUTPUT_LINK_UP) {
    169 
    170             switch(ctrl->port_speed[port-1]) {
    171                 case LED_SPD_10G:
    172                     send_val = 0x0; /* b'000 */
    173                     break;
    174                 case LED_SPD_25G:
    175                     send_val = 0x1; /* b'001 */
    176                     break;
    177                 case LED_SPD_40G:
    178                     send_val = 0x2; /* b'010 */
    179                     break;
    180                 case LED_SPD_50G:
    181                     send_val = 0x3; /* b'011 */
    182                     break;
    183                 case LED_SPD_100G:
    184                     send_val = 0x4; /* b'100 */
    185                     break;
    186                 case LED_SPD_200G:
    187                     send_val = 0x5; /* b'101 */
    188                     break;
    189                 case LED_SPD_400G:
    190                     send_val = 0x6; /* b'110 */ 
    191                     break;
    192                 default:
    193                     send_val = 0x7; /* b'111 */
    194                     break;
    195             }
    196         }
    197 
    198         if (((accu_val & LED_OUTPUT_RX) || (accu_val & LED_OUTPUT_TX)) &&
    199             (activity_count & ACTIVITY_TICKS)) {
    200             send_val = 0x7;
    201         }
    202 
    203         /* Write value to led_ram bank1 */
    204         WRITE_LED_SEND_DATA(ctrl->pat_ram_base, port, send_val);
    205     } /* for */
    206 
    207     /* Send the pattern over LED interface 0 */
    208     ctrl->intf_ctrl[0].valid = 1;
    209     ctrl->intf_ctrl[0].start_row = 0;
    210     ctrl->intf_ctrl[0].end_row = 127;
    211     ctrl->intf_ctrl[0].pat_width = 3;
    212 
    213     /* Invalidate rest of the interfaces */
    214     ctrl->intf_ctrl[1].valid = 0;
    215     ctrl->intf_ctrl[2].valid = 0;
    216     ctrl->intf_ctrl[3].valid = 0;
    217     ctrl->intf_ctrl[4].valid = 0;
    218 #endif
    219     return;
    220 }