/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
   All Rights Reserved

Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:

   As a special exception, the copyright holders of this software give
   you permission to link this software with independent modules, and
   to copy and distribute the resulting executable under terms of your
   choice, provided that you also meet, for each linked independent
   module, the terms and conditions of the license of that module.
   An independent module is a module which is not derived from this
   software.  The special exception does not apply to any modifications
   of the software.

Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.

:>
*/

#include <bcmos_system.h>
#include <bcmolt_api.h>
#include <bcmolt_model_types.h>
#include <bcm_dev_log.h>
#include <bcmolt_board.h>
#include "omon.h"
#include "bcmolt_utils.h"
/* These macros need to be defined before the following include. */
#define BCM_I2C_DEV_ADDR_START typedef enum {
#define BCM_I2C_DEV_ADDR(name, desc, val) name = val,
#define BCM_I2C_DEV_ADDR_END } bcm_i2c_dev_addr;
#include "bcmolt_i2c_devs_addr.h"


/* Fixed sample delay exceeds the sum of the maximum grant size and a worst case
   retrieval time based on various optics modules' data sheets */
#define OMON_FIXED_SAMPLE_DELAY_US      12000
#define SFF_8472_IDENTIFIER_ADDR        0x00    /* SFP and XFP Identifier byte*/
#define SFF_8077i_IDENTIFIER_ADDR       128     /* XFP Identifier byte */
#define SFF_8472_RX_POWER_ADDR          104     /* SFP offeset into A2 */
#define SFF_8077i_RX_POWER_ADDR         104     /* XFP byte 104/105 into A0  (yes A0) */
#define SFF_8077i_VENDOR_NAME_ADDR      148     /* XFP bytes 163-148 into A0   */
#define SFF_8077i_VENDOR_NAME_LEN       16      /* XFP name length  */
#define SFF_8077i_VENDOR_PN_ADDR        168     /* XFP bytes 183-168 into A0   */
#define SFF_8077i_VENDOR_PN_LEN         16      /* XFP part number length   */
#define SFF_8077i_VENDOR_REV_ADDR       184     /* XFP bytes 185-184 into A0   */
#define SFF_8077i_VENDOR_REV_LEN        2       /* XFP revision len   */
#define SFF_8077i_VENDOR_SN_ADDR        196     /* XFP bytes 211-196 into A0   */
#define SFF_8077i_VENDOR_SN_LEN         16      /* XFP serial number len   */
#define OMON_TASK_MSG_Q_SIZE            16      /* allow one message per port */
#define SFF_PAGE_ADDR1                  0       /* use SFP_I2C_ADDR1 for I2C read A0 */
#define SFF_PAGE_ADDR2                  1       /* use SFP_I2C_ADDR2 for 12C read A2 */

#define SFF_8472_VENDOR_NAME_ADDR      20      /* SFP bytes 20-35 into A0   */
#define SFF_8472_VENDOR_NAME_LEN       16      /* SFP name length  */
#define SFF_8472_VENDOR_OUI_ADDR       37      /* SFP bytes 37-39 into A0   */
#define SFF_8472_VENDOR_OUI_LEN        3       /* SFP oui length  */
#define SFF_8472_VENDOR_PN_ADDR        40      /* SFP bytes 40-55 into A0   */
#define SFF_8472_VENDOR_PN_LEN         16      /* SFP part number length   */
#define SFF_8472_VENDOR_REV_ADDR       56      /* SFP bytes 56-59 into A0   */
#define SFF_8472_VENDOR_REV_LEN        4       /* SFP revision len   */
#define SFF_8472_VENDOR_SN_ADDR        68      /* SFP bytes 68-83 into A0   */
#define SFF_8472_VENDOR_SN_LEN         16      /* SFP serial number len   */
#define SFF_8472_VENDOR_SFF_ADDR       94      /* SFP bytes 94 into A0   */
#define SFF_8472_VENDOR_SFF_LEN        1       /* SFP SFF-8472 Compliance revision len   */

#define SFF_8472_DIAG_MON_ADDR         92      /* SFP bytes 92 into A0   */
#define SFF_8472_ENHANCED_OPT_ADDR     93      /* SFP bytes 93 into A0   */
#define SFF_8472_TEMPERATURE_ADDR      96      /* SFP bytes 96 into A0   */
#define SFF_8472_DIAG_MON_LEN          1       /* SFP SFF-8472 Diagnostic Monitoring Type len   */

/* Table 32 5.2 Identifier values SFF8077i*/
#define SFF_IDENTIFIER_SFP  0x03
#define SFF_IDENTIFIER_XFP  0x06

typedef uint32_t omon_rssi_value;


/* Uniquely identifies specific EPON links under management by this
   application */
typedef struct
{
    bcmolt_devid device_id;
    bcmolt_epon_ni epon_ni;
    bcmos_mac_address mac_address;
} omon_link_key;


typedef struct
{
    uint32_t  caddr;    /* I2C switch control address */
    uint32_t  sctrl;    /* I2C switch control command value */
} i2c_coords;


typedef struct
{
    bcmos_msg os_msg;
    omon_link_key link_key;
    uint16_t trigger_width_ns;
    uint16_t trigger_delay_ns;
    uint16_t sample_period_us;
    bcmcli_session *session;
    bcmolt_epon_llid llid;
    uint8_t scan_mode;
} omon_task_msg;


static dev_log_id omon_log_id = DEV_LOG_INVALID_ID;
static bcmos_task omon_task;
static bcmos_bool is_running = BCMOS_FALSE;


/*******************************************************************************
 * BCM968620 platform dependent I2C access
 ******************************************************************************/


uint8_t bcm968620_client_switchctrl_sfp[16][2] =
{
    {   0x72,     0x80, },
    {   0x72,     0x40, },
    {   0x72,     0x20, },
    {   0x72,     0x10, },
    {   0x72,      0x8, },
    {   0x72,      0x4, },
    {   0x72,      0x2, },
    {   0x72,      0x1, },
    {   0x73,     0x10, },
    {   0x73,     0x20, },
    {   0x73,     0x40, },
    {   0x73,     0x80, },
    {   0x73,      0x1, },
    {   0x73,      0x2, },
    {   0x73,      0x4, },
    {   0x73,      0x8, },
};


uint8_t bcm968620_client_switchctrl_xfp[8][2] =
{
    /* caddr,    sctrl */
    {   0x72,      0x8, },
    {   0x72,      0x4, },
    {   0x72,      0x2, },
    {   0x72,      0x1, },
    {   0x73,     0x10, },
    {   0x73,     0x20, },
    {   0x73,     0x40, },
    {   0x73,     0x80, },
};

