-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Address Dell issue#46 : Adding MUX reset logic to fix probe failures #2356
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,3 +60,60 @@ i2c_poll_bus_exists() { | |
fi | ||
} | ||
|
||
# Perform an i2c mux device create | ||
# Input is of the form: | ||
# "echo [mux driver] <i2c-mux-address> > <i2c-bus/operation>" i2c-channel-first | ||
# where operation = "new_device" | ||
# i2c-channel-first is the first of the 8 channels that this mux should create | ||
i2c_mux_create() { | ||
local MAX_MUX_CHANNEL_RETRY=5 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel 5 is too large, could you change to 3. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed this |
||
local MAX_MUX_CHANNELS=8 | ||
local count=0 | ||
local i | ||
local i2c_bus_op | ||
local i2c_bus | ||
local i2c_bus_num | ||
local i2c_mux | ||
local i2c_mux_channel_first | ||
local i2c_mux_channel_last | ||
|
||
# Extract the i2c parameters from the command line | ||
i2c_bus_op=`echo "$1" | cut -d'>' -f 2` | ||
i2c_bus=$(dirname $i2c_bus_op) | ||
i2c_bus_num=`echo $(basename $i2c_bus) | cut -d'-' -f 2` | ||
i2c_mux=`echo "$1" | cut -d' ' -f 3 | sed 's/^0x//'` | ||
i2c_mux_channel_first=$i2c_bus/i2c-$2 | ||
i2c_mux_channel_last=$i2c_bus/i2c-$(expr $2 + $MAX_MUX_CHANNELS - 1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the above logic is too complex to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed |
||
|
||
if i2c_poll_bus_exists $i2c_bus; then | ||
while [[ "$count" -lt "$MAX_MUX_CHANNEL_RETRY" ]]; do | ||
eval "$1" > /dev/null 2>&1 | ||
ret=$? | ||
|
||
# Give more time for the mux channels to get created based on retries | ||
i=0 | ||
while [[ "$i" -lt "$count" ]]; do | ||
sleep .5 | ||
i=$((i+1)) | ||
done | ||
|
||
# Check if the (first and last) mux channels got created | ||
if [[ $ret -eq "0" && -e $i2c_mux_channel_first && -e $i2c_mux_channel_last ]]; then | ||
break; | ||
else | ||
# If the channel did not get created, remove the mux, reset the mux tree and retry | ||
i2c_config "echo 0x$i2c_mux > /sys/bus/i2c/devices/i2c-$devnum/i2c-$i2c_bus_num/delete_device" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you rename the function |
||
reset_muxes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. before resetting the mux, could you add one line specific log indicating which mux failed to be initialized? what's the root? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added debug with mux details. |
||
fi | ||
|
||
count=$((count+1)) | ||
done | ||
fi | ||
|
||
if [[ "$count" -eq "$MAX_MUX_CHANNEL_RETRY" ]]; then | ||
echo "ERROR: $1,$2 : i2c mux channel not created" | ||
return | ||
fi | ||
|
||
return | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ init_devnum() { | |
# Attach/Detach CPU board mux @ 0x70 | ||
cpu_board_mux() { | ||
case $1 in | ||
"new_device") i2c_config "echo pca9547 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" | ||
"new_device") i2c_mux_create "echo pca9547 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" 2 | ||
;; | ||
"delete_device") i2c_config "echo 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" | ||
;; | ||
|
@@ -33,7 +33,7 @@ cpu_board_mux() { | |
# Attach/Detach Switchboard MUX @ 0x71 | ||
switch_board_mux() { | ||
case $1 in | ||
"new_device") i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-4/$1" | ||
"new_device") i2c_mux_create "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-4/$1" 10 | ||
;; | ||
"delete_device") i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-4/$1" | ||
;; | ||
|
@@ -78,13 +78,17 @@ switch_board_cpld() { | |
switch_board_qsfp_mux() { | ||
case $1 in | ||
"new_device") | ||
# The mux for the QSFPs spawn {18..25}, {26..33}... {74..81} | ||
# starting at chennel 18 and 16 channels per IOM. | ||
channel_first=18 | ||
for ((i=9;i>=6;i--)); | ||
do | ||
# 0x71 mux on the IOM 1 | ||
mux_index=$(expr $i - 5) | ||
echo "Attaching PCA9548 $mux_index" | ||
i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-$i/$1" | ||
i2c_config "echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-$i/$1" | ||
i2c_mux_create "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-$i/$1" $channel_first | ||
i2c_mux_create "echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-$i/$1" $(expr $channel_first + 8) | ||
channel_first=$(expr $channel_first + 16) | ||
done | ||
;; | ||
"delete_device") | ||
|
@@ -191,6 +195,28 @@ xcvr_presence_interrupts() { | |
esac | ||
} | ||
|
||
# Reset the mux tree | ||
reset_muxes() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for resetting the muxes, is it possible to reset only one mux per the failure? or do we need to reset all the muxes? if we reset all the muxes, do we need to re-build the whole i2c tree? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is possible to reset only the specific mux that are part of this channel - however the complexity of that logic is not warranted. Resetting the muxes does not necessitate rebuilding the kernel's i2c tree. |
||
local i | ||
|
||
# Reset the IOM muxes (if they have been already instantiated) | ||
for ((i=14;i<=17;i++)); | ||
do | ||
if [[ -e /sys/class/i2c-adapter/i2c-$i/$i-003e ]]; then | ||
echo 0xfc > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset | ||
echo 0xff > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset | ||
fi | ||
done | ||
|
||
# Reset the switch card PCA9548A | ||
io_rd_wr.py --set --val 0xef --offset 0x110 | ||
io_rd_wr.py --set --val 0xff --offset 0x110 | ||
|
||
# Reset the CPU Card PCA9547 | ||
io_rd_wr.py --set --val 0xfd --offset 0x20b | ||
io_rd_wr.py --set --val 0xff --offset 0x20b | ||
} | ||
|
||
init_devnum | ||
|
||
if [[ "$1" == "init" ]]; then | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for me, this piece of code is a little bit hard to understand. since the i2c tree is fixed on each platform, it would be better to have some more predefined numbers instead of number manipulation here.
the function could be simpler like i2c_mux_create <root> <sub_root> <first>
so that in the script you only need to call the function e.g. i2c_mux_create 4 0x71 10 or i2c_mux_create 7 0x71 50 or i2c_mux_create 7 0x72 58
the echo command and the details of the retry could be inside the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed this.