#!/bin/bash
set +x
. /opt/node_type_recognize.sh
G_MML_FILE_PATH="/opt/huawei/snas/script/inspect_mml"
G_SCRIPT_PATH="/opt/inspect"
source $G_MML_FILE_PATH/CheckItems
. $G_SCRIPT_PATH/inspect_map.sh
CurInspectNum="144"
CurInspectFun="$(GetInspectType $CurInspectNum)"
RESULTFILE="/tmp/tmpResult${CurInspectFun}"
LOG_FILE="/var/log/inspect.log"
>${RESULTFILE}

isPass=0

function LOG
{
   time=$(date)
   echo [${time}][$$][${CurInspectFun}]$@ >> ${LOG_FILE}
}

function set_ifs
{
    IFS_OLD=$IFS
    IFS=$'\n'
}

function restore_ifs
{
    IFS=$IFS_OLD
}

function GetEthName()
{
    local descrip=$*
    EthArray=("BCM5716" "I350" "T420" "T520" "82599EB" "MT27630" "MT27500" "MT27710" "I354" "82599ES" "SGMII" "X722" "Hi1822" "Huawei Technologies Co.")
    for item in ${EthArray[*]}; do
        echo "$descrip" | grep $item > /dev/null
        if [ $? -eq 0 ];then
            if [ "$item" = "Huawei Technologies Co." ];then
                echo "Kunpeng 920"
            else
                echo "$item"
            fi
            return 0
        fi
    done
    echo "NULL"
    return 1
}

function CpuBdfMapDevice()
{
    local condition=$1
    case $condition in
        "00:03.0" | "00:03.2" )
            filter="[0000:00]"
            ;;
        "80:01.0" | "80:02.0")
            filter="[0000:80]"
            ;;
    esac
    CpuDevFunNum=`echo ${condition:3:4}`
    #get text range for [0000:80] or [0000:00]
    EthText=`lspci -tv |awk -v tmpfilter=$filter '{ if(index($0,tmpfilter)){flag=1;print $0;next;};strtmp=substr($0,4,1);if(flag==1&&strtmp == "["){flag=0;};if(flag==1)print $0;}'`
    oneline=`echo "$EthText" | grep "+-${CpuDevFunNum}-"`
    BusNum=`echo ${oneline:21:2}`
    DevFunNum=`echo "${oneline}" | awk '{Len=length($1);print substr($1,Len-3,4)}'`
    tmpNum=`echo ${BusNum}:${DevFunNum}`
    BdfNum=`echo $tmpNum | grep ^[0-9][0-9][:][0-9][0-9][.][0-9]$`
    BdfLength=${#BdfNum}
    if [  $BdfLength -eq 7 ];then
        echo $BdfNum
        return 0
    else
        echo "NULL"
        return 1
    fi
}


function CheckRHSpeed
{
    local iRet=0
    local IsExist=0
    CpuBdfArray=("00:03.0" "00:03.2" "80:01.0" "80:02.0")
    for item in ${CpuBdfArray[*]};do

        BdfNumber=`CpuBdfMapDevice ${item}`
        if [ "$BdfNumber" = "NULL" ];then
            LOG "[$FUNCNAME][$LINENO]item=$item,device BDF number error!!"
            continue
        else
            IsExist=1
        fi
        Ethline=`lspci -s ${BdfNumber} -vvv | head -1`
        #ȡ
        EthName=`GetEthName "$Ethline"`

        if [ "$EthName" = "NULL" ];then
            LOG "[$FUNCNAME][$LINENO]name info($Ethline),get EthName failed!"
            continue
        fi
        #ȡʵЭʺλ
        EthSpeed=`lspci -s ${BdfNumber} -vvv | grep -w 'LnkSta:' | awk -F, '{print $1}' | awk '{print $3}'`
        EthWidth=`lspci -s ${BdfNumber} -vvv | grep -w 'LnkSta:' | awk -F, '{print $2}' | awk '{print $2}'`
        #ȡı׼Эʺλ
        EthStdSpeed=`lspci -s ${BdfNumber} -vvv | grep -w 'LnkCap:' | awk -F, '{print $2}' | awk '{print $2}'`
        if [ "$EthStdSpeed" = "unknown" ];then
            LOG "[$FUNCNAME][$LINENO]item=$item, no get Eth Standard Speed !"
            continue
        fi
        EthStdWidth=`lspci -s ${BdfNumber} -vvv | grep -w 'LnkCap:' | awk -F, '{print $3}' | awk '{print $2}'`
        LOG "[$FUNCNAME][$LINENO]BdfNumber=$BdfNumber,EthSpeed=$EthSpeed,EthWidth=$EthWidth;EthStdSpeed=$EthStdSpeed,EthStdWidth=$EthStdWidth"

        if [ "${EthSpeed}" != "${EthStdSpeed}" ] && [ "$EthWidth" != "$EthStdWidth" ]; then
            isPass=1
            echo "[ERR]INFO:BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) and bit width ($EthWidth) of the NIC are not ($EthStdSpeed) and ($EthStdWidth) as expected"  >>${RESULTFILE}
            iRet=1
        elif [ "${EthSpeed}" != "${EthStdSpeed}" ];then
            isPass=1
            echo "[ERR]INFO:BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) of the NIC is not ($EthStdSpeed) as expected"    >>${RESULTFILE}
            iRet=1
        elif [ "$EthWidth" != "$EthStdWidth" ];then
            isPass=1
            echo "[ERR]INFO:BDF($BdfNumber). Actual bit width ($EthWidth) of the NIC is not ($EthStdWidth) as expected"  >>${RESULTFILE}
            iRet=1
        fi
        echo "Name:$EthName||BDF:$BdfNumber||Speed:$EthSpeed||Width:$EthWidth||status:pass"  >>${RESULTFILE}
    done

    if [ $IsExist -eq 0 ];then
        isPass=1
        echo "[ERR]INFO:No matched NIC!" >>${RESULTFILE}
        iRet=1
    fi
    return $iRet
}