static bcmos_bool omon_is_epon_ni_valid(bcmolt_epon_ni epon)
{
    bcmolt_system_mode system_mode;

    bcmolt_system_mode_get(current_device, &system_mode);

    switch (system_mode)
    {
        case BCMOLT_SYSTEM_MODE_EPON__16_X:
            return epon < 16;
        case BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA:
        case BCMOLT_SYSTEM_MODE_EPON__8_X_10_G:
        case BCMOLT_SYSTEM_MODE_EPON__8_X:
            return epon < 8;
        case BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA:
        case BCMOLT_SYSTEM_MODE_EPON__4_X_10_G:
        case BCMOLT_SYSTEM_MODE_EPON__4_X:
            return epon < 4;
        case BCMOLT_SYSTEM_MODE_EPON__2_X_10_G:
            return epon < 2;
        default:
            return BCMOS_FALSE;
    }
}

static bcmos_bool trx_id_from_epon_ni(bcmolt_epon_ni epon, uint8_t *trx_id)
{
    static const uint8_t epon_4x[4] = { 2, 3, 6, 7 };
    static const uint8_t epon_2x_10g[2] = { 3, 4 };
    bcmolt_system_mode system_mode;

    bcmolt_system_mode_get(current_device, &system_mode);

    switch (system_mode)
    {
        case BCMOLT_SYSTEM_MODE_EPON__16_X:
        case BCMOLT_SYSTEM_MODE_EPON__8_X:
        case BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA:
        case BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA:
        case BCMOLT_SYSTEM_MODE_EPON__8_X_10_G:
        case BCMOLT_SYSTEM_MODE_EPON__4_X_10_G:
            *trx_id = (uint8_t)epon;
            return BCMOS_TRUE;
        case BCMOLT_SYSTEM_MODE_EPON__4_X:
            *trx_id = epon_4x[epon];
            return BCMOS_TRUE;
        case BCMOLT_SYSTEM_MODE_EPON__2_X_10_G:
            *trx_id = epon_2x_10g[epon];
            return BCMOS_TRUE;
        default:
            *trx_id = (uint8_t)-1;
            return BCMOS_FALSE;
    }
}

static char * bcmolt_get_scan_result(bcmolt_rogue_scan_status status)
{
    switch (status)
    {
        case BCMOLT_ROGUE_SCAN_STATUS_COMPLETE:
            return "OK: EPON ROGUE SCAN IS COMPLETE";
        case BCMOLT_ROGUE_SCAN_STATUS_LLID_STATE_IS_BAD:
            return "FAIL: REQUESTED LLID IS IN USE";
        case BCMOLT_ROGUE_SCAN_STATUS_SCAN_ERR_INTERNAL:
            return "FAIL: SCAN HAD AN INTERNAL SW ERROR";
        case BCMOLT_ROGUE_SCAN_STATUS_SCAN_ERR_NORES:
            return "FAIL: NO RESOURCES AVAILABLE";
        case BCMOLT_ROGUE_SCAN_STATUS_LLID_IS_OOR:
            return "FAIL: REQUESTED LLID IS OUT OF RANGE";
        default:
            return "OK: BCMOLT_ROGUE_SCAN_STATUS_COMPLETE";
    }
}

/**
 * \brief Get I2C address
 *
 * This function returns the I2C mux target address for the given link_key
 * object.
 *
 * \param epon_ni EPON port index
 * \param coords I2C mux target container
 *
 * \return
 * None
 */
static
void omon_get_i2c_coords(uint8_t trx_id, i2c_coords* coords)
{
    bcmolt_system_mode system_mode;

    bcmolt_system_mode_get(0, &system_mode);

    if (system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA)
    {
        coords->caddr  = bcm968620_client_switchctrl_xfp[trx_id][0];
        coords->sctrl  = bcm968620_client_switchctrl_xfp[trx_id][1];
    }
    else
    {
        coords->caddr  = bcm968620_client_switchctrl_sfp[trx_id][0];
        coords->sctrl  = bcm968620_client_switchctrl_sfp[trx_id][1];
    }
} /* omon_get_i2c_coords */


/**
 * \brief Configure I2C mux
 *
 * This function configures the I2C mux to target the correct optics module for
 * the currently executing RSSI measurement.
 *
 * \param epon_ni EPON port index
 *
 * \return
 * BCM_ERR_OK if successful, error code if not
 */
static
bcmos_errno omon_platform_configure_i2c(uint8_t trx_id, uint8_t page)
{

     i2c_coords coords;
     bcmos_errno rc;

     omon_get_i2c_coords(trx_id, &coords);

     rc = bcm_board_dev_change(coords.caddr);
     if (rc != BCM_ERR_OK)
     {
          BCM_LOG(WARNING, omon_log_id,
                  "bcm_board_dev_change(%u) failed\n", coords.caddr);
     }
     else
     {
         rc = bcm_board_switch_write(coords.sctrl);
         if (rc != BCM_ERR_OK)
         {
              BCM_LOG(WARNING, omon_log_id,
                      "bcm_board_switch_write(%u) failed\n", coords.sctrl);
         }
         else
         {
             if (page == SFF_PAGE_ADDR1)
             {
                 rc = bcm_board_dev_change(SFP_I2C_ADDR1);
             }
             else
             {   // SFF_PAGE_ADDR2
                 rc = bcm_board_dev_change(SFP_I2C_ADDR2);
             }
             if (rc != BCM_ERR_OK)
             {
                 BCM_LOG(WARNING, omon_log_id,
                           "bcm_board_dev_change(%u) failed\n", (SFP_I2C_ADDR1+page));
             }
         }
     }
     return rc;

} /* omon_platform_configure_i2c */


/**
 * \brief Read Manufacturing data from Optic Module
 *
 * This function reads the XFP Tranceiver Data (according to
 * SFF8077i for an XFP) from an optics module. The result is
 * displayed for this sample code.
 *
 * \param epon_ni EPON NI to take measurement
 *
 * \return
 * BCM_ERR_OK if successful, error code if not
 */
