#!/bin/bash

LOGFILE="/var/log/inspect.log"

function log_file()
{
    echo [`date`][$$]$@ >> $LOGFILE
}

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

function restore_ifs
{
    IFS=$IFS_OLD
}

function IsRHNode()
{
    local name=''
    name=$(dmidecode -t 1 | grep "Product Name:" | awk '{print $3}')
    if [ "$name" = "RH2288" -o "$name" = "5288" -o "$name" = "RH2288H" ]; then
        return 0
    else
        return 1
    fi
}

function GetEthName()
{
    local descrip=$*
    EthArray=("BCM5716" "I350" "T420" "T520" "82599EB" "MT27630" "MT27500")
    for item in ${EthArray[*]}; do
        echo "$descrip" | grep $item > /dev/null
        if [ $? -eq 0 ];then
            echo "$item"
            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_file "[$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_file "[$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_file "[$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_file "[$FUNCNAME][$LINENO]BdfNumber=$BdfNumber,EthSpeed=$EthSpeed,EthWidth=$EthWidth;EthStdSpeed=$EthStdSpeed,EthStdWidth=$EthStdWidth"
        
        if [ ${EthSpeed} != ${EthStdSpeed} ] && [ $EthWidth != $EthStdWidth ]; then
            echo "[ERR]BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) and bit width ($EthWidth) of the NIC are not ($EthStdSpeed) and ($EthStdWidth) as expected.ERRCODE(5)"
            iRet=1
        elif [ ${EthSpeed} != ${EthStdSpeed} ];then
            echo "[ERR]BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) of the NIC is not ($EthStdSpeed) as expected.ERRCODE(6)"
            iRet=1
        elif [ $EthWidth != $EthStdWidth ];then
            echo "[ERR]BDF($BdfNumber). Actual bit width ($EthWidth) of the NIC is not ($EthStdWidth) as expected.ERRCODE(7)"
            iRet=1
        fi
        echo "Name:$EthName||BDF:$BdfNumber||Speed:$EthSpeed||Width:$EthWidth"       
    done
    
    if [ $IsExist -eq 0 ];then
        echo "[ERR]No matched NIC!.ERRCODE(4)"
        iRet=1
    fi
    return $iRet
}

function CheckT3000Speed
{
    local EthInfo=""
    local iRet=0
    local IsExist=0
    EthInfo=`lspci | grep -w Ethernet | grep -v "Virtual"`  
    if [ "$EthInfo" = "" ];then
        log_file "[$FUNCNAME][$LINENO]exec command failed!(lspci | grep Ethernet)"
        echo "[ERR]No matched NIC!ERRCODE(4)"
        iRet=1
        return $iRet
    fi
    #no duplicate info,get last line
    tmpInfo=`echo "$EthInfo" | awk -F: 'BEGIN{} {if($1 in array){next;}else{array[$1]=$0;}} END{for(x in array) print array[x];}'`
    set_ifs
    for line in $tmpInfo;do
        #ȡBDF
        BdfNumber=`echo $line | awk '{print $1}'`
        #ȡ
        EthName=`GetEthName "${line}"`
        if [ $EthName = "NULL" ];then
            log_file "[$FUNCNAME][$LINENO]name info($line),get EthName failed!"
            continue
        else
            IsExist=1
        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_file "[$FUNCNAME][$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_file "[$FUNCNAME][$LINENO]BdfNumber=$BdfNumber,EthSpeed=$EthSpeed,EthWidth=$EthWidth;EthStdSpeed=$EthStdSpeed,EthStdWidth=$EthStdWidth"
        
        if [ ${EthSpeed} != ${EthStdSpeed} ] && [ $EthWidth != $EthStdWidth ]; then
            echo "[ERR]BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) and bit width ($EthWidth) of the NIC are not ($EthStdSpeed) and ($EthStdWidth) as expected.ERRCODE(5)"
            iRet=1
        elif [ ${EthSpeed} != ${EthStdSpeed} ];then
            echo "[ERR]BDF($BdfNumber). Actual PCIe negotiation rate ($EthSpeed) of the NIC is not ($EthStdSpeed) as expected.ERRCODE(6)"
            iRet=1
        elif [ $EthWidth != $EthStdWidth ];then
            echo "[ERR]BDF($BdfNumber). Actual bit width ($EthWidth) of the NIC is not ($EthStdWidth) as expected.ERRCODE(7)"
            iRet=1
        fi
        
        echo "Name:$EthName||BDF:$BdfNumber||Speed:$EthSpeed||Width:$EthWidth"
    done
    restore_ifs
    if [ $IsExist -eq 0 ];then
        echo "[ERR]No matched NIC!ERRCODE(4)"
        iRet=1
    fi
    return $iRet
}

function CheckPcieSpeed()
{   
    local iRet=0
    IsRHNode
    if [ $? -eq 0 ]; then       
        CheckRHSpeed
    else
        CheckT3000Speed
    fi
    iRet=$?
    return $iRet
}


CheckPcieSpeed
exit 0