#!/bin/sh
#------------------------------------------------------------------
#
# generate_platforms - Platform dependent parsing and file generation
#
# Feb 2016 Joel Aller
#
# Copyright (c) 2016-2020 by cisco Systems, Inc.
# All rights reserved.
#------------------------------------------------------------------
#set -x

MERAKI_BOARD=`cat /MERAKI_BOARD`
if [ "$MERAKI_BOARD" != "barbados" ]; then
    exit 0   
fi

. /usr/bin/parse_cmdline.sh
. /usr/bin/platformfunc.sh

DST_DIR=$PLATFORM_DATA_DIR

# TODO: ???Get this info from u-boot
MIN_IF_NUM=0
MAX_IF_NUM=3

# Base/default power without USB
BOARD_BARBADOS_PWR=219
BOARD_BARBADOS_UPOE_PWR=200
BOARD_BARBADOS_3K_USB_OFFSET_PWR=34
BOARD_BARBADOS_2K_PWR=191
BOARD_BARBADOS_2K_USB_OFFSET_PWR=34
BOARD_MILOS_PWR=252
BOARD_MILOS_I_PWR=330
BOARD_BARBADOS_A_PWR=255
BOARD_BARBADOS_A_USB_OFFSET_PWR=18
BOARD_DUPLO_PWR=254 
BOARD_DUPLO_UPOE_PWR=235 
BOARD_DUPLO_USB_OFFSET_PWR=45

# $1 - Error message
error_action () {
    echo "WARNING: $1"
    echo "WARNING: $1" > ${DST_DIR}/error_log
}

enumerate_internal_iot() {
    local i
    local retry=3
    local authorized=/sys/bus/usb/devices/usb2/2-1/authorized
    local device=ttyXRUSB0

    insmod /lib/modules/usbserial.ko
    insmod /lib/modules/exar.ko

    for i in `seq $retry`; do
        if [ -e $authorized ]; then
            echo 1 > $authorized
            break
        fi
        logger -s -t $0 "Waiting for internal IOT on USB bus"
        sleep 1
    done

    for i in `seq $retry`; do
        if [ -e /dev/${device} ]; then
            plat_set_iot_device ttyiot0 $device
            touch ${DST_DIR}/has_ble
            echo 2650F1 > ${DST_DIR}/ble_chip
            break
        fi
       logger -s -t $0 "Waiting for IOT device /dev/${device}"
        sleep 1
    done
}

# Nolan phase 2 is not supported on 11ac aps. Need
# to be upldate device list for barbados platform
plat_set_barbados_iox_external_dev_list()
{
cat >> ${IOX_DEVICE_CONFIG_FILE} <<IOX_DEV_LIST
  -
    device_id: /dev/ttyiote0
    device_name: async2
    setup_script:
    teardown_script:
    aliases:
IOX_DEV_LIST
}