static
bcmos_errno omon_trx_status_read(bcmolt_epon_ni epon_ni, bcmcli_session *session)
{
    uint32_t sff_identifier = 1;
    bcmos_errno rc = BCM_ERR_OK;
    uint8_t i;

    // 80771 XFP Specific stuff
    uint32_t raw_vendorId_8077i;
    uint8_t vendorId_8077i[SFF_8077i_VENDOR_NAME_LEN+1];
    uint32_t raw_vendorPn_8077i;
    uint8_t vendorPn_8077i[SFF_8077i_VENDOR_PN_LEN+1];
    uint32_t raw_vendorSn_8077i;
    uint8_t vendorSn_8077i[SFF_8077i_VENDOR_SN_LEN+1];
    uint32_t raw_vendorRev_8077i;
    uint8_t vendorRev_8077i[SFF_8077i_VENDOR_REV_LEN+1];

    memset(&vendorId_8077i, 0, sizeof(vendorId_8077i));
    memset(&vendorPn_8077i, 0, sizeof(vendorPn_8077i));
    memset(&vendorSn_8077i, 0, sizeof(vendorSn_8077i));
    memset(&vendorRev_8077i, 0, sizeof(vendorRev_8077i));

    // 8472 SFP Specific stuff
    uint32_t raw_vendorId_8472;
    uint8_t vendorId_8472[SFF_8472_VENDOR_NAME_LEN+1];
    uint32_t raw_vendorPn_8472;
    uint8_t vendorPn_8472[SFF_8472_VENDOR_PN_LEN+1];
    uint32_t raw_vendorSn_8472;
    uint8_t vendorSn_8472[SFF_8472_VENDOR_SN_LEN+1];
    uint32_t raw_vendorRev_8472;
    uint8_t vendorRev_8472[SFF_8472_VENDOR_REV_LEN+1];
    uint32_t raw_vendorSff_8472;
    uint8_t vendorSff_8472[SFF_8472_VENDOR_SFF_LEN+1];
    uint32_t raw_vendorOui_8472;
    uint8_t vendorOui_8472[SFF_8472_VENDOR_OUI_LEN+1];
    uint32_t raw_diagMon_8472;
    uint8_t diagMon_8472 = 0;
    uint32_t raw_enhancedOpt_8472;
    uint8_t enhancedOpt_8472 = 0;

    memset(&vendorId_8472, 0, sizeof(vendorId_8472));
    memset(&vendorPn_8472, 0, sizeof(vendorPn_8472));
    memset(&vendorSn_8472, 0, sizeof(vendorSn_8472));
    memset(&vendorRev_8472, 0, sizeof(vendorRev_8472));
    memset(&vendorSff_8472, 0, sizeof(vendorSff_8472));
    memset(&vendorOui_8472, 0, sizeof(vendorOui_8472));

    uint8_t* tmpresult;
    int16_t temp_result = 0;
    uint32_t raw_temp_result = 0;

    uint8_t trx_id;

    if ( ! trx_id_from_epon_ni(epon_ni, &trx_id) )
    {
        BCM_LOG(ERROR, omon_log_id,
                "TRX Id is invalid for EPON NI %d \n", epon_ni);
        return BCM_ERR_RANGE;
    }

    char *pSfpType;

    pSfpType = "UNKN";


    // Check for transevier presence
    if ( (rc = omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR1)) == BCM_ERR_OK)
    {
        /* Read module identifier */
        if ( (rc = bcm_board_dev_read(8, SFF_8472_IDENTIFIER_ADDR, &sff_identifier)) == BCM_ERR_OK)
        {
            switch (sff_identifier & 0x000F)
            {
                case SFF_IDENTIFIER_SFP:
                    pSfpType = "SFP\0";
                    // Read the vendor Id
                    for (i=0; i<SFF_8472_VENDOR_NAME_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_NAME_ADDR+i, &raw_vendorId_8472);
                        vendorId_8472[i] = (uint8_t)raw_vendorId_8472;
                    }

                    // Read the part Number, serial number, SFF revision, and Revision
                    for (i=0; i<SFF_8472_VENDOR_PN_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_PN_ADDR+i, &raw_vendorPn_8472);
                        vendorPn_8472[i] = (uint8_t)raw_vendorPn_8472;
                    }

                    for (i=0; i<SFF_8472_VENDOR_SN_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_SN_ADDR+i, &raw_vendorSn_8472);
                        vendorSn_8472[i] = (uint8_t)raw_vendorSn_8472;
                    }

                    for (i=0; i<SFF_8472_VENDOR_REV_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_REV_ADDR+i, &raw_vendorRev_8472);
                        vendorRev_8472[i] = (uint8_t)raw_vendorRev_8472;
                    }

                    for (i=0; i<SFF_8472_VENDOR_SFF_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_SFF_ADDR+i, &raw_vendorSff_8472);
                        vendorSff_8472[i] = (uint8_t)raw_vendorSff_8472;
                    }
                    for (i=0; i<SFF_8472_VENDOR_OUI_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_OUI_ADDR+i, &raw_vendorOui_8472);
                        vendorOui_8472[i] = (uint8_t)raw_vendorOui_8472;
                    }

                    rc = rc | bcm_board_dev_read(8, SFF_8472_DIAG_MON_ADDR, &raw_diagMon_8472);
                    diagMon_8472 = (uint8_t)raw_diagMon_8472;

                    rc = rc | bcm_board_dev_read(8, SFF_8472_ENHANCED_OPT_ADDR, &raw_enhancedOpt_8472);
                    enhancedOpt_8472 = (uint8_t)raw_enhancedOpt_8472;

                    // Shift to A2
                    rc = rc | omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR2);
                    rc = rc | bcm_board_dev_read(16, SFF_8472_TEMPERATURE_ADDR, &raw_temp_result);

                    tmpresult = (uint8_t*)(&raw_temp_result);

                    temp_result = tmpresult[3];
                    temp_result = (temp_result << 8) | tmpresult[2];

                    break;

                case SFF_IDENTIFIER_XFP:

                    pSfpType = "XFP\0";
                    // Read the vendor Id
                    for (i=0; i<SFF_8077i_VENDOR_NAME_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_NAME_ADDR+i, &raw_vendorId_8077i);
                        vendorId_8077i[i] = (uint8_t)raw_vendorId_8077i;
                    }

                    // Read the part Number, SN, and Revision
                    for (i=0; i<SFF_8077i_VENDOR_PN_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_PN_ADDR+i, &raw_vendorPn_8077i);
                        vendorPn_8077i[i] = (uint8_t)raw_vendorPn_8077i;
                    }

                    for (i=0; i<SFF_8077i_VENDOR_SN_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_SN_ADDR+i, &raw_vendorSn_8077i);
                        vendorSn_8077i[i] = (uint8_t)raw_vendorSn_8077i;
                    }

                    for (i=0; i<SFF_8077i_VENDOR_REV_LEN; i++)
                    {
                        rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_REV_ADDR+i, &raw_vendorRev_8077i);
                        vendorRev_8077i[i] = (uint8_t)raw_vendorRev_8077i;
                    }

                    break;
                default:
                    rc = BCM_ERR_NODEV;
                    break;
            }
        }
        else
        {
            BCM_LOG(ERROR, omon_log_id,
                    "TRX Could not read device : SFF_8472_IDENTIFIER_ADDR for PON %d rc %d (%s)\n",
                    epon_ni, rc, bcmos_strerror(rc));
        }
    }
    else
    {
        BCM_LOG(ERROR, omon_log_id,
                "TRX Could not configure platform : SFF_PAGE_ADDR1 for PON %d rc %d (%s)\n",
                epon_ni, rc, bcmos_strerror(rc));
        rc = BCM_ERR_NODEV;
    }


    if (rc == BCM_ERR_OK)
    {
        if ( (sff_identifier & 0x000F) == SFF_IDENTIFIER_XFP)
        {
        bcmcli_session_print(session,
                             "\n[OMON] %s Tranceiver is present on PON %d\r\n"
                             "  [OMON] Trx Vendor Id is: %s\r\n "
                             " [OMON] Vendor Part Number: %s\r\n "
                             " [OMON] Vendor Serial Number: %s\r\n "
                             " [OMON] Vendor Revision: %s\r\n ",
                                 pSfpType, epon_ni, vendorId_8077i,
                                 vendorPn_8077i, vendorSn_8077i, vendorRev_8077i);
        }
        else
        {
            // SFP stuff
            bcmcli_session_print(session,
                                 "\n[OMON] %s Tranceiver is present on PON %d\r\n"
                                 "  [OMON] Trx Vendor Id is: %s\r\n "
                                 " [OMON] Vendor Part Number: %s\r\n "
                                 " [OMON] Vendor Serial Number: %s\r\n "
                                 " [OMON] Vendor Revision: %s\r\n "
                                 " [OMON] Vendor OUI: %s\r\n "
                                 " [OMON] Transceiver Temperature: %dC\r\n "
                                 " [OMON] Enhanced Options SFF-8472 Byte 93: %x\r\n "
                                 " [OMON] Diagnostic Monitor Type SFF-8472 Byte 92: %x\r\n ",
                                 pSfpType, epon_ni, vendorId_8472,
                                 vendorPn_8472, vendorSn_8472, vendorRev_8472, vendorOui_8472,
                                 temp_result/256, enhancedOpt_8472, diagMon_8472 );
        }
    }

    return rc;
} /* omon_rssi_read */

