BAL and Maple Release 2.2
Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bcm68620_release/release/host_customized/user_config/Makefile b/bcm68620_release/release/host_customized/user_config/Makefile
new file mode 100644
index 0000000..1db59e8
--- /dev/null
+++ b/bcm68620_release/release/host_customized/user_config/Makefile
@@ -0,0 +1,16 @@
+#
+# user_config
+#
+MOD_NAME = user_config
+MOD_DEPS = common_api fld ll_pcie
+
+ifeq ("$(OS_KERNEL)", "linux")
+ MOD_TYPE = linux_lib
+else
+ MOD_TYPE = lib
+endif
+
+ifneq ("$(BOARD)", "")
+ srcs = board/$(BOARD)/bcmolt_user_utils.c
+ MOD_DEPS += i2c_devs board_selector
+endif
diff --git a/bcm68620_release/release/host_customized/user_config/bcmolt_user_utils.h b/bcm68620_release/release/host_customized/user_config/bcmolt_user_utils.h
new file mode 100644
index 0000000..ff32e36
--- /dev/null
+++ b/bcm68620_release/release/host_customized/user_config/bcmolt_user_utils.h
@@ -0,0 +1,75 @@
+/*
+<: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.
+
+:>
+ */
+
+#ifndef _BCMOLT_USER_UTILS_H_
+#define _BCMOLT_USER_UTILS_H_
+
+#include <bcmolt_model_types.h>
+#include <bcmos_system.h>
+#include <bcmolt_msg.h>
+#include <bcmolt_fld.h>
+
+/* Validate that the given system mode is supported for the given device.
+ * This function returns BCM_ERR_OK if the system mode is valid or a different error code otherwise. */
+bcmos_errno bcmuser_system_mode_validate(bcmolt_devid device, bcmolt_system_mode system_mode);
+
+/* Read file from a file system into a buffer. */
+int bcmuser_image_read(
+ bcmolt_devid device,
+ bcmolt_device_image_type image_type,
+ uint32_t offset,
+ uint8_t *buf,
+ uint32_t buf_size);
+
+/* Turn off the processor of the embedded device. */
+bcmos_errno bcmuser_device_off(bcmolt_devid device);
+
+/* Turn on the processor of the embedded device. */
+bcmos_errno bcmuser_device_on(bcmolt_devid device);
+
+/* Check whether or not the embedded device processor is running. */
+bcmos_errno bcmuser_device_is_running(bcmolt_devid device, bcmos_bool *is_cpu_on);
+
+/* Prepare the PCIe bus for communication with the embedded devices */
+bcmos_errno bcmuser_pcie_prepare(void);
+
+/* Prepare the PCIe channel for communication with the embedded device.
+ * For example, this function may re-enumerate the PCI-E bus. */
+bcmos_errno bcmuser_pcie_channel_prepare(bcmolt_devid device);
+
+bcmos_errno bcmuser_pcie_channel_prepare_for_kt2(bcmolt_devid device);
+
+/* Remove the PCIe channel for communication with the embedded device.
+ * For example, this function may re-enumerate the PCI-E bus. */
+bcmos_errno bcmuser_pcie_channel_remove(bcmolt_devid device);
+
+/* Reset the host processor. */
+bcmos_errno bcmuser_host_reset(void);
+
+#endif
diff --git a/bcm68620_release/release/host_customized/user_config/board/wrx/bcmolt_user_utils.c b/bcm68620_release/release/host_customized/user_config/board/wrx/bcmolt_user_utils.c
new file mode 100644
index 0000000..94f58a9
--- /dev/null
+++ b/bcm68620_release/release/host_customized/user_config/board/wrx/bcmolt_user_utils.c
@@ -0,0 +1,533 @@
+/*
+<: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;
+}
diff --git a/bcm68620_release/release/host_customized/user_config/board_selector/Makefile b/bcm68620_release/release/host_customized/user_config/board_selector/Makefile
new file mode 100644
index 0000000..bfbfe46
--- /dev/null
+++ b/bcm68620_release/release/host_customized/user_config/board_selector/Makefile
@@ -0,0 +1,15 @@
+#
+# board_selector
+#
+MOD_NAME = board_selector
+MOD_SUPPRESS_OS_DEP = y
+
+ifeq ("$(OS_KERNEL)", "linux")
+ MOD_TYPE = linux_lib
+else
+ MOD_TYPE = lib
+endif
+
+ifneq ("$(BOARD)", "")
+ srcs = $(BOARD)/bcmolt_board_selector.c
+endif
diff --git a/bcm68620_release/release/host_customized/user_config/board_selector/bcmolt_board_selector.h b/bcm68620_release/release/host_customized/user_config/board_selector/bcmolt_board_selector.h
new file mode 100644
index 0000000..74a8103
--- /dev/null
+++ b/bcm68620_release/release/host_customized/user_config/board_selector/bcmolt_board_selector.h
@@ -0,0 +1,61 @@
+/*
+<: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.
+
+:>
+ */
+
+/*
+ * bcmolt_board_selector.h
+ */
+
+#ifndef _BCMOLT_BOARD_SELECTOR_H_
+#define _BCMOLT_BOARD_SELECTOR_H_
+
+#include <bcmos_system.h>
+
+/* bus, devfn --> device mapping table */
+typedef struct
+{
+ int bus;
+ int devfn;
+ int device;
+} bus_devfn_devid;
+
+/* Get PCI rescan string. It is used in linux to rescan PCIe bus */
+const char *bcmolt_board_pci_rescan_string_get(void);
+
+/* Get bus, devfn --> dev_id mapping table.
+ * The table is terminated by row with bus=-1,devfn=-1
+ */
+const bus_devfn_devid *bcmolt_board_pci_map_table_get(void);
+
+/* Return TRUE if board supports Maple-standalone mode */
+bcmos_bool bcmolt_board_supports_standalone(uint32_t version);
+
+/* Returns number of maple devices on the board */
+uint8_t bcmolt_board_num_maple_devices(void);
+
+#endif /* _BCMOLT_BOARD_SELECTOR_H_ */
diff --git a/bcm68620_release/release/host_customized/user_config/board_selector/wrx/bcmolt_board_selector.c b/bcm68620_release/release/host_customized/user_config/board_selector/wrx/bcmolt_board_selector.c
new file mode 100644
index 0000000..c997a12
--- /dev/null
+++ b/bcm68620_release/release/host_customized/user_config/board_selector/wrx/bcmolt_board_selector.c
@@ -0,0 +1,113 @@
+/*
+<: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.
+
+:>
+ */
+
+/*
+ * bcmolt_board_selector.c
+ */
+
+#include <linux/fs.h>
+#include "bcmolt_board_selector.h"
+
+static bus_devfn_devid bus_devfn_devid_table_svk4[] = {
+ { 5, 0, 0},
+ { 3, 0, 1},
+ {-1,-1,-1},
+};
+
+static bus_devfn_devid bus_devfn_devid_table_svk1_3[] = {
+ { 3, 0, 0},
+ {-1,-1,-1},
+};
+
+#define SVK4_IDENT_FILE "/etc/svk4"
+
+#define PCIE_DEVICE_RESCAN_FILE_SVK4 "/sys/bus/pci/devices/0000:02:00.0/rescan"
+#define PCIE_DEVICE_RESCAN_FILE_SVK1_3 "/sys/bus/pci/devices/0000:02:01.0/rescan"
+
+/* Minimum required FPGA version for standalone mode (host / embedded processors running disconnected). */
+#define FPGA_VER_FOR_STANDALONE 7
+
+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 bcmos_bool can_read_file(const char *path)
+{
+ struct file *fd = file_open(path, O_RDONLY);
+ if ((fd == NULL) || (fd == (void *)-ENOENT)) /* -ENOENT; No such file or directory */
+ {
+ return BCMOS_FALSE;
+ }
+
+ file_close(fd);
+ return BCMOS_TRUE;
+}
+
+static bcmos_bool board_is_svk4(void)
+{
+ return can_read_file(SVK4_IDENT_FILE);
+}
+
+/* Get PCI rescan string. It is used in linux to rescan PCIe bus */
+const char *bcmolt_board_pci_rescan_string_get(void)
+{
+ return board_is_svk4() ? PCIE_DEVICE_RESCAN_FILE_SVK4 : PCIE_DEVICE_RESCAN_FILE_SVK1_3;
+}
+
+/* Get bus, devfn --> dev_id mapping table.
+ * The table is terminated by row with bus=-1,devfn=-1
+ */
+const bus_devfn_devid *bcmolt_board_pci_map_table_get(void)
+{
+ return board_is_svk4() ? bus_devfn_devid_table_svk4 : bus_devfn_devid_table_svk1_3;
+}
+
+/* Return TRUE if board supports Maple-standalone mode */
+bcmos_bool bcmolt_board_supports_standalone(uint32_t version)
+{
+ return board_is_svk4() || version >= FPGA_VER_FOR_STANDALONE;
+}
+
+/* Returns number of maple devices on the board */
+uint8_t bcmolt_board_num_maple_devices(void)
+{
+ return board_is_svk4() ? 2 : 1;
+}