/*
<: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 <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/reboot.h>
#include <linux/pci.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <bcmos_system.h>
#include <bcm_config.h>
#include <bcmolt_msg.h>
#include <bcmolt_fld.h>
#include <bcmolt_llpcie.h>
#include <bcmolt_conv.h>
#include <bcmolt_i2c_devs.h>
#include <bcmolt_board_selector.h>
#include "bcmolt_user_utils.h"

#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>

#define BOOT_FILE                       "/opt/bcm68620/bcm68620_boot.bin"
#define APPL_FILE                       "/opt/bcm68620/bcm68620_appl.bin"
#define ONU_FW_FILE                     "/opt/bcm68620/dummy_onu_firmware.bin"

#define FPGA_REG_FPGA_VERSION 0x0
#define FPGA_REG_BOARD_CONF 0x1
#define FPGA_REG_RESETS 0x2

#define FPGA_RST_BIT_DEVICE 0x0
#define FPGA_DEVICE_SWITCH  4

#define FPGA_ENABLE_ALL_DEVICES 0x1f
#define FPGA_ENABLE_SWITCH              (1 << FPGA_DEVICE_SWITCH)
/* For now swap devices for consistency with PCI enumeration */
#define FPGA_DEVICE_RESET_BIT(dev)      (1 << (FPGA_RST_BIT_DEVICE + dev))

/* Minimum required FPGA version for reading default system mode via BOARD_CONF register. */
#define FPGA_VER_FOR_SVK_CONFIG 6

/* Lock that protects critical sections */
static bcmos_mutex user_lock;
static bcmos_bool user_lock_initialized;

typedef enum
{
    SVK_BOARD_ID_1    = 0x7, /* SVK #1 - BCM968620S: all PON flavors supported, SFP+ */
    SVK_BOARD_ID_2_XG = 0x6, /* SVK #2 - BCM968620XG: XGPON */
    SVK_BOARD_ID_2_XE = 0x5, /* SVK #2 - BCM968620XE: 10G EPON */
    SVK_BOARD_ID_3    = 0x4, /* SVK #3 - BCM968620K: all PON flavors supported, XFP */
    DVT_BOARD_ID      = 0x3, /* DVT board */
} svk_board_id;

typedef enum
{
    SVK_MODE_GPON_16X     = 0xF, /* SVK #1/3: 16x GPON mode, SVK #2: only valid mode */
    SVK_MODE_EPON_1G_16X  = 0xE, /* SVK #1/3: 16x 1G EPON mode */
    SVK_MODE_XGPON        = 0xD, /* SVK #1/3: 8x XGPON mode */
    SVK_MODE_EPON_10G_8X  = 0xC, /* SVK #1/3: 8x 10G EPON mode */
    SVK_MODE_EPON_GPON_8X = 0xB, /* SVK #1/3: 8x 10G EPON + 8x GPON coexistence mode */
} svk_mode;


#define CHECK_RETURN_ERROR(cond,rc) \
		do { \
			if (cond) {\
				bcmos_printf("%s#%d: failed with rc=%d\n", __FUNCTION__, __LINE__, rc);\
				return rc;\
			}\
		} while (0)


static void userlock_lock(void)
{
    if (!user_lock_initialized)
    {
        bcmos_mutex_create(&user_lock, 0, "reset_lock");
        user_lock_initialized = BCMOS_TRUE;
    }
    bcmos_mutex_lock(&user_lock);
}


static void userlock_unlock(void)
{
    bcmos_mutex_unlock(&user_lock);
}

static struct file *file_open(const char *path, int flags)
{
    struct file *fd = NULL;
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;

    fd = filp_open(path, flags, mode);
    if(IS_ERR(fd))
        return NULL;
    return fd;
}

static void file_close(struct file *file)
{
    filp_close(file, NULL);
}

static int file_read(struct file *file, uint32_t offset, uint8_t *data, unsigned int size)
{
    unsigned long long o = offset;
    mm_segment_t oldfs;
    int bytes_read;

    oldfs = get_fs();
    set_fs(get_ds());
    bytes_read = vfs_read(file, data, size, &o);
    set_fs(oldfs);
    if (bytes_read < 0)
    {
        BCMOS_TRACE_ERR("vfs_read returned error %d\n", bytes_read);
        return (int)BCM_ERR_IO;
    }
    return bytes_read;
}