/**
 * \brief Read RSSI results from I2C
 *
 * This function reads the RX Power Measurement (SFF8472 for an
 * SFP and SFF8077i for an XFP) from an optics module. The
 * result is stored in the global omon_state.
 *
 * \param epon_ni EPON NI to take measurement
 * \param rssi_value Returned RSSI value if successful
 *
 * \return
 * BCM_ERR_OK if successful, error code if not
 */
static
bcmos_errno omon_rssi_read(bcmolt_epon_ni epon_ni, uint32_t *rssi_value)
{
    uint32_t raw_rssi_result = 0;
    uint32_t sff_identifier = 1;
    uint8_t trx_id;
    uint32_t rssi_result = 0;
    bcmos_errno rc = BCM_ERR_OK;
    uint8_t* result;

    if ( ! trx_id_from_epon_ni(epon_ni, &trx_id) )
    {
        BCM_LOG(ERROR, omon_log_id,
                "TRX Id is invalid for EPON NI %d \n", epon_ni);
        return BCM_ERR_RANGE;
    }

    // Check for transevier presence
    if (bcm_board_trx_present(trx_id) == BCM_ERR_OK)
    {
        rc = omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR1);
        /* Read module identifier */

        if (rc == BCM_ERR_OK)
        {
            /* Read module identifier */
            rc = bcm_board_dev_read(8, SFF_8472_IDENTIFIER_ADDR, &sff_identifier);

            if (rc == BCM_ERR_OK)
            {
                result = (uint8_t*)(&raw_rssi_result);

                switch (sff_identifier & 0x000F)
                {
                    case SFF_IDENTIFIER_SFP:
                        rc = omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR2);
                        if (rc == BCM_ERR_OK)
                        {
                            rc = bcm_board_dev_read(16, SFF_8472_RX_POWER_ADDR, &raw_rssi_result);
                        }
                        break;
                    case SFF_IDENTIFIER_XFP:

                        rc = bcm_board_dev_read(16, SFF_8077i_RX_POWER_ADDR, &raw_rssi_result);

                        break;
                    default:
                        rc = BCM_ERR_NODEV;
                        break;
                }

                if (rc == BCM_ERR_OK)
                {
                    rssi_result = result[3];
                    rssi_result = (rssi_result << 8) | result[2];

                    *rssi_value = rssi_result;

                }
            }
            else
            {
                BCM_LOG(ERROR, omon_log_id,
                        "TRX Could not read device : SFF_8472_IDENTIFIER_ADDR for PON %d rc %d (%s)\n",
                        epon_ni, rc, bcmos_strerror(rc));
                rc = BCM_ERR_IO;
            }
        }
        else
        {
            BCM_LOG(ERROR, omon_log_id,
                    "TRX Could not read platform : SFF_PAGE_ADDR1 for PON %d rc %d (%s)\n",
                    epon_ni, rc, bcmos_strerror(rc));
            rc = BCM_ERR_IO;
        }
    }
    else
    {
        rc = BCM_ERR_NODEV;
    }

    return rc;
} /* omon_rssi_read */


/*******************************************************************************
 * Platform independent RSSI measurement
 ******************************************************************************/

/**
 * \brief Read XFP/SFP Data from Transceiver Module1
 *
 * This function reads the manufacturing data from the SFP
 * module via I2C.
 *
 * \param link_key EPON NI
 *
 * \return
 * None
 */