mkdir -p $DST_DIR
rm -f $DST_DIR/*


# Create cookie files
create_platform_files

usb_power_level="`plat_get_usb_admin_state`"
#
# Parse kernel command line for convinience info retrieval
#

val="`cmdline_get_bootedpart`"
if [ ! -z "$val" ]; then
    echo $val > ${DST_DIR}/booted_partition
else
    error_action "Unknown booted partition"
fi

val="`cmdline_get_activepart`"
if [ ! -z "$val" ]; then
    echo $val > ${DST_DIR}/active_partition
    echo `cmdline_get_alternateboot $val` > ${DST_DIR}/alternate_partition
else
    error_action "Unknown active partition"
fi

val="`cmdline_get_activeboot`"
if [ ! -z "$val" ]; then
    echo $val > ${DST_DIR}/bootloader_booted
    if [ $val -eq 0 ]; then
        echo master > ${DST_DIR}/show_bootloader_booted
    elif [ $val -eq 1 ]; then
        echo shadow > ${DST_DIR}/show_bootloader_booted
    else
        echo unknow > ${DST_DIR}/show_bootloader_booted
        error_action "Unknown bootloader booted"
    fi
else
    # Older u-boot does not support shadowing. Assume we are booted on master
    echo 0 > ${DST_DIR}/bootloader_booted
    echo master > ${DST_DIR}/show_bootloader_booted
    error_action "WARNING: Old bootloader. Please upgrade to the new version"
fi

val="`cmdline_get_bootloader_version`"
if [ ! -z "$val" ]; then
    echo $val > ${DST_DIR}/bootloader_raw_version
    printf '0x%x\n' $((val & ~1))  > ${DST_DIR}/bootloader_version
    if [ "$((val & 1))" -ne 0 ]; then
        echo developer > ${DST_DIR}/bootloader_release
    else
        echo release > ${DST_DIR}/bootloader_release
    fi
else
    echo 0x0000 > ${DST_DIR}/bootloader_version
    error_action "Unknown bootloader version"
fi

pid=`cat /COOKIE_PID | sed -e 's/AIR-//' | cut -d '-' -f 1`
val="`cmdline_get_board_id`"
if [ ! -z "$val" ]; then
    echo $val > ${DST_DIR}/board_id
    echo 0 > ${DST_DIR}/halo_radio_id
    case $val in
        # BARBADOS3K_BOARD_ID
        0x20)
            echo 3K > ${DST_DIR}/board_name
            #
            # Generate all additional board info based on boardid below
            #

            # POE stuff (in Deciwatts)
            plat_set_default_poe_max $BOARD_BARBADOS_PWR
            plat_set_default_upoe_power_max $BOARD_BARBADOS_UPOE_PWR

            # Radio stuff
            echo 2 > ${DST_DIR}/max_radios

            touch ${DST_DIR}/has_usb
            plat_set_usb_small_max_power 2500
            plat_set_usb_offset_power $BOARD_BARBADOS_3K_USB_OFFSET_PWR
            # TODO: USB enable by default for now.
            plat_set_usb_power_level $usb_power_level

            # Expansion module power
            plat_set_em_small_max_power 2700

            # Support antenna detection
            if [ $pid == AP3802E ]; then
                touch ${DST_DIR}/antenna_detection
            fi
            #provide ethphyid mdio addr
            plat_set_iox_internal_device_list
            ;;
        # BARBADOS2K_BOARD_ID
        0x21)
            echo 2K > ${DST_DIR}/board_name

            # POE stuff (in Deciwatts)
            plat_set_default_poe_max $BOARD_BARBADOS_2K_PWR

            # Radio stuff
            echo 2 > ${DST_DIR}/max_radios

            touch ${DST_DIR}/has_usb
            plat_set_usb_small_max_power 2500
            plat_set_usb_offset_power $BOARD_BARBADOS_2K_USB_OFFSET_PWR
            # TODO: USB enable by default for now.
            plat_set_usb_power_level $usb_power_level

            #Support antenna detection
            if [ $pid == AP2802E ]; then
                touch ${DST_DIR}/antenna_detection
            fi
            plat_set_iox_internal_device_list
            ;;
        # BARBADOS2KP1_ID
        0x22)
            echo 2k-proto > ${DST_DIR}/board_name
            # Radio stuff
            echo 2 > ${DST_DIR}/max_radios

            touch ${DST_DIR}/has_usb
            plat_set_iox_internal_device_list
            ;;
        # MILOS_ID
        0x23)
            echo milos > ${DST_DIR}/board_name

            # POE stuff (in Deciwatts)
            if [ $pid == AP1562I ]; then
                plat_set_default_poe_max $BOARD_MILOS_I_PWR
                plat_set_default_upoe_power_max $BOARD_MILOS_I_PWR
            else
                plat_set_default_poe_max $BOARD_MILOS_PWR
            fi

            # Radio stuff
            echo 2 > ${DST_DIR}/max_radios
            ;;
        # 2KH_ID
        0x24)
            echo 2KH > ${DST_DIR}/board_name

            #
            # Generate all additional board info based on boardid below
            #
            # Radio stuff
            echo 2 > ${DST_DIR}/max_radios
            echo 2 > ${DST_DIR}/halo_radio_id

            touch ${DST_DIR}/has_usb
            plat_set_iox_internal_device_list
            ;;
        # 3KVE_ID
        0x25)
            echo 3KVE > ${DST_DIR}/board_name

            # POE stuff (in Deciwatts)
            plat_set_default_poe_max $BOARD_BARBADOS_PWR
            plat_set_default_upoe_power_max $BOARD_BARBADOS_UPOE_PWR

            #
            # Generate all additional board info based on boardid below
            #
            # Radio stuff
            echo 2 > ${DST_DIR}/max_radios

            touch ${DST_DIR}/has_usb
            plat_set_usb_small_max_power 2500
            plat_set_usb_offset_power $BOARD_BARBADOS_3K_USB_OFFSET_PWR
            # TODO: USB enable by default for now.
            plat_set_usb_power_level  $usb_power_level

            # Expansion module power
            plat_set_em_small_max_power 2700
            plat_set_iox_internal_device_list
            ;;
        # 3KH_ID, 4800AP, BARBADOS4K_BOARD_ID
        0x26)
            echo 3KH > ${DST_DIR}/board_name

            #
            # Generate all additional board info based on boardid below
            #

            # POE stuff (in Deciwatts)
            plat_set_default_poe_max $BOARD_BARBADOS_A_PWR
            plat_set_default_upoe_power_max $BOARD_BARBADOS_A_PWR

            # PHY stuff
            echo 5 > ${DST_DIR}/phy_serdes_0
            echo 6 > ${DST_DIR}/phy_serdes_1
            echo 28 > ${DST_DIR}/phy_pc_bit
            echo 43 > ${DST_DIR}/phy_irq_line
            # Radio stuff
            echo 3 > ${DST_DIR}/max_radios
            echo 2 > ${DST_DIR}/halo_radio_id

            touch ${DST_DIR}/has_usb
            plat_set_usb_small_max_power 2500
            plat_set_usb_offset_power $BOARD_BARBADOS_A_USB_OFFSET_PWR
            enumerate_internal_iot
            # TODO: USB enable by default for now.
            plat_set_usb_power_level $usb_power_level
            # AOA
            touch ${DST_DIR}/aoa_capable

            plat_set_iox_internal_device_list /dev/ttyXRUSB0
            ;;
        # Duplo
        0x27)
            echo duplo > ${DST_DIR}/board_name

            # POE stuff (in Deciwatts)
            ap_type=`cat /AP_TYPE_NAME_STR`
            plat_set_default_poe_max $BOARD_DUPLO_PWR
            plat_set_default_upoe_power_max $BOARD_DUPLO_UPOE_PWR

            echo "gpio_enable=54 gpio_overcurrent=9" > ${DST_DIR}/has_usb
            plat_set_usb_small_max_power 4500
            plat_set_usb_offset_power $BOARD_DUPLO_USB_OFFSET_PWR
            plat_set_usb_power_level $usb_power_level

            # Radio stuff
            echo 2 > ${DST_DIR}/max_radios

            touch ${DST_DIR}/has_pse
            # Support antenna detection
            touch ${DST_DIR}/antenna_detection

            # Duplo+'s uboot is not bundled in rootfs, remove Barbados uboot image for avoiding burning
	    # wrong uboot into Duplo+
            if [ `parse_cmdline_value board_rev` == 1 ]; then
                rm -f /lib/firmware/btldr_DEV.img /lib/firmware/btldr.img 
                mv /lib/firmware/base-part-ubifs-1GB.img.bz2 /lib/firmware/base-part-ubifs.img.bz2
            fi
            plat_set_iox_internal_device_list
            ;;
        *)
            echo unknown > ${DST_DIR}/board_name
            ;;
    esac
    if [ -f ${DST_DIR}/has_usb ]; then
        plat_set_barbados_iox_external_dev_list
    fi
else
    echo -1 > ${DST_DIR}/board_id
    error_action "Unknown board id"
fi

for port in $(seq $MIN_IF_NUM $MAX_IF_NUM); do
    val="`cmdline_get_phy_type $port`"
    if [ ! -z "$val" ]; then
        echo $val > ${DST_DIR}/phy${port}_type
    fi
done

# $1 - wiredX
# $2 - portX
create_port_mappings () {
    echo ${2} > ${DST_DIR}/wired${1}_port
    echo wired${1} > ${DST_DIR}/nic${2}
    if [ ! -f ${DST_DIR}/wired${1} ]; then
        echo nic${2} > ${DST_DIR}/wired${1}
    fi
}

# $1 - portX
remove_created_port_mapping ()
{
    local wired
    local port

    rm -f ${DST_DIR}/nic${1}
    for wired in $(seq $MIN_IF_NUM $MAX_IF_NUM); do
        port="`cat ${DST_DIR}/wired${wired}_port 2> /dev/null`"
        if [ ! -z "$port" -a "$port" == "$1" ]; then
            rm -f ${DST_DIR}/wired${1}_port
            rm -f ${DST_DIR}/wired${1}
        fi
    done
}

dump_port_mapping ()
{
    local wired
    local port

    for wired in $(seq $MIN_IF_NUM $MAX_IF_NUM); do
        port="`cat ${DST_DIR}/wired${wired}_port 2> /dev/null`"
        if [ ! -z "$port" ]; then
            echo "wired${wired} -> port${port}"
        fi
    done
}

port_map=0
for wired in $(seq $MIN_IF_NUM $MAX_IF_NUM); do
    val="`cmdline_get_wired_interface $wired`"
    if [ ! -z "$val" ]; then
        if [ $val -gt $MAX_IF_NUM ]; then
            error_action "Invalid port ${val}"
        elif [ "$((port_map & (1<<val)))" -ne 0 ]; then
            error_action "Duplicate mapping of port${val} to wired${wired}"
        else
            create_port_mappings $wired $val
            port_map="$((port_map | (1 << val)))"
        fi
    fi
done

val="`cmdline_get_nss_interface_map`"
if [ -z "$val" -o $((val)) -eq 0 ]; then
    echo 0 > ${DST_DIR}/mvl_nss_state
    echo disable > ${DST_DIR}/show_nss_state
    echo 0x0 > ${DST_DIR}/nss_interface_map
    touch ${DST_DIR}/nic_mode

    # Old u-boot may not have wiredX param. Create default 3k mapping
    if [ ! -f ${DST_DIR}/wired0_port ]; then
        create_port_mappings 0 0
    fi
    if [ ! -f ${DST_DIR}/wired1_port ]; then
        create_port_mappings 1 1
    fi
else
    echo 1 > ${DST_DIR}/mvl_nss_state
    echo enable > ${DST_DIR}/show_nss_state
    echo $val > ${DST_DIR}/nss_interface_map
    echo nss0 > ${DST_DIR}/wired0
    touch ${DST_DIR}/nss_mode

    # Rewrite port mappings
    for port in $(seq $MIN_IF_NUM $MAX_IF_NUM); do
        if [ "$((val & (1 << port)))" -ne 0 ]; then
            # Old u-boot may not have wiredX param. Create default 3k mapping
            if [ ! -f ${DST_DIR}/nic${port} ]; then
                create_port_mappings $port $port
            fi
        else
            # Remove in case previously created
            remove_created_port_mapping $port
        fi
    done
fi

val="`cmdline_get_detected_expanssion_module`"
if [ ! -z "$val" ]; then
    echo $val > ${DST_DIR}/detected_em
    ln -sf /dev/ttyS2 /dev/ttyNolanEM
fi

val="`cmdline_get_em0_interface`"
if [ ! -z "$val" ]; then
    echo nic${val} > ${DST_DIR}/em0
fi

val="`cmdline_get_poe_max`"
if [ ! -z "$val" ]; then
    # Possible overide
    plat_set_default_poe_max $val
fi
#dump_port_mapping
