#!/bin/bash debug_flag=0 port_map=('00' '10' '11' '12' '13' '14' '15' '16' '17' '18' '19' '20' '21' '22' '23' '24' '25' '26' '27' '28' '29' '30' '31' '32' '33' '34' '35' '36' '37' '38' '39' '40' '41') port_1_8_presence=0 port_9_16_presence=0 port_17_24_presence=0 port_25_32_presence=0 port_1_8_reset=0 port_9_16_reset=0 port_17_24_reset=0 port_25_32_reset=0 result=0 #$1=dev_addr, $2=reg, $3=val bmc_write() { addr_8b=$(echo $(($1)) | awk '{printf $1}') addr_8b=`expr $addr_8b \\* 2` ipmitool raw 0x06 0x52 0x05 $addr_8b 0 $2 $3 1>>/dev/null 2>>/dev/null } #$1=dev_addr, $2=reg, $3=len bmc_read() { addr_8b=$(echo $(($1)) | awk '{printf $1}') addr_8b=`expr $addr_8b \\* 2` val=$(ipmitool raw 0x06 0x52 0x05 $addr_8b $3 $2 2>>/dev/null) if [ $? -eq 0 ];then result=$val return 1 else return 0 fi } bmc_qsfp_presence_read() { val=$(ipmitool raw 0x30 0x92 2>>/dev/null) if [ $? -eq 0 ];then port_1_8_presence=$(echo $val | awk '{printf $36}') port_9_16_presence=$(echo $val | awk '{printf $37}') port_17_24_presence=$(echo $val | awk '{printf $40}') port_25_32_presence=$(echo $val | awk '{printf $41}') port_1_8_presence=$( printf "%d" 0x$port_1_8_presence ) port_9_16_presence=$( printf "%d" 0x$port_9_16_presence ) port_17_24_presence=$( printf "%d" 0x$port_17_24_presence ) port_25_32_presence=$( printf "%d" 0x$port_25_32_presence ) return 1 fi return 0 } bmc_qsfp_reset_read() { val=$(ipmitool raw 0x30 0x92 2>>/dev/null) if [ $? -eq 0 ];then port_1_8_reset=$(echo $val | awk '{printf $38}') port_9_16_reset=$(echo $val | awk '{printf $39}') port_17_24_reset=$(echo $val | awk '{printf $42}') port_25_32_reset=$(echo $val | awk '{printf $43}') port_1_8_reset=$( printf "%d" 0x$port_1_8_reset ) port_9_16_reset=$( printf "%d" 0x$port_9_16_reset ) port_17_24_reset=$( printf "%d" 0x$port_17_24_reset ) port_25_32_reset=$( printf "%d" 0x$port_25_32_reset ) return 1 fi return 0 } #$1=port_no bmc_qsfp_reset_write() { local port=$1 val=$(ipmitool raw 0x30 0x92 2>>/dev/null) if [ $? -eq 0 ];then ori_1_8_reset=$(echo $val | awk '{printf $38}') ori_9_16_reset=$(echo $val | awk '{printf $39}') ori_17_24_reset=$(echo $val | awk '{printf $42}') ori_25_32_reset=$(echo $val | awk '{printf $43}') ori_1_8_reset=$( printf "%d" 0x$ori_1_8_reset ) ori_9_16_reset=$( printf "%d" 0x$ori_9_16_reset ) ori_17_24_reset=$( printf "%d" 0x$ori_17_24_reset ) ori_25_32_reset=$( printf "%d" 0x$ori_25_32_reset ) else return 0 fi port=`expr $port - 1` port_blk=0 port_blk=`expr $port / 8` bit_idx=`expr $port % 8` bit_idx=$((1<<$bit_idx)) if [ $port_blk -eq 1 ];then tmp_1_8_reset=$(($ori_1_8_reset ^ $bit_idx)) elif [ $port_blk -eq 2 ];then tmp_9_16_reset=$(($ori_9_16_reset ^ $bit_idx)) elif [ $port_blk -eq 3 ];then tmp_17_24_reset=$(($ori_17_24_reset ^ $bit_idx)) else tmp_25_32_reset=$(($ori_25_32_reset ^ $bit_idx)) fi #set to reset state ipmitool raw 0x30 0x91 $tmp_1_8_reset $tmp_9_16_reset $tmp_17_24_reset $tmp_25_32_reset 1>>/dev/null 2>>/dev/null #set back to normal state ipmitool raw 0x30 0x91 $ori_1_8_reset $ori_9_16_reset $ori_17_24_reset $ori_25_32_reset 1>>/dev/null 2>>/dev/null } #$1=port_no bmc_qsfp_eeprom_read() { local port=$1 local eeprom_low local eeprom_pg0 local eeprom_pg2 local eeprom_pg3 local eeprom_pg11 port=`expr $port - 1` i2cmux_dev=0 i2cmux_dev=`expr $port / 8` i2cmux_dev=`expr $i2cmux_dev + $((0x72))` ch=`expr $port % 8` ch=$((1<<$ch)) bmc_write $i2cmux_dev 0x00 $ch bmc_write 0x50 0x7f 0x00 #QSFP-DD low page bmc_read 0x50 0 128 if [ $? -eq 1 ];then eeprom_low=$result else bmc_write $i2cmux_dev 0x00 0x0 return 1 fi #QSFP-DD page0 bmc_read 0x50 128 128 if [ $? -eq 1 ];then eeprom_pg0=$result else bmc_write $i2cmux_dev 0x00 0x0 return 1 fi #QSFP-DD page1 bmc_write 0x50 0x7f 0x01 bmc_read 0x50 128 128 if [ $? -eq 1 ];then eeprom_pg1=$result else bmc_write $i2cmux_dev 0x00 0x0 return 1 fi #QSFP-DD page2 bmc_write 0x50 0x7f 0x02 bmc_read 0x50 128 128 if [ $? -eq 1 ];then eeprom_pg2=$result else bmc_write $i2cmux_dev 0x00 0x0 return 1 fi #QSFP-DD page3 bmc_write 0x50 0x7f 0x03 bmc_read 0x50 128 128 if [ $? -eq 1 ];then eeprom_pg3=$result else bmc_write $i2cmux_dev 0x00 0x0 return 1 fi #QSFP-DD page11 bmc_write 0x50 0x7f 0x11 bmc_read 0x50 128 128 if [ $? -eq 1 ];then eeprom_pg11=$result else bmc_write $i2cmux_dev 0x00 0x0 return 1 fi sfp_type=$(echo $eeprom_low | awk '{printf $1}') sfp_type=$( printf "%d" 0x$sfp_type ) #get temperature temp=$(echo $eeprom_low | awk '{printf $15}') if [ $temp != "" ];then temp=$( printf "%d" 0x$temp ) temp_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/temp" echo $temp > $temp_path fi #get lp_mode lpmod_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/lp_mode" if [ $sfp_type -eq 24 ];then lpmod=$(echo $eeprom_low | awk '{printf $27}') if [ $lpmod != "" ];then state=$((lpmod&0x10)) if [ $state -eq 16 ];then echo 1 > $lpmod_path else echo 0 > $lpmod_path fi fi elif [ $sfp_type -eq 17 ];then lpmod=$(echo $eeprom_low | awk '{printf $93}') if [ $lpmod != "" ];then state=$((lpmod&0x02)) if [ $state -eq 2 ];then echo 1 > $lpmod_path else echo 0 > $lpmod_path fi fi else lpmod="" fi eeprom_low=$(echo $eeprom_low | sed 's/[[:space:]]//g') eeprom_pg0=$(echo $eeprom_pg0 | sed 's/[[:space:]]//g') eeprom_pg1=$(echo $eeprom_pg1 | sed 's/[[:space:]]//g') eeprom_pg2=$(echo $eeprom_pg2 | sed 's/[[:space:]]//g') eeprom_pg3=$(echo $eeprom_pg3 | sed 's/[[:space:]]//g') eeprom_pg11=$(echo $eeprom_pg11 | sed 's/[[:space:]]//g') if [ $debug_flag -eq 0 ];then eeprom_low_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_low" eeprom_low=$(echo $eeprom_low | sed -e 's/ //g') echo $eeprom_low > $eeprom_low_path eeprom_pg0_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg0" eeprom_pg0=$(echo $eeprom_pg0 | sed -e 's/ //g') echo $eeprom_pg0 > $eeprom_pg0_path eeprom_pg1_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg1" eeprom_pg1=$(echo $eeprom_pg1 | sed -e 's/ //g') echo $eeprom_pg1 > $eeprom_pg1_path eeprom_pg2_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg2" eeprom_pg2=$(echo $eeprom_pg2 | sed -e 's/ //g') echo $eeprom_pg2 > $eeprom_pg2_path eeprom_pg3_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg3" eeprom_pg3=$(echo $eeprom_pg3 | sed -e 's/ //g') echo $eeprom_pg3 > $eeprom_pg3_path eeprom_pg11_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg11" eeprom_pg11=$(echo $eeprom_pg11 | sed -e 's/ //g') echo $eeprom_pg11 > $eeprom_pg11_path else printf "\nPort %d EEPROM:" $1 printf "\nLow--------------------------------------------\n" for i in $(seq 1 128); do printf "%s " ${eeprom_low:0:2} eeprom_low=$(echo $eeprom_low | sed 's/^..//') val=`expr $i % 16` if [ $val -eq 0 ];then printf "\n" fi done printf "\n-----------------------------------------------\n" printf "Page0------------------------------------------\n" for i in $(seq 1 128); do printf "%s " ${eeprom_pg0:0:2} eeprom_pg0=$(echo $eeprom_pg0 | sed 's/^..//') val=`expr $i % 16` if [ $val -eq 0 ];then printf "\n" fi done printf "\n-----------------------------------------------\n" printf "Page1------------------------------------------\n" for i in $(seq 1 128); do printf "%s " ${eeprom_pg1:0:2} eeprom_pg0=$(echo $eeprom_pg1 | sed 's/^..//') val=`expr $i % 16` if [ $val -eq 0 ];then printf "\n" fi done printf "\n-----------------------------------------------\n" printf "Page2------------------------------------------\n" for i in $(seq 1 128); do printf "%s " ${eeprom_pg2:0:2} eeprom_pg2=$(echo $eeprom_pg2 | sed 's/^..//') val=`expr $i % 16` if [ $val -eq 0 ];then printf "\n" fi done printf "\n-----------------------------------------------\n" printf "Page3------------------------------------------\n" for i in $(seq 1 128); do printf "%s " ${eeprom_pg3:0:2} eeprom_pg3=$(echo $eeprom_pg3 | sed 's/^..//') val=`expr $i % 16` if [ $val -eq 0 ];then printf "\n" fi done printf "\n-----------------------------------------------\n" printf "Page11-----------------------------------------\n" for i in $(seq 1 128); do printf "%s " ${eeprom_pg11:0:2} eeprom_pg11=$(echo $eeprom_pg11 | sed 's/^..//') val=`expr $i % 16` if [ $val -eq 0 ];then printf "\n" fi done printf "\n-----------------------------------------------\n" fi bmc_write $i2cmux_dev 0x00 0x0 return 0 } #$1=port_no bmc_qsfp_eeprom_clear() { eeprom_low_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_low" echo "" > $eeprom_low_path eeprom_pg0_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg0" echo "" > $eeprom_pg0_path eeprom_pg1_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg1" echo "" > $eeprom_pg1_path eeprom_pg2_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg2" echo "" > $eeprom_pg2_path eeprom_pg3_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg3" echo "" > $eeprom_pg3_path eeprom_pg11_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom_pg11" echo "" > $eeprom_pg11_path } QSFP_monitor() { while true do if [ -e /sys/bus/i2c/devices/0-0061/module_present_1 ] && [ -e /sys/bus/i2c/devices/0-0062/module_present_32 ] && [ -e /sys/bus/i2c/devices/0-0041/eeprom_low ];then bmc_qsfp_presence_read mod_presence=$((port_25_32_presence<<8)) mod_presence=`expr $mod_presence + $port_17_24_presence` mod_presence=$((mod_presence<<8)) mod_presence=`expr $mod_presence + $port_9_16_presence` mod_presence=$((mod_presence<<8)) mod_presence=`expr $mod_presence + $port_1_8_presence` for i in $(seq 1 32); do idx=`expr $i - 1` check_bit=$((1<<$idx)) is_presence=$(($mod_presence & $check_bit)) if [ $i -le 16 ];then cpld_path="/sys/bus/i2c/devices/0-0061/" else cpld_path="/sys/bus/i2c/devices/0-0062/" fi if [ $is_presence -eq 0 ];then bmc_qsfp_eeprom_read $i if [ $? -eq 0 ];then echo 1 > $cpld_path"module_present_"$i fi else echo 0 > $cpld_path"module_present_"$i bmc_qsfp_eeprom_clear $i fi done sleep 5 else sleep 1 fi done } QSFP_monitor