static
void omon_trx_status_initiate(bcmcli_session *session,
                                     omon_link_key *link_key)
{

    bcmos_errno rc;

    /* Perform the I2C operations specified in SFF-8472 (SFP)/SFF-8077i (XFP) to
       retrieve the pmanufacturer data from the optics module. */

    if (! omon_is_epon_ni_valid(link_key->epon_ni))
    {
        BCM_LOG(ERROR, omon_log_id,
                "[OMON] TRX Status: epon_ni of (%d) is out of range for platform\n", link_key->epon_ni);
        return ;
    }
    // Check for transceiver presence

    uint8_t trx_id;

    if ( ! trx_id_from_epon_ni(link_key->epon_ni, &trx_id) )
    {
        BCM_LOG(ERROR, omon_log_id,
                "[OMON] TRX Id is invalid for EPON NI %d \n", link_key->epon_ni);
        return;
    }

    rc = bcm_board_trx_present(trx_id);

    if (rc == BCM_ERR_NODEV)
    {
        bcmcli_session_print(session,
                "[OMON] TRX Status: Trx_id %d Not Present on PON %d\r\n ", trx_id, link_key->epon_ni);
        return;
    }

    rc = omon_trx_status_read(trx_id, session);

    if (rc != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, omon_log_id,
                "[OMON] Issue TRX Status: Read operation failed with rc %d (%s)\n",
                rc, bcmos_strerror(rc));
        return;
    }

    /* Notify external host code of the outcome through an optional callback,
       defaulting to output in the CLI session where the command was initiated
       if no callback is supplied. */

    bcmcli_session_print(session,
                         "\n[OMON] TRX Status: Data on PON %d Complete\r\n", link_key->epon_ni);
}
/**
 * \brief Read RSSI Measurement Result from Transceiver Module
 *
 * This function reads the stored RSSI measurement from the
 * XFP/SFP module via I2C.
 *
 * \param link_key EPON NI
 *
 * \return
 * None
 */
static
void omon_rssi_read_initiate(bcmcli_session *session,
                                     omon_link_key *link_key)
{
    uint32_t rssi_value = 0;
    bcmos_errno rc;

    if (! omon_is_epon_ni_valid(link_key->epon_ni))
    {
        BCM_LOG(ERROR, omon_log_id,
                "[OMON] Rssi Read: epon_ni of (%d) is out of range for platform\n", link_key->epon_ni);
        return ;
    }

    /* Perform the I2C operations specified in SFF-8472 (SFP)/SFF-8077i (XFP) to
       retrieve the power measurements from the optics module. */
    rc = omon_rssi_read(link_key->epon_ni, &rssi_value);

    if (rc == BCM_ERR_NODEV)
    {
        bcmcli_session_print(session,
                "[OMON] Rssi Read: TRX Not Present on PON %d\r\n ", link_key->epon_ni);
        return;
    }

    if (rc == BCM_ERR_IO)
    {
        bcmcli_session_print(session,
            "[OMON] Rssi Read: Could not read device for PON %d \n",link_key->epon_ni);
        return;
    }

    if (rc != BCM_ERR_OK)
    {
        bcmcli_session_print(session,
                "Issue RSSI Read operation failed with rc %d (%s)\n",
                rc, bcmos_strerror(rc));
        return;
    }
    /* Notify external host code of the outcome through an optional callback,
       defaulting to output in the CLI session where the command was initiated
       if no callback is supplied. */

    bcmcli_session_print(session,
            "[OMON] RSSI Read RX Power: Pon_ni=%d rx power %d.%duW\r\n",
            link_key->epon_ni,
            rssi_value/10,
            rssi_value%10);

    bcmcli_session_print(session,
                         "\n[OMON] RSSI Read on PON %d Complete\r\n",
                         link_key->epon_ni);
}
/*omon_rssi_read_initiate*/


/**
 * \brief Request Maple Firmware to run the Rogue ONU LLID scan.
 *
 * This function sends an API message to the OLT to run a scan
 * on a specific EPON LLID or across all LLIDs in the PON.
 * Results are returned upon completion. Rogue LLIDs are marked
 * and quarentined for the host to examine.
 *
 * \param link_key EPON link information
 * \param epopn_llid  Specific LLID to scan
 * \param scan_mode   Specifies a single LLID or All.
 *
 * \return
 * None
 */

static
void omon_run_rogue_llid_scan(bcmcli_session *session,
                                     omon_link_key *link_key,
                                     bcmolt_epon_llid llid,
                                     uint8_t scan_mode)
{
    const bcmolt_epon_ni_key ni_key = { .epon_ni = link_key->epon_ni };
    bcmolt_epon_ni_rogue_llid_scan issue_llid_scan_op;
    bcmos_errno rc = BCM_ERR_OK;

    /* Perform an API operation directing the Maple firmware to issue an bcmolt_epon_ni_issue_rogue_rx_power
       RSSI grant to the specified EPON link. BCMOLT_EPON_NI_OPER_ID_ISSUE_ROGUE_RX_POWER*/

    BCMOLT_OPER_INIT(&issue_llid_scan_op, epon_ni, rogue_llid_scan , ni_key);
    BCMOLT_OPER_PROP_SET(&issue_llid_scan_op, epon_ni, rogue_llid_scan, mode, scan_mode);
    BCMOLT_OPER_PROP_SET(&issue_llid_scan_op, epon_ni, rogue_llid_scan, llid, llid);

    BCM_LOG_CALLER_FMT(INFO, omon_log_id,
            "Issue Rogue Scan Operation for LLID 0x%x, Pon_ni=%d\r\n", llid, link_key->epon_ni);

    rc = bcmolt_oper_submit(link_key->device_id, &issue_llid_scan_op.hdr);

    if (rc != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, omon_log_id,
                "Rogue Scan Operation Failed with rc %d (%s)\n",
                rc, bcmos_strerror(rc));

        return;
    }
}/*omon_run_rogue_llid_scan*/

/**
 * \brief Execute RSSI measurement
 *
 * This function sends an API message to the OLT to issue an RSSI grant.  It
 * then reads back the results via I2C. Set grant_length_tq to 0 to retreive the
 * RSSI value without issuing the strobe command to the OLT.
 *
 * \param link_key EPON RSSI link information
 * \param grant_length_tq Size of the RSSI grant
 * \param start_offset Strobe offset from start of the RSSI grant
 * \param end_offset Strobe offset from the end of the RSSI grant
 *
 * \return
 * None
 */
