#!/usr/bin/bash

# Copyright (c) 2018, Mellanox Technologies
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of the FreeBSD Project.

# Arrays are bash specific so this script requires bash.

bffamily_version=1.0
BF1_PLATFORM_ID=0x00000211
BF2_PLATFORM_ID=0x00000214
BF3_PLATFORM_ID=0x0000021c

usage()
{
  echo "syntax: bffamily [--help|-h] [--chip] [--version|-v]"
}

show_chip()
{
  if grep -q TH500 /sys/firmware/acpi/tables/DSDT 2>/dev/null; then
    echo "BlueField-4"
  elif grep -q "MLNXBF33" /sys/firmware/acpi/tables/SSDT* 2>/dev/null; then
    echo "BlueField-3"
  elif grep -q "MLNXBF22" /sys/firmware/acpi/tables/SSDT* 2>/dev/null; then
    echo "BlueField-2"
  elif grep -q "MLNXBF02" /sys/firmware/acpi/tables/SSDT* 2>/dev/null; then
    echo "BlueField-1"
  else
    echo "Unknown"
  fi
}

options=$(getopt -n bffamily -o chv -l chip,help,version -- "$@")
eval set -- "$options"
while [ "$1" != -- ]; do
  case $1 in
    --help|-h) usage; exit 0;;
    --chip|-c) show_chip; exit 0;;
    --version|-v) echo "$0 version '$bffamily_version'"; exit 0 ;;
  esac
  shift
done
shift

bfversion=$(bfhcafw mcra 0xf0014.0:16 2>/dev/null)

if [[ "$bfversion" = "$BF1_PLATFORM_ID" ]]; then
    # map product family names to an appropriate regular expressions
    declare -A PRODUCT_FAMILY_MAP=(
        ["Bluewhale"]="MBE(11|12)0(0|1)[A-F]-(BC|BN)[0-9]"
        ["SmartNIC/Bekka"]="MBF1(L|M)332A-(AF|AE|AS|AT)(NAT|CAT)"
        ["Lamina SmartNIC 100G"]="MBF1L516A-(ES|CS)(NAT|CAT)"
        ["Tresnis"]="MBF1L516B-(ES|CS)(NAT|CAT)"
        ["Sella BF1600"]="MBF1M6[A-F0-9]6A-(CS|CE)(NAT|CAT|NAN)"
        ["Sella-SmartNIC/Follera"]="MBF1L666A-ES(CAT|NAT)"
        ["Denarious"]="MBF1M216A-CSNAT_C16"
        ["Poondion"]="MBF1M706A-CSNAT_C15"
        ["Poondion BF1700"]="MBF1M716A-CSNAT"
    )
    PART_NUMBER=$(lspci -s "$(bfhcafw bus)" -vv | grep PN)

elif [[ "$bfversion" = "$BF2_PLATFORM_ID" ]]; then
    # map product family names to an appropriate regular expressions
    declare -A PRODUCT_FAMILY_MAP=(
        ["EVB"]="MBF2-EVB"
        ["Camelot"]="(MBF2(H|M)5(26A|16A|25A|15A))|03GX455|SN37A98074"
        ["Atlantis"]="(MBF2(H|M)(322A|332A))|03GX454|SN37A98073"
        ["Arcadia OCP 3.0"]="MBF2M(922|912)A"
        ["Asgard"]="MBF2H51(5|6)B"
        ["BlueForce"]="BLUEFORCE_IPN"
        ["BlueSphere"]="(MBS2M512(A|C)|BS2M512A)"
        ["PRIS"]="699210020215"
        ["Camelantis"]="MBF2H5(1|3)2C"
        ["Aztlan"]="(MBF2(H51|M51|H53)6C)|0PXDVR|(30-100(299|300)-01)"
        ["OVH"]="SSN4MELX100200"
        ["Dell-Camelantis"]="0JNDCM"
        ["El-Dorado"]="MBF2M3(4|5)5A"
        ["Roy"]="6992100402(05|06|30|31)"
        ["ZAM"]="699140280000"
    )
    PART_NUMBER=$(bfhcafw flint q full | grep "Part Number:" | cut -f 2 -d ":" | xargs)

elif [[ "$bfversion" = "$BF3_PLATFORM_ID" ]]; then

    # map product family names to an appropriate regular expressions
    declare -A PRODUCT_FAMILY_MAP=(
        ["EVB"]="MBF3-(DDR4-EVB|EVB-SKT|EVB)"
	["Moonraker"]="(900-9D3(B|C|L)|SN37B36732|SN37B75411|SN37C16116|8217991|8225672|P66102|0WJ9T5|0HFWRM)"
	["Goldeneye"]="(900-9D3D|P66584|0KK4NR|06CMW1)"
	["Roy"]="699-21014-0230"
	["Zhora"]="800-11012-0000-000"
    )
    PART_NUMBER=$(lspci -s "$(bfhcafw bus)" -vv | grep PN)

else
    echo "Unknown platform"
    exit 1
fi

for family_name in "${!PRODUCT_FAMILY_MAP[@]}"
do
    PN=$(echo "$PART_NUMBER" | grep -oE "${PRODUCT_FAMILY_MAP[$family_name]}" 2>/dev/null)

    if [ -n "$PN" ]
    then
        echo "$family_name"
        exit 0
    fi
done

echo "Unknown Product Family"

exit 1