static int file_write(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size)
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_write(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}

static bcmos_errno file_write_1(const char *path)
{
    struct file *fd;
    char to_write[] = { '1' };
    loff_t pos = 0;
    ssize_t bytes_written;

    fd = file_open(path, O_WRONLY);
    if ((fd == NULL) || (fd == (void *)-ENOENT)) /* -ENOENT; No such file or directory */
    {
        BCMOS_TRACE_ERR("Can't open file %s for writing. Error %s\n",
            path, bcmos_strerror(fd == NULL ? BCM_ERR_NULL : BCM_ERR_NOENT));
        return (fd == NULL ? BCM_ERR_NULL : BCM_ERR_NOENT);
    }

    bytes_written = file_write(fd, pos, to_write, sizeof(to_write));
    if (bytes_written != sizeof(to_write))
    {
        BCMOS_TRACE_ERR("vfs_write returned incorrect number of characters written: %d\n", bytes_written);
    }

    file_close(fd);
    return BCM_ERR_OK;
}

static bcmos_errno i2c_fpga_read(uint32_t reg, uint32_t *val)
{
    return maple_i2c_read_fpga(maple_i2c_get_client(FPGA_I2C_ADDR), reg, val);
}

static bcmos_errno i2c_fpga_write(uint32_t reg, uint32_t val)
{
    return maple_i2c_write_fpga(maple_i2c_get_client(FPGA_I2C_ADDR), reg, val);
}

static bcmos_errno i2c_config_switch(void)
{
    uint8_t to_write = 1;
    int ret;

    ret = maple_i2c_write(maple_i2c_get_client(I2C_SW0_I2C_ADDR), &to_write, 1);
    if (ret != 0)
    {
        BCMOS_TRACE_ERR("Failed to write switch: %d\n", ret);
        return BCM_ERR_INTERNAL;
    }

    return BCM_ERR_OK;
}

static bcmos_errno i2c_fpga_version_get(uint32_t *version)
{
    return i2c_fpga_read(FPGA_REG_FPGA_VERSION, version);
}

static bcmos_errno i2c_svk_config_get(svk_board_id *board_id, svk_mode *mode)
{
    uint32_t val;
    bcmos_errno rc;

    rc = i2c_fpga_read(FPGA_REG_BOARD_CONF, &val);
    if (rc == BCM_ERR_OK)
    {
        *board_id = (svk_board_id)(val & 0x7);
        *mode = (svk_mode)((val >> 4) & 0xF);
    }

    return rc;
}

static bcmos_errno i2c_device_cpu_state_set(bcmolt_devid device, bcmos_bool is_on)
{
    bcmos_errno rc;
    uint32_t reset_values;

    /* Prevent race condition when this function is called for 2 devices simultaneously */
    userlock_lock();

    do
    {
        rc = i2c_config_switch();
        if (rc)
            break;

        /* Read-modify-write so we can set only the relevant bit */
        rc = i2c_fpga_read(FPGA_REG_RESETS, &reset_values);
        if (rc)
            break;

        if (is_on)
            reset_values |= FPGA_DEVICE_RESET_BIT(device);
        else
            reset_values &= ~FPGA_DEVICE_RESET_BIT(device);

        rc = i2c_fpga_write(FPGA_REG_RESETS, reset_values);

    } while (0);

    userlock_unlock();

    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    bcmos_usleep(1000);

    return BCM_ERR_OK;
}

