480 lines
11 KiB
Plaintext
480 lines
11 KiB
Plaintext
|
#!/bin/bash
|
||
|
|
||
|
debug_flag=0
|
||
|
port_map=('00' '10' '11' '12' '13' '14' '15' '16' '17' '18' '19' '1a' '1b' '1c' '1d' '1e' '1f' '20' '21' '22' '23' '24' '25' '26' '27' '28' '29' '2a' '2b' '2c' '2d' '2e' '2f')
|
||
|
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
|
||
|
pre_port_1_8_reset=256
|
||
|
pre_port_9_16_reset=256
|
||
|
pre_port_17_24_reset=256
|
||
|
pre_port_25_32_reset=256
|
||
|
pre_port_1_8_lpmode=256
|
||
|
pre_port_9_16_lpmode=256
|
||
|
pre_port_17_24_lpmode=256
|
||
|
pre_port_25_32_lpmode=256
|
||
|
pre_port_1_8_modsel=256
|
||
|
pre_port_9_16_modsel=256
|
||
|
pre_port_17_24_modsel=256
|
||
|
pre_port_25_32_modsel=256
|
||
|
|
||
|
byte_hex_test()
|
||
|
{
|
||
|
if ! [[ $1 =~ ^[0-9A-Fa-f]{2}$ ]] ; then
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
#$1=mux $2=channel $3=dev_addr, $4=reg, $5=val
|
||
|
bmc_write()
|
||
|
{
|
||
|
addr_8b=$(echo $(($3)) | awk '{printf $1}')
|
||
|
addr_8b=`expr $addr_8b \\* 2`
|
||
|
ipmitool raw 0x30 0x85 $1 $2 $addr_8b 2 $4 $5 1>>/dev/null 2>>/dev/null
|
||
|
sleep 1
|
||
|
ipmitool raw 0x30 0x87 1>>/dev/null 2>>/dev/null
|
||
|
}
|
||
|
|
||
|
#$1=mux $2=channel $3=dev_addr, $4=reg, $5=len
|
||
|
bmc_read()
|
||
|
{
|
||
|
addr_8b=$(echo $(($3)) | awk '{printf $1}')
|
||
|
addr_8b=`expr $addr_8b \\* 2`
|
||
|
ipmitool raw 0x30 0x86 $1 $2 $addr_8b $5 $4 1>>/dev/null 2>>/dev/null
|
||
|
sleep 1
|
||
|
val=$(ipmitool raw 0x30 0x87 2>>/dev/null)
|
||
|
if [ $? -eq 0 ];then
|
||
|
result=$val
|
||
|
return 1
|
||
|
else
|
||
|
return 0
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
bmc_qsfp_lpmode_write()
|
||
|
{
|
||
|
|
||
|
cpld_path="/sys/bus/i2c/devices/0-0006/"
|
||
|
val=0
|
||
|
for i in $(seq 1 8);
|
||
|
do
|
||
|
lpmode_path=$cpld_path"port"$i"_lpmode"
|
||
|
lpmode_input=$(cat $lpmode_path | awk '{printf $1}')
|
||
|
val=$((val | (lpmode_input << ($i - 1))))
|
||
|
done
|
||
|
if [ $val -ne $pre_port_1_8_lpmode ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0c 0x0 0x50 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_1_8_lpmode=$val
|
||
|
fi
|
||
|
val=0
|
||
|
for i in $(seq 9 16);
|
||
|
do
|
||
|
lpmode_path=$cpld_path"port"$i"_lpmode"
|
||
|
lpmode_input=$(cat $lpmode_path | awk '{printf $1}')
|
||
|
val=$((val | (lpmode_input << ($i - 9))))
|
||
|
done
|
||
|
|
||
|
if [ $val -ne $pre_port_9_16_lpmode ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0c 0x0 0x51 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_9_16_lpmode=$val
|
||
|
fi
|
||
|
|
||
|
cpld_path="/sys/bus/i2c/devices/0-0007/"
|
||
|
val=0
|
||
|
for i in $(seq 17 24);
|
||
|
do
|
||
|
lpmode_path=$cpld_path"port"$i"_lpmode"
|
||
|
lpmode_input=$(cat $lpmode_path | awk '{printf $1}')
|
||
|
val=$((val | (lpmode_input << ($i - 17))))
|
||
|
done
|
||
|
|
||
|
if [ $val -ne $pre_port_17_24_lpmode ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0e 0x0 0x50 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_17_24_lpmode=$val
|
||
|
fi
|
||
|
val=0
|
||
|
for i in $(seq 25 32);
|
||
|
do
|
||
|
lpmode_path=$cpld_path"port"$i"_lpmode"
|
||
|
lpmode_input=$(cat $lpmode_path | awk '{printf $1}')
|
||
|
val=$((val | (lpmode_input << ($i - 25))))
|
||
|
done
|
||
|
|
||
|
if [ $val -ne $pre_port_25_32_lpmode ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0e 0x0 0x51 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_25_32_lpmode=$val
|
||
|
fi
|
||
|
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
bmc_qsfp_modsel_write()
|
||
|
{
|
||
|
|
||
|
cpld_path="/sys/bus/i2c/devices/0-0006/"
|
||
|
val=0
|
||
|
for i in $(seq 1 8);
|
||
|
do
|
||
|
modsel_path=$cpld_path"port"$i"_modsel"
|
||
|
modsel_input=$(cat $modsel_path | awk '{printf $1}')
|
||
|
val=$((val | (modsel_input << ($i - 1))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_1_8_modsel ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0c 0x0 0x60 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_1_8_modsel=$val
|
||
|
fi
|
||
|
val=0
|
||
|
for i in $(seq 9 16);
|
||
|
do
|
||
|
modsel_path=$cpld_path"port"$i"_modsel"
|
||
|
modsel_input=$(cat $modsel_path | awk '{printf $1}')
|
||
|
val=$((val | (modsel_input << ($i - 9))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_9_16_modsel ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0c 0x0 0x61 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_9_16_modsel=$val
|
||
|
fi
|
||
|
|
||
|
cpld_path="/sys/bus/i2c/devices/0-0007/"
|
||
|
val=0
|
||
|
for i in $(seq 17 24);
|
||
|
do
|
||
|
modsel_path=$cpld_path"port"$i"_modsel"
|
||
|
modsel_input=$(cat $modsel_path | awk '{printf $1}')
|
||
|
val=$((val | (modsel_input << ($i - 17))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_17_24_modsel ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0e 0x0 0x60 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_17_24_modsel=$val
|
||
|
fi
|
||
|
val=0
|
||
|
for i in $(seq 25 32);
|
||
|
do
|
||
|
modsel_path=$cpld_path"port"$i"_modsel"
|
||
|
modsel_input=$(cat $modsel_path | awk '{printf $1}')
|
||
|
val=$((val | (modsel_input << ($i - 25))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_25_32_modsel ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0e 0x0 0x61 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_25_32_modsel=$val
|
||
|
fi
|
||
|
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
bmc_qsfp_presence_read()
|
||
|
{
|
||
|
a=0
|
||
|
tmp1=$(ipmitool raw 0x30 0x25 0x00 0x0c 0x1 0x30 2>>/dev/null)
|
||
|
a=$((a+$?))
|
||
|
tmp1=$(echo $tmp1 | awk '{printf $1}')
|
||
|
sleep 0.05
|
||
|
tmp2=$(ipmitool raw 0x30 0x25 0x00 0x0c 0x1 0x31 2>>/dev/null)
|
||
|
a=$((a+$?))
|
||
|
tmp2=$(echo $tmp2 | awk '{printf $1}')
|
||
|
sleep 0.05
|
||
|
tmp3=$(ipmitool raw 0x30 0x25 0x00 0x0e 0x1 0x30 2>>/dev/null)
|
||
|
a=$((a+$?))
|
||
|
tmp3=$(echo $tmp3 | awk '{printf $1}')
|
||
|
sleep 0.05
|
||
|
tmp4=$(ipmitool raw 0x30 0x25 0x00 0x0e 0x1 0x31 2>>/dev/null)
|
||
|
a=$((a+$?))
|
||
|
tmp4=$(echo $tmp4 | awk '{printf $1}')
|
||
|
sleep 0.05
|
||
|
if [ $a -eq 0 ];then
|
||
|
byte_hex_test $tmp1
|
||
|
if [ $? -eq 0 ]; then
|
||
|
return 0
|
||
|
fi
|
||
|
port_1_8_presence=$( printf "%d" 0x$tmp1 )
|
||
|
byte_hex_test $tmp2
|
||
|
if [ $? -eq 0 ]; then
|
||
|
return 0
|
||
|
fi
|
||
|
port_9_16_presence=$( printf "%d" 0x$tmp2 )
|
||
|
byte_hex_test $tmp3
|
||
|
if [ $? -eq 0 ]; then
|
||
|
return 0
|
||
|
fi
|
||
|
port_17_24_presence=$( printf "%d" 0x$tmp3 )
|
||
|
byte_hex_test $tmp4
|
||
|
if [ $? -eq 0 ]; then
|
||
|
return 0
|
||
|
fi
|
||
|
port_25_32_presence=$( printf "%d" 0x$tmp4 )
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
bmc_qsfp_reset_write()
|
||
|
{
|
||
|
|
||
|
cpld_path="/sys/bus/i2c/devices/0-0006/"
|
||
|
val=0
|
||
|
for i in $(seq 1 8);
|
||
|
do
|
||
|
reset_path=$cpld_path"port"$i"_reset"
|
||
|
reset_input=$(cat $reset_path | awk '{printf $1}')
|
||
|
val=$((val | (reset_input << ($i - 1))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_1_8_reset ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0c 0x0 0x20 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_1_8_reset=$val
|
||
|
fi
|
||
|
val=0
|
||
|
for i in $(seq 9 16);
|
||
|
do
|
||
|
reset_path=$cpld_path"port"$i"_reset"
|
||
|
reset_input=$(cat $reset_path | awk '{printf $1}')
|
||
|
val=$((val | (reset_input << ($i - 9))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_9_16_reset ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0c 0x0 0x21 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_9_16_reset=$val
|
||
|
fi
|
||
|
|
||
|
cpld_path="/sys/bus/i2c/devices/0-0007/"
|
||
|
val=0
|
||
|
for i in $(seq 17 24);
|
||
|
do
|
||
|
reset_path=$cpld_path"port"$i"_reset"
|
||
|
reset_input=$(cat $reset_path | awk '{printf $1}')
|
||
|
val=$((val | (reset_input << ($i - 17))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_17_24_reset ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0e 0x0 0x20 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_17_24_reset=$val
|
||
|
fi
|
||
|
val=0
|
||
|
for i in $(seq 25 32);
|
||
|
do
|
||
|
reset_path=$cpld_path"port"$i"_reset"
|
||
|
reset_input=$(cat $reset_path | awk '{printf $1}')
|
||
|
val=$((val | (reset_input << ($i - 25))))
|
||
|
done
|
||
|
|
||
|
val=$((0xff - val))
|
||
|
if [ $val -ne $pre_port_25_32_reset ]; then
|
||
|
ipmitool raw 0x30 0x25 0x00 0x0e 0x0 0x21 $val 1>>/dev/null 2>>/dev/null
|
||
|
sleep 0.05
|
||
|
pre_port_25_32_reset=$val
|
||
|
fi
|
||
|
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
#$1=port_no
|
||
|
bmc_qsfp_eeprom_read()
|
||
|
{
|
||
|
local port=$1
|
||
|
local eeprom_part1
|
||
|
local eeprom_part2
|
||
|
local eeprom_part3
|
||
|
local eeprom_part4
|
||
|
local eeprom1_full
|
||
|
local eeprom2_full
|
||
|
|
||
|
port=`expr $port - 1`
|
||
|
i2cmux_dev=0
|
||
|
i2cmux_dev=`expr $port / 8`
|
||
|
i2cmux_dev=`expr $i2cmux_dev + 2`
|
||
|
ch=`expr $port % 8`
|
||
|
|
||
|
bmc_write $i2cmux_dev $ch 0x50 0x7f 0x00
|
||
|
bmc_read $i2cmux_dev $ch 0x50 0 128
|
||
|
if [ $? -eq 1 ];then
|
||
|
eeprom_part1=$result
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
bmc_read $i2cmux_dev $ch 0x50 128 128
|
||
|
if [ $? -eq 1 ];then
|
||
|
eeprom_part2=$result
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
#QSFP-DD page2
|
||
|
bmc_write $i2cmux_dev $ch 0x50 0x7f 0x02
|
||
|
bmc_read $i2cmux_dev $ch 0x50 128 128
|
||
|
if [ $? -eq 1 ];then
|
||
|
eeprom_part3=$result
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
#QSFP-DD page11
|
||
|
bmc_write $i2cmux_dev $ch 0x50 0x7f 0x11
|
||
|
bmc_read $i2cmux_dev $ch 0x50 128 128
|
||
|
if [ $? -eq 1 ];then
|
||
|
eeprom_part4=$result
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
sfp_type=$(echo $eeprom_part1 | awk '{printf $1}')
|
||
|
byte_hex_test $sfp_type
|
||
|
if [ $? -eq 0 ]; then
|
||
|
return
|
||
|
fi
|
||
|
sfp_type=$( printf "%d" 0x$sfp_type )
|
||
|
|
||
|
#get temperature
|
||
|
temp=$(echo $eeprom_part1 | 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_part1 | 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_part1 | 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
|
||
|
|
||
|
eeprom1_full=$eeprom_part1$eeprom_part2
|
||
|
eeprom1_full=$(echo $eeprom1_full | sed 's/[[:space:]]//g')
|
||
|
eeprom2_full=$eeprom_part3$eeprom_part4
|
||
|
eeprom2_full=$(echo $eeprom2_full | sed 's/[[:space:]]//g')
|
||
|
|
||
|
if [ $debug_flag -eq 0 ];then
|
||
|
eeprom1_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom1"
|
||
|
eeprom1_full=$(echo $eeprom1_full | sed -e 's/ //g')
|
||
|
echo $eeprom1_full > $eeprom1_path
|
||
|
eeprom2_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom2"
|
||
|
eeprom2_full=$(echo $eeprom2_full | sed -e 's/ //g')
|
||
|
echo $eeprom2_full > $eeprom2_path
|
||
|
else
|
||
|
printf "\nPort %d EEPROM:" $1
|
||
|
printf "-----------------------------------------------\n"
|
||
|
for i in $(seq 1 256);
|
||
|
do
|
||
|
printf "%s " ${eeprom1_full:0:2}
|
||
|
eeprom1_full=$(echo $eeprom1_full | sed 's/^..//')
|
||
|
|
||
|
val=`expr $i % 16`
|
||
|
if [ $val -eq 0 ];then
|
||
|
printf "\n"
|
||
|
fi
|
||
|
done
|
||
|
printf "\n-----------------------------------------------\n"
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
#$1=port_no
|
||
|
bmc_qsfp_eeprom_clear()
|
||
|
{
|
||
|
eeprom1_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom1"
|
||
|
echo "" > $eeprom1_path
|
||
|
eeprom2_path="/sys/bus/i2c/devices/0-00"${port_map[$1]}"/eeprom2"
|
||
|
echo "" > $eeprom2_path
|
||
|
}
|
||
|
|
||
|
QSFP_monitor()
|
||
|
{
|
||
|
while true
|
||
|
do
|
||
|
if [ -e /sys/bus/i2c/devices/0-0006/port1_present ] && [ -e /sys/bus/i2c/devices/0-0007/port32_present ] && [ -e /sys/bus/i2c/devices/0-002f/eeprom1 ];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`
|
||
|
|
||
|
bmc_qsfp_lpmode_write
|
||
|
bmc_qsfp_modsel_write
|
||
|
bmc_qsfp_reset_write
|
||
|
|
||
|
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-0006/"
|
||
|
else
|
||
|
cpld_path="/sys/bus/i2c/devices/0-0007/"
|
||
|
fi
|
||
|
|
||
|
if [ $is_presence -eq 0 ];then
|
||
|
echo 1 > $cpld_path"port"$i"_present"
|
||
|
bmc_qsfp_eeprom_read $i
|
||
|
else
|
||
|
echo 0 > $cpld_path"port"$i"_present"
|
||
|
bmc_qsfp_eeprom_clear $i
|
||
|
fi
|
||
|
done
|
||
|
sleep 2
|
||
|
else
|
||
|
sleep 1
|
||
|
fi
|
||
|
done
|
||
|
}
|
||
|
|
||
|
QSFP_monitor
|