static
void omon_rssi_measurement_initiate(bcmcli_session *session,
                                    omon_link_key *link_key,
                                    uint16_t trigger_width_tq,
                                    uint16_t trigger_delay_tq,
                                    uint16_t sample_period)
{
    const bcmolt_epon_ni_key ni_key = { .epon_ni = link_key->epon_ni };
    bcmolt_epon_ni_issue_rssi_grant issue_rssi_grant_op;
    bcmos_errno rc = BCM_ERR_OK;

    if (! omon_is_epon_ni_valid(link_key->epon_ni))
    {
        BCM_LOG(ERROR, omon_log_id,
                "[OMON] Rx Power: epon_ni of (%d) is out of range for platform\n", link_key->epon_ni);
        return ;
    }

    uint8_t trx_id;

    if ( ! trx_id_from_epon_ni(link_key->epon_ni, &trx_id) )
    {
        BCM_LOG(ERROR, omon_log_id,
                "[OMON] Rx Power: TRX Id is invalid for EPON NI %d \n", link_key->epon_ni);
        return;
    }

    // Check for transevier presence
    rc = bcm_board_trx_present(trx_id);

    if (rc == BCM_ERR_NODEV)
    {
        bcmcli_session_print(session,
                "[OMON] Rx Power: TRX Not Present on PON %d\r\n ", link_key->epon_ni);
        return;
    }

    /* Perform an API operation directing the Maple firmware to issue an bcmolt_epon_ni_issue_rogue_rx_power
       RSSI grant to the specified EPON link. BCMOLT_EPON_NI_OPER_ID_ISSUE_ROGUE_RX_POWER*/

    BCMOLT_OPER_INIT(&issue_rssi_grant_op, epon_ni, issue_rssi_grant , ni_key);
    BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
                         granted_link, link_key->mac_address);
    BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
                         trigger_width, trigger_width_tq);
    BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
                         trigger_delay, trigger_delay_tq);
    BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
                         sample_period, sample_period);

    rc = bcmolt_oper_submit(link_key->device_id, &issue_rssi_grant_op.hdr);
    if (rc != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, omon_log_id,
                "issue RSSI grant operation failed with rc %d (%s)\n",
                rc, bcmos_strerror(rc));

        return;
    }
}
/*omon_rssi_measurement_initiate*/

// rssi specific indication handler interface --
static bcmos_errno bcmolt_user_appl_rssi_handle_ind(bcmolt_devid device_id,
                                                    uint8_t instance,
                                                    bcmolt_auto *ind)
{

    bcmolt_epon_ni_rssi_measurement_completed* omon_ind;
    uint32_t rssi_value = 0;
    bcmolt_epon_ni epon_ni;
    bcmos_errno rc = BCM_ERR_OK;
    char tBuf[40];

    omon_ind = (bcmolt_epon_ni_rssi_measurement_completed *) ind;
    epon_ni = omon_ind->key.epon_ni;

    if (omon_ind->data.status == BCMOLT_RESULT_SUCCESS)
    {
        /* Perform the I2C operations specified in SFF-8472 (SFP)/SFF-8077i (XFP) to
           retrieve the power measurements from the optics module. */
        rc = omon_rssi_read(epon_ni, &rssi_value);

    }
    /* Notify external host code of the outcome through an optional callback,
       defaulting to output in the CLI session where the command was initiated
       if no callback is supplied. */

    BCM_LOG_CALLER_FMT(INFO, omon_log_id,
            " RSSI Indication Rcv: for Link Mac %s, LLID 0x%x, Dev=%01d, Pon_ni=%d\r\n",
                       bcmos_mac_2_str(&omon_ind->data.link_mac, tBuf),
                         omon_ind->data.llid,
                         device_id,
                         omon_ind->key.epon_ni);

    if (rc == BCM_ERR_OK)
    {
        BCM_LOG(INFO, omon_log_id,
                 " %s measured rx power %d.%duW raw_data %d\n",
                   (omon_ind->data.status == BCMOLT_RESULT_SUCCESS ? "Succeeded" : "Failed"),
                   rssi_value/10, rssi_value%10, rssi_value);
    }
    else
    {
        BCM_LOG(INFO, omon_log_id,
            "pon %d, failed with errno %d (%s)\n",
                  epon_ni, rc, bcmos_strerror(rc));
    }
    return rc;
}

// epon rogue onu specific indication handler interface --
static bcmos_errno bcmolt_user_appl_rogue_handle_ind(bcmolt_devid device_id,
                                                     uint8_t instance,
                                                     bcmolt_auto *ind)
{
    (void)instance;
    bcmolt_epon_denied_link_rogue_violation* rogue_ind;
    char tBuf[40];

    rogue_ind = (bcmolt_epon_denied_link_rogue_violation *) ind;

    /* Notify external host code of the outcome through an optional callback,
       defaulting to output in the CLI session where the command was initiated
       if no callback is supplied. */

    BCM_LOG_CALLER_FMT(INFO, omon_log_id,
            "Rogue ONU Scan Violation: AlmState = %s, Link Mac %s, LLID 0x%x, Range=%0d, Pon_ni=%2d\r\n",
                       (rogue_ind->data.alarm_status.alarm_status == BCMOLT_STATUS_ON ? "ON" : "OFF"),
                       bcmos_mac_2_str(&rogue_ind->key.mac_address, tBuf),
                         rogue_ind->data.alarm_status.denied_llid,
                         rogue_ind->data.alarm_status.denied_range,
                         rogue_ind->key.epon_ni);

    return BCM_ERR_OK;
}

// epon rogue scan complete specific indication handler interface --
static bcmos_errno bcmolt_user_appl_rogue_complete_handle_ind(bcmolt_devid device_id,
                                                              uint8_t instance,
                                                              bcmolt_auto *ind)
{
    (void)instance;
    bcmolt_epon_ni_rogue_scan_complete* rogue_ind;

    rogue_ind = (bcmolt_epon_ni_rogue_scan_complete *) ind;

    /* Notify external host code of the outcome through an optional callback,
       defaulting to output in the CLI session where the command was initiated
       if no callback is supplied. */

    BCM_LOG_CALLER_FMT(INFO, omon_log_id,
            "Rogue ONU scan complete for Pon %d, Status = %s\r\n",
                       rogue_ind->key.epon_ni,
                       bcmolt_get_scan_result(rogue_ind->data.return_ind_status));
    return BCM_ERR_OK;
}