static bcmos_bool bcmuser_system_mode_is_valid(bcmolt_system_mode system_mode, svk_board_id board_id, svk_mode svk_mode)
{
    switch (board_id)
    {
    case SVK_BOARD_ID_1:
    case SVK_BOARD_ID_3:
        switch (svk_mode)
        {
        case SVK_MODE_GPON_16X:
            return (system_mode == BCMOLT_SYSTEM_MODE_GPON__4_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_GPON__8_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_GPON__16_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_GPON_8_XGPON_4_X_COEXISTENCE ||
                    system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__8_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__4_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_NGPON2__8_X_2_P_5_G);
        case SVK_MODE_EPON_1G_16X:
            return (system_mode == BCMOLT_SYSTEM_MODE_EPON__4_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_EPON__16_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_EPON__2_X_10_G ||
                    system_mode == BCMOLT_SYSTEM_MODE_EPON__4_X_10_G ||
                    system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X_10_G);
        case SVK_MODE_XGPON:
            return (system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__8_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__4_X ||
                    system_mode == BCMOLT_SYSTEM_MODE_NGPON2__8_X_2_P_5_G);
        case SVK_MODE_EPON_10G_8X:
            return
                (system_mode == BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA) ||
                (system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA) ||
                (system_mode == BCMOLT_SYSTEM_MODE_EPON__2_X_10_G) ||
                (system_mode == BCMOLT_SYSTEM_MODE_EPON__4_X_10_G) ||
                (system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X_10_G);
        default:
            return BCMOS_FALSE;
        }
    case SVK_BOARD_ID_2_XG:
        return (system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__8_X ||
                system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__4_X ||
                system_mode == BCMOLT_SYSTEM_MODE_NGPON2__8_X_2_P_5_G ||
                system_mode == BCMOLT_SYSTEM_MODE_XGS__2_X_10_G ||
                system_mode == BCMOLT_SYSTEM_MODE_NGPON2__2_X_10_G);
    case SVK_BOARD_ID_2_XE:
        return
            (system_mode == BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA) ||
            (system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA) ||
            (system_mode == BCMOLT_SYSTEM_MODE_AE_8_X) ||
            (system_mode == BCMOLT_SYSTEM_MODE_EPON__2_X_10_G) ||
            (system_mode == BCMOLT_SYSTEM_MODE_EPON__4_X_10_G) ||
            (system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X_10_G);
    case DVT_BOARD_ID:
        return BCMOS_TRUE;
    default:
        return BCMOS_FALSE;
    }
}

bcmos_errno bcmuser_system_mode_validate(bcmolt_devid device, bcmolt_system_mode system_mode)
{
    bcmos_errno rc;
    uint32_t version;
    svk_board_id board_id;
    svk_mode svk_mode;

    rc = i2c_config_switch();
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    rc = i2c_fpga_version_get(&version);
    if (rc != BCM_ERR_OK)
    {
        BCMOS_TRACE_INFO("Failed to read FPGA version\n");
        return rc;
    }

    if (version < FPGA_VER_FOR_SVK_CONFIG)
    {
        /* this FPGA version don't support reading the SVK version, so we must assume it's OK */
        return BCM_ERR_OK;
    }

    rc = i2c_svk_config_get(&board_id, &svk_mode);
    if (rc != BCM_ERR_OK)
    {
        BCMOS_TRACE_INFO("Failed to read SVK config\n");
        return rc;
    }

    if (bcmuser_system_mode_is_valid(system_mode, board_id, svk_mode))
    {
        return BCM_ERR_OK;
    }
    else
    {
        BCMOS_TRACE_INFO(
            "System mode %s is not supported for board ID %d, SVK mode %d\n",
            bcmolt_system_mode_name(system_mode),
            board_id,
            svk_mode);
        return BCM_ERR_NOT_SUPPORTED;
    }
}

int bcmuser_image_read(bcmolt_devid device, bcmolt_device_image_type image_type,
    uint32_t offset, uint8_t *buf, uint32_t buf_size)
{
    struct file *fd;
    int bytes_read;
    bcmos_errno rc;
    static int2str_t image_type2str[] =
    {
        {BCMOLT_DEVICE_IMAGE_TYPE_BOOTLOADER, BOOT_FILE},
        {BCMOLT_DEVICE_IMAGE_TYPE_APPLICATION, APPL_FILE},
        {BCMOLT_DEVICE_IMAGE_TYPE_ITU_PON_ONU_FIRMWARE, ONU_FW_FILE},
        {-1}
    };
    const char *filename;

    filename = int2str(image_type2str, image_type);
    fd = file_open(filename, O_RDONLY);
    if ((fd == NULL) || (fd == (void *)-ENOENT)) /* -ENOENT; No such file or directory */
    {
        rc = (fd == NULL ? BCM_ERR_NULL : BCM_ERR_NOENT);
        BCMOS_TRACE_ERR("filp_open returned error %s (%d)\n", bcmos_strerror(rc), rc);
        return rc;
    }
    bytes_read = file_read(fd, offset, buf, buf_size);
    file_close(fd);
    if (bytes_read < 0)
    {
        return (int)BCM_ERR_IO;
    }
    return bytes_read;
}

bcmos_errno bcmuser_device_off(bcmolt_devid device)
{
    /* Ignore request for non-existing device */
    if (device >= bcmolt_board_num_maple_devices())
        return BCM_ERR_OK;
    BCMOS_TRACE_INFO("device=%u\n", device);
    return i2c_device_cpu_state_set(device, BCMOS_FALSE);
}

bcmos_errno bcmuser_device_on(bcmolt_devid device)
{
    bcmos_errno rc;

    BCMOS_TRACE_INFO("device=%u\n", device);
    if (device >= bcmolt_board_num_maple_devices())
        return BCM_ERR_RANGE;

    rc = i2c_device_cpu_state_set(device, BCMOS_TRUE);
    /* Wait a moment to make sure the device is discoverable in case it just booted. */
    bcmos_usleep(50 * 1000);

    return rc;
}

bcmos_errno bcmuser_device_is_running(bcmolt_devid device, bcmos_bool *is_running)
{
    bcmos_errno rc;
    uint32_t reset_values;
    uint32_t version;

    rc = i2c_config_switch();
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    rc = i2c_fpga_version_get(&version);
    if (rc != BCM_ERR_OK)
    {
        BCMOS_TRACE_INFO("Failed to read FPGA version\n");
        return rc;
    }
    if (!bcmolt_board_supports_standalone(version))
    {
        /* For older FPGAs that don't support standalone mode, the device is taken out of reset at boot.  We need to lie
           and tell device control that it's not running, so it will be programmed from scratch. */
        BCMOS_TRACE_INFO("FPGA version %d doesn't support standalone mode\n", version);
        *is_running = BCMOS_FALSE;
        return BCM_ERR_OK;
    }

    rc = i2c_fpga_read(FPGA_REG_RESETS, &reset_values);
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    *is_running = ((reset_values & FPGA_DEVICE_RESET_BIT(device)) != 0);

    return BCM_ERR_OK;
}

bcmos_errno bcmuser_host_reset(void)
{
    bcm_ll_pcie_cleanup();
    kernel_restart(NULL);
    return BCM_ERR_OK; /* will never be reached */
}

bcmos_errno bcmuser_pcie_prepare(void)
{
    bcmos_errno rc;
    uint32_t reset_values;
    const char *pcie_rescan_file = bcmolt_board_pci_rescan_string_get();
    int i;

    /* - Take all devices out of reset
     * - rescan bus
     * - restore reset value
     */

    rc = i2c_config_switch();
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    /* Read-modify-write so we can set only the relevant bit */
    rc = i2c_fpga_read(FPGA_REG_RESETS, &reset_values);
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    rc = i2c_fpga_write(FPGA_REG_RESETS, FPGA_ENABLE_ALL_DEVICES);
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    bcmos_usleep(50000);

    /* Now recan PCI bus */
    /* Now re-enumerate the PCI bus by writing a 1 to the 'rescan' file. */
    rc = file_write_1(pcie_rescan_file);
    if (rc != BCM_ERR_OK)
        BCMOS_TRACE_ERR("file write returned error %s (%d)\n", bcmos_strerror(rc), rc);
    bcmos_usleep(100 * 1000);

    /* Now initialize ll_pcie driver and map maple devices */
    rc = bcm_ll_pcie_init();
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    /* Now restore rest values. Keep switch out of reset */
    for (i = 0; i < bcmolt_board_num_maple_devices(); i++)
    {
        if ((FPGA_DEVICE_RESET_BIT(i) & reset_values) == 0)
            bcmuser_pcie_channel_remove(i);
    }
    rc = i2c_fpga_write(FPGA_REG_RESETS, reset_values | FPGA_ENABLE_SWITCH);
    CHECK_RETURN_ERROR(rc != BCM_ERR_OK, rc);

    return 0;
}

bcmos_errno bcmuser_pcie_channel_prepare(bcmolt_devid device)
{
    bcmos_errno rc;

    rc = bcm_ll_pcie_dev_enable(device);
    if (rc)
        BCMOS_TRACE_ERR("Couldn't prepare device %d. Error %s\n", device, bcmos_strerror(rc));

    return rc;
}

bcmos_errno bcmuser_pcie_channel_remove(bcmolt_devid device)
{
    bcm_ll_pcie_dev_disable(device);
    return BCM_ERR_OK;
}