function CheckT3000Speed
{
    local EthInfo=""
    local iRet=0
    local IsExist=0
    local IsC72=0
    IsC72Node
    IsC72=$?
    EthInfo=`lspci -D | grep -w Ethernet | grep -v "Virtual"`
    if [ "$EthInfo" = "" ];then
        LOG "[$LINENO]exec command failed!(lspci | grep Ethernet)"
        isPass=1
        echo "[ERR]INFO:No matched NIC from command(lspci -D | grep -w Ethernet | grep -v Virtual)!" >>${RESULTFILE}
        iRet=1
        return $iRet
    fi
    #no duplicate info,get last line
    tmpInfo=`echo "$EthInfo" | awk -F: 'BEGIN{} {if($2 in array){next;}else{array[$2]=$0;}} END{for(x in array) print array[x];}'`
    set_ifs
    for line in $tmpInfo;do
        #ȡBDF
        BdfNumber=`echo $line | awk '{print $1}' | cut -d: -f2,3`
        #ȡ
        EthName=`GetEthName "${line}"`
        if [ "$EthName" = "NULL" ];then
            LOG "[$LINENO]name info($line),get EthName failed!"
            continue
        else
            IsExist=1
        fi
        #C72I354SGMIIҪЭʺλ
        if [ ${IsC72} -eq 0 ] && [ "${EthName}" = "I354" -o "${EthName}" = "SGMII" ]; then
            LOG "[$LINENO]c72 node ${EthName} no need to check!"
            echo "Name:$EthName||BDF:$BdfNumber||Speed:--||Width:--||status:no need to check!"  >>${RESULTFILE}
            continue
        fi
        #ȡʵЭʺλ
        EthSpeed=`lspci -s ${BdfNumber} -vvv |grep -w 'LnkSta:' | awk -F, '{print $1}' | awk '{print $3}'`
        EthWidth=`lspci -s ${BdfNumber} -vvv |grep -w 'LnkSta:' | awk -F, '{print $2}' | awk '{print $2}'`
        #ȡı׼Эʺλ
        EthStdSpeed=`lspci -s ${BdfNumber} -vvv |grep -w 'LnkCap:' | awk -F, '{print $2}' | awk '{print $2}'`
        if [ "$EthStdSpeed" = "unknown" ];then
            LOG "[$LINENO]BdfNumber=$BdfNumber, no get Eth Standard Speed !"
            continue
        fi
        EthStdWidth=`lspci -s ${BdfNumber} -vvv |grep -w 'LnkCap:' | awk -F, '{print $3}' | awk '{print $2}'`
        LOG "[$LINENO]BdfNumber=$BdfNumber,EthSpeed=$EthSpeed,EthWidth=$EthWidth;EthStdSpeed=$EthStdSpeed,EthStdWidth=$EthStdWidth"

        if [ "${EthSpeed}" != "${EthStdSpeed}" ] && [ "$EthWidth" != "$EthStdWidth" ]; then
            isPass=1
            echo "[ERR]INFO:BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) and bit width ($EthWidth) of the NIC are not ($EthStdSpeed) and ($EthStdWidth) as expected"    >>${RESULTFILE}
            iRet=1
        elif [ "${EthSpeed}" != "${EthStdSpeed}" ];then
            isPass=1
            echo "[ERR]INFO:BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) of the NIC is not ($EthStdSpeed) as expected"  >>${RESULTFILE}
            iRet=1
        elif [ "$EthWidth" != "$EthStdWidth" ];then
            isPass=1
            echo "[ERR]INFO:BDF($BdfNumber). Actual bit width ($EthWidth) of the NIC is not ($EthStdWidth) as expected"  >>${RESULTFILE}
            iRet=1
        fi

        echo "Name:$EthName||BDF:$BdfNumber||Speed:$EthSpeed||Width:$EthWidth||status:pass" >>${RESULTFILE}
    done
    restore_ifs
    if [ $IsExist -eq 0 ];then
        isPass=1
        echo "[ERR]INFO:No matched NIC!" >>${RESULTFILE}
        iRet=1
    fi
    return $iRet
}

function CheckPcieSpeed()
{
    local iRet=0
    IsStandardNode
    iRet=$?
    if [ ${iRet} -eq 0 ];then
        echo "Name:--||BDF:--||Speed:--||Width:--||status:Do not involve(VM)." >>${RESULTFILE}
        return ${iRet}
    fi
    IsRHV3Node
    if [ $? -eq 0 ]; then
        CheckRHSpeed
    else
        #V5ARMT3000Ĵ
        CheckT3000Speed
    fi
    iRet=$?
    return $iRet
}


CheckPcieSpeed
echo "${CurInspectFun}_Pass $isPass" >>${RESULTFILE}
exit 0