// public indication handler interface -- called in transport layer context
bcmos_errno bcmolt_user_appl_omon_handle_ind(bcmolt_devid device_id, uint8_t instance, bcmolt_auto *ind)
{

    // Not an error, we just don't care about this indication.
    bcmos_errno rc = BCM_ERR_OK;

    // We look at message targetting epon ni.
    if (ind->hdr.obj_type == BCMOLT_OBJ_ID_EPON_NI)
    {
        // We look at RSSI Completion event indications.
        if (ind->hdr.subgroup == (uint16_t)BCMOLT_EPON_NI_AUTO_ID_RSSI_MEASUREMENT_COMPLETED)
        {
            rc = bcmolt_user_appl_rssi_handle_ind(device_id,instance,ind);
        }
        else
        {
            // We look for Rogue Scan Complete event indications.
            if (ind->hdr.subgroup == (uint16_t)BCMOLT_EPON_NI_AUTO_ID_ROGUE_SCAN_COMPLETE)
            {
                rc = bcmolt_user_appl_rogue_complete_handle_ind(device_id, instance, ind);
            }
        }

        if (rc != BCM_ERR_OK )
        {
            BCM_LOG_CALLER_FMT(INFO, omon_log_id,
                    "OMON Handle Indication Error: Pon %d, Type %d, Rc %d\r\n",
                               instance, ind->hdr.subgroup, rc);
        }

        // Not an error, we just don't care about this indication.
        return BCM_ERR_OK;
    }

    // We look at message targetting epon denied links.
    if (ind->hdr.obj_type == BCMOLT_OBJ_ID_EPON_DENIED_LINK)
    {
        // We look at Denied Link Events of this type.
        if (ind->hdr.subgroup == BCMOLT_EPON_DENIED_LINK_AUTO_ID_ROGUE_VIOLATION)
        {
            rc = bcmolt_user_appl_rogue_handle_ind(device_id, instance, ind);
        }
        else
        {
            // Not an error, we just don't care about this object.
            return BCM_ERR_OK;
        }
    }
    return rc;

} /* bcmolt_user_appl_omon_handle_ind */

/**
 * \brief Optical monitoring task message handler
 *
 * This function is the optical monitoring task handler.  At this time the only
 * message is BCMOS_MSG_ID_INITIATE_RSSI_SAMPLE which starts the RSSI
 * measurement on the OLT.
 *
 * \param module_id BCMOS_MODULE_ID_USER_APPL_OMON
 * \param os_msg Message contents
 */
static
void omon_os_msg_handle(bcmos_module_id module_id, bcmos_msg *os_msg)
{
    omon_task_msg *msg = (omon_task_msg *)os_msg;

    switch (msg->os_msg.type)
    {
    case BCMOS_MSG_ID_INITIATE_RX_POWER:
            omon_rssi_measurement_initiate(msg->session,
                                       &msg->link_key,
                                       msg->trigger_width_ns ,
                                       msg->trigger_delay_ns,
                                       msg->sample_period_us);
        break;
    case BCMOS_MSG_ID_INITIATE_TRX_STATUS:

            omon_trx_status_initiate(msg->session,
                                     &msg->link_key);
            break;
        case BCMOS_MSG_ID_INITIATE_ROGUE_SCAN:
            omon_run_rogue_llid_scan(msg->session,
                                     &msg->link_key,
                                     msg->llid,
                                     msg->scan_mode);

        break;
    case BCMOS_MSG_ID_INITIATE_RSSI_READ:
            omon_rssi_read_initiate(msg->session,
                                     &msg->link_key);
      break;
    default:
        break;
    }
    bcmos_free(os_msg);
} /* omon_os_msg_handle */


/**
 * \brief Start the optical monitoring task
 *
 * This function starts the user level optical monitoring task and creates the
 * optical monitoring module.  It should only be called once at start up.
 *
 * \return
 * None
 */
void bcmolt_epon_omon_appl_init(void)
{
    bcmos_errno rc;
    bcmos_task_parm task_params =
    {
        .name = "user_appl_omon",
        .priority = TASK_PRIORITY_USER_APPL_OMON,
        .core = BCMOS_CPU_CORE_ANY, /* No CPU affinity */
        .init_handler = NULL
    };
    bcmos_module_parm module_params =
    {
        .qparm =
        {
            .name = "user_appl_omon",
            .size = OMON_TASK_MSG_Q_SIZE
        }
    };

    if (is_running)
    {
        return;
    }

    omon_log_id = bcm_dev_log_id_register("user_appl_omon",
                                           DEV_LOG_LEVEL_INFO,
                                           DEV_LOG_ID_TYPE_BOTH);
    BUG_ON(DEV_LOG_INVALID_ID == omon_log_id);

    rc = bcmos_task_create(&omon_task, &task_params);
    BUG_ON(rc != BCM_ERR_OK);

    rc = bcmos_module_create(BCMOS_MODULE_ID_USER_APPL_OMON, &omon_task,
                             &module_params);
    BUG_ON(rc != BCM_ERR_OK);

    is_running = BCMOS_TRUE;
} /* bcmolt_epon_omon_appl_init */


/*******************************************************************************
 * CLI
 ******************************************************************************/


/**
 * \brief RX power sample CLI command
 *
 * This function handles the "sample" CLI command.  It processes the CLI
 * parameters and dispatches a start sample message to the optical monitoring
 * task.
 *
 * \param session CLI session ID
 * \param parm Command parameters
 * \param n_parms Number of parameters
 *
 * \return
 * BCM_ERR_OK if successful, error code if not
 */
static
bcmos_errno omon_cmd_rx_power(bcmcli_session *session,
                            const bcmcli_cmd_parm parm[],
                            uint16_t n_parms)
{
    omon_link_key link_key;
    bcmos_errno rc;
    bcmcli_cmd_parm *epon_ni;
    bcmcli_cmd_parm *mac_addr;
    bcmcli_cmd_parm *Twidth_ns;
    bcmcli_cmd_parm *Tdelay_ns;
    bcmcli_cmd_parm *Tsample_us;
    omon_task_msg *msg;

    /* Get the CLI parameters. */
    epon_ni    = bcmcli_find_named_parm(session, "epon_ni");
    mac_addr   = bcmcli_find_named_parm(session, "granted_link");
    Twidth_ns  = bcmcli_find_named_parm(session, "trigger_width");  // RSSI Twidth in ns
    Tdelay_ns  = bcmcli_find_named_parm(session, "trigger_delay");  // RSSI Tdelay in ns
    Tsample_us = bcmcli_find_named_parm(session, "sample_period");  // RSSI Tsample in us

    link_key.device_id = current_device;
    link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;
    link_key.mac_address = (bcmos_mac_address)mac_addr->value.mac;

    /* Send an indication to the internal task's message queue to be
       processed. */
    msg = bcmos_calloc(sizeof(*msg));
    BUG_ON(msg == NULL);
    msg->os_msg.type = BCMOS_MSG_ID_INITIATE_RX_POWER;
    msg->os_msg.handler = omon_os_msg_handle;
    msg->link_key = link_key;
    msg->trigger_width_ns = Twidth_ns->value.number;
    msg->trigger_delay_ns = Tdelay_ns->value.number;
    msg->sample_period_us = Tsample_us->value.number;
    msg->session = session;
    rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
                                  &msg->os_msg, 0);
    BUG_ON(rc);


    return rc;
} /* omon_cmd_sample */

static
bcmos_errno omon_cmd_trx_data(bcmcli_session *session,
                              const bcmcli_cmd_parm parm[],
                              uint16_t n_parms)
{
    omon_link_key link_key;
    bcmos_errno rc;
    bcmcli_cmd_parm *epon_ni;
    omon_task_msg *msg;

    /* Get the CLI parameters. */
    epon_ni = bcmcli_find_named_parm(session, "epon_ni");

    link_key.device_id = current_device;
    link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;

    /* Send an indication to the internal task's message queue to be
       processed. */
    msg = bcmos_calloc(sizeof(*msg));
    BUG_ON(msg == NULL);
    msg->os_msg.type = BCMOS_MSG_ID_INITIATE_TRX_STATUS;
    msg->os_msg.handler = omon_os_msg_handle;
    msg->link_key = link_key;
    msg->session = session;
    rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
                                  &msg->os_msg, 0);
    BUG_ON(rc);


    return rc;
}
/* omon_cmd_trx_data */

static
bcmos_errno omon_cmd_read_rssi_result(bcmcli_session *session,
                              const bcmcli_cmd_parm parm[],
                              uint16_t n_parms)
{
    omon_link_key link_key;
    bcmos_errno rc;
    bcmcli_cmd_parm *epon_ni;
    omon_task_msg *msg;

    /* Get the CLI parameters. */
    epon_ni = bcmcli_find_named_parm(session, "epon_ni");

    link_key.device_id = current_device;
    link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;

    /* Send an indication to the internal task's message queue to be
       processed. */
    msg = bcmos_calloc(sizeof(*msg));
    BUG_ON(msg == NULL);
    msg->os_msg.type = BCMOS_MSG_ID_INITIATE_RSSI_READ;
    msg->os_msg.handler = omon_os_msg_handle;
    msg->link_key = link_key;
    msg->session = session;
    rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
                                  &msg->os_msg, 0);
    BUG_ON(rc);


    return rc;
}
/* omon_cmd_read_rssi_result */

static
bcmos_errno omon_cmd_llid_scan(bcmcli_session *session,
                              const bcmcli_cmd_parm parm[],
                              uint16_t n_parms)
{
    omon_link_key link_key;
    bcmos_errno rc;
    bcmcli_cmd_parm *epon_ni;
    bcmcli_cmd_parm *epon_llid;
    bcmcli_cmd_parm *epon_mode;
    omon_task_msg *msg;

    /* Get the CLI parameters. */
    epon_ni = bcmcli_find_named_parm(session, "epon_ni");
    epon_mode = bcmcli_find_named_parm(session, "scan_mode");
    epon_llid = bcmcli_find_named_parm(session, "epon_llid");

    link_key.device_id = current_device;
    link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;

    /* Send an indication to the internal task's message queue to be
       processed. */
    msg = bcmos_calloc(sizeof(*msg));
    BUG_ON(msg == NULL);
    msg->os_msg.type = BCMOS_MSG_ID_INITIATE_ROGUE_SCAN;
    msg->os_msg.handler = omon_os_msg_handle;
    msg->link_key = link_key;
    msg->session = session;
    msg->llid = epon_llid->value.number;
    msg->scan_mode = epon_mode->value.number;
    rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
                                  &msg->os_msg, 0);
    BUG_ON(rc);


    return rc;
}


/**
 * \brief Install CLI commands
 *
 * This function creates and optical monitoring command directoy "omon" and
 * installs optical monitoring CLI commands to this directory.
 *
 * \param top_dir Parent of "omon" directory
 *
 * \return
 * BCM_ERR_OK if successful, error code if not
 */
void bcmolt_user_appl_epon_omon_cli_init(bcmcli_entry *top_dir)
{
    static const char *dir_name = "omon";

    if (bcmcli_dir_find(top_dir, dir_name))
    {
        return;
    }

    bcmcli_entry *dir = bcmcli_dir_add(top_dir,
                                       dir_name,
                                       "EPON optical monitoring commands",
                                       BCMCLI_ACCESS_ADMIN, NULL);
    BUG_ON(dir == NULL);

    BCMCLI_MAKE_CMD(dir, "rx_power", "Issue RX Power Measurement", omon_cmd_rx_power,
            BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0),
            BCMCLI_MAKE_PARM("granted_link", "Link mac address, 000000000000 for Idle Power", BCMCLI_PARM_MAC, 0),
            BCMCLI_MAKE_PARM("trigger_width",
                             "RSSI Trigger Width (Tw) in ns, Desired width of RSSI Trigger based on the Optical Module Specifications."
                             "This is a mandatory parameter used for all RX Power measurements ( including Idle power) and must not be 0."
                             "Note: The granularity of the device is 1 TQ (16ns) the input will be rounded up to the next TQ."
                             , BCMCLI_PARM_NUMBER, 0),
            BCMCLI_MAKE_PARM("trigger_delay",
                             "RSSI Trigger Delay (Td) in ns, Desired delay to meet the trigger delay timing requirement of the Optical Module Specifications."
                             "The rssi trigger delay is measured from the start of sync_time and is adjusted as needed. "
                             "The trigger delay moves the assertion of the RSSI Trigger strobe into the grant window."
                             "Note: The granularity of the device is 1 TQ (16ns) the input will be rounded up to the next TQ."
                             , BCMCLI_PARM_NUMBER, 0),
            BCMCLI_MAKE_PARM("sample_period",
                             "(Ti2c) Sample period in uS, internal I2C hold/prohibit time where access to device is not allowed."
                             "During this period the internal RSSI data is invalid and I2C opertions on this device must not be executed."
                             "A value of 500uS is recommended for most applications. "
                             , BCMCLI_PARM_NUMBER, 0));

    BCMCLI_MAKE_CMD(dir, "trx_data", "Read Tranceiver Data", omon_cmd_trx_data,
            BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0));

    BCMCLI_MAKE_CMD(dir, "read_rssi", "Read RSSI Result from Tranceiver", omon_cmd_read_rssi_result,
            BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0));

    BCMCLI_MAKE_CMD(dir, "llid_scan", "Run Rogue ONU LLID Scan", omon_cmd_llid_scan,
            BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0),
            BCMCLI_MAKE_PARM("scan_mode", "LLID scan mode 1 for full pon scan, 0 for targeted (llid required for targeted)", BCMCLI_PARM_NUMBER, 0),
            BCMCLI_MAKE_PARM("epon_llid", "EPON llid to scan when mode=0", BCMCLI_PARM_HEX, 0));
}
/* bcmolt_user_appl_epon_omon_cli_init */


/* End of file omon.c */

