blob: 00eeebeb890c18436438a1e850ee508ee79bbe5c [file] [log] [blame]
#!/bin/sh
. /etc/utils.sh
#
# reset and initialize the marvell parts in chimera
#
register_experiment NoPhyFWUpgrade
register_experiment CpssNoStart
register_experiment CpssNoInit
register_experiment Cpss10GOnly
cpss_bin="cpss.gomain"
# Switch configuration written to this file and then loaded into switch.
CPSS_CONFIG="/tmp/cpss_config"
die()
{
echo "$0: $*" >&2
pkill -x $cpss_bin
exit 1
}
# Given a set of vlan identifiers to exclude, generate the
# range descriptions that exclude those identifiers.
vlan_ranges()
{
local result vlans last final curr v dt range
result=""
vlans=$(echo "$@" | sed -e 's/ /\n/g' | sort -nu)
last=${vlans##.* }
final=$(($vlan_end+1))
if [ "$last" = $vlan_end ]; then
final=
fi
set -- $vlans $final
curr=$vlan_start
while [ $# -gt 0 ]; do
v=$1
shift
dt=$(($v - $curr))
if [ $dt -lt 0 ]; then
# silently drop illegal values
continue
fi
# emit in blocks of $max_at_once
while [ $dt -gt 0 ]; do
if [ $dt -eq 1 ]; then
result="${result} $curr"
curr=$(($v + 1))
elif [ $dt -le $max_at_once ]; then
result="${result} $curr-$(($v-1))"
curr=$(($v + 1))
else
v2=$(($curr+$max_at_once))
result="${result} $curr-$(($v2-1))"
curr=$v2
fi
dt=$(($v - $curr))
done
done
echo ${result}
}
# Generate the switchport allowed vlan lines with the appropriate
# ranges when passed a set of vlans to exclude.
generate_vlan_allow_lines()
{
local range
for range in $(vlan_ranges "$@"); do
echo "switchport allowed vlan add ${range} outer_tag0_inner_tag1"
done
}
vlan_start=1
vlan_end=4095
max_at_once=500
vlan_ooband=$(ptp-config -g vlan_ooband)
vlan_inband=$(ptp-config -g vlan_inband)
vlan_peer=$(ptp-config -g vlan_peer)
# Use vlan 4095 (reserved in 802.1q) for untagged traffic.
vlan_untagged=4095
port_poe=0/0
port_soc=0/4
port_modem=0/24
port_sfp=0/25
# 2nd SFP port available only on 1.2 boards
port_sfp2=0/26
src_modem=${port_modem##0/}
src_sfp=${port_sfp##0/}
# There are 6128 available buffers, each buffer is 256 bytes.
# Increasing buffers allocated to modem port as this is where
# congestion is likely to occur.
port_modem_buffers=4000
port_modem_tc_buffers=$(($port_modem_buffers/8))
pci="/dev/switch"
ready=/tmp/cpss_ready
rm -f "$ready"
# Take switch out of reset in case it was left that way
if [ -e /dev/gpio/3236_reset ]; then
echo 0 >/dev/gpio/3236_reset/value
fi
if [ ! -d $pci ]; then
# rescan the pci bus in case it was in reset
echo 1 >/sys/bus/pci/rescan
msleep 200
fi
if [ ! -d $pci ]; then
die "PCI device for 3236 switch not found at '$pci'"
fi
# Check that vendor & device ID have expected values
vendor_id_expected="0x11ab"
vendor_id="$(cat ${pci}/vendor)"
device_id_expected="0xf410"
device_id="$(cat ${pci}/device)"
if [ "$vendor_id" != "$vendor_id_expected" ] || [ "$device_id" != "$device_id_expected" ]; then
die "pci vendor_id ($vendor_id != $vendor_id_expected) or" \
"device_id ($device_id != $device_id_expected) mismatch!"
fi
# Resetting the 3236 causes all the PCI BARs to be reset, so we need to remove
# the switch from the pci bus then rescan the pci bus at the end. Finally we
# need to enable the switch again.
echo 1 >$pci/remove
msleep 100
if [ ! -d $pci ]; then
echo "$pci was removed successfully!"
else
die "There is still a PCI device present after removal at: $pci"
fi
# If 3236_reset is available then the switch software reset line is available.
# Wait for 3236_ready to go high before starting cpss.
if [ -e /dev/gpio/3236_reset ]; then
echo 1 >/dev/gpio/3236_reset/value
msleep 100
echo 0 >/dev/gpio/3236_reset/value
bailout=0
while [ ${bailout} -le 3 ]; do
state=$(cat /dev/gpio/3236_ready/value)
if [ ${state} -eq 1 ]; then
echo "$0: 3236 is ready after reset!"
break
else
bailout=$(($bailout+1))
msleep 500
fi
done
if [ ${bailout} -gt 3 ]; then
die "Error: 3236 was NOT reset!"
fi
fi
# reset phys
reset="2011_reset 3220_reset"
for n in $reset; do
echo 1 >/dev/gpio/$n/value
done
msleep 100
for n in $reset; do
echo 0 >/dev/gpio/$n/value
done
echo 1 >/sys/bus/pci/rescan
msleep 200
if [ ! -d $pci ]; then
die "There is no PCI device at $pci after rescanning!"
else
echo "Excellent! $pci has reappeared."
fi
echo "Finally, enabling the switch..."
echo 1 >$pci/enable
if experiment NoPhyFWUpgrade; then
echo "$0: experiment NoPhyFWUpgrade enabled, skipping upgrade check." >&2
else
# Switch now available on PCI bus, can now also talk to 10G PHY through
# switch's MDIO bus. Before starting CPSS, check whether the 10G PHY needs
# a firmware update.
echo "Performing 10G PHY firmware update (if needed)"
update-phy-firmware -f 2>&1 | logos update-phy-firmware
fi
if experiment CpssNoStart; then
echo "$0: experiment CpssNoStart is enabled, not starting cpss." >&2
exit 0
fi
# start cpss as persistent server
pkill -x $cpss_bin
export CMDFS_ROOT=/usr/lib/cpss/scripts
ptyserver -p 4455 $cpss_bin -logtostderr 2>&1 | logos cpss_pty &
# check that shell loaded and we get a prompt
# try a few times; we get one timeout at boot time, don't know why
success=0
for n in $(seq 3); do
cpss_cmd -f <<EOF
EOF
if [ $? = 0 ]; then
success=1
break
fi
echo "$0: still waiting for cpss prompt" >&2
sleep 1
done
[ $success = 1 ] || die "no cpss prompt"
echo "$0: got cpss prompt"
# start configuring cpss
if experiment CpssNoInit; then
echo "$0: experiment CpssNoInit enabled, skipping init and 2011 config." >&2
else
# disable pager
cpss_cmd -f <<EOF || die "failed to disable pager"
debug
set print pause disable
end
EOF
# init the switch, check for result
initOK="Init system returned:0"
cpss_cmd -f <<EOF | grep "$initOK" || die "cpssInitSystem failed"
cpssInitSystem 19,2,0
EOF
# show cpss version
echo show version | cpss_cmd -f
# init 88x2011 (xfi/xaui transceiver)
cpss_cmd -f <<EOF | grep "Successfully" || die "failed to initialize 2011"
chimera
init_2011
end
EOF
rm -rf $CPSS_CONFIG
if experiment Cpss10GOnly; then
echo "$0: experiment Cpss10GOnly is enabled, skipping vlans." >&2
# configure just the 10G path
cat >> $CPSS_CONFIG <<EOF
config
interface range ethernet $port_modem,$port_sfp
speed 10000 mode SR_LR
exit
end
EOF
else
# configure ports, vlans
cat >> $CPSS_CONFIG <<EOF
cpss-api call cpssDxChBrgVlanRemoveVlanTag1IfZeroModeSet devNum 0 mode CPSS_DXCH_BRG_VLAN_REMOVE_TAG1_IF_ZERO_E
cpss-api call cpssDxChBrgVlanRangeSet devNum 0 vidRange 4095
config
counters egress-queue device all count-drop
interface range ethernet all
switchport allowed vlan remove 1
port-mac learning automatic
flow-control off
shutdown
exit
no counters mac counters reset-on-read all
$(for n in $(vlan_ranges); do
echo interface range vlan device 0 vid $n
echo exit
done
)
interface ethernet $port_poe
speed 1000 mode SGMII
switchport allowed vlan add $vlan_ooband untagged
switchport pvid $vlan_ooband
no shutdown
exit
interface ethernet $port_soc
speed 1000 mode 1000Base_X
qos trust vpt
switchport allowed vlan add $vlan_ooband tagged
switchport allowed vlan add $vlan_peer tagged
switchport allowed vlan add $vlan_inband tagged
switchport pvid $vlan_ooband
no shutdown
exit
interface ethernet $port_modem
speed 10000 mode SR_LR
jumbo-frame 9100
qos trust vpt
flow-control on
$(generate_vlan_allow_lines $vlan_ooband $vlan_untagged)
switchport allowed vlan add $vlan_untagged untagged
switchport pvid $vlan_untagged
no shutdown
exit
interface ethernet $port_sfp
speed 10000 mode SR_LR
jumbo-frame 9100
qos trust vpt
$(generate_vlan_allow_lines $vlan_peer $vlan_ooband $vlan_untagged)
switchport allowed vlan add $vlan_untagged untagged
switchport pvid $vlan_untagged
no shutdown
exit
EOF
num_sfp_ports
num_sfps=$?
if [ $num_sfps -eq 2 ]; then
cat >> $CPSS_CONFIG <<EOF
interface ethernet $port_sfp2
speed 10000 mode SR_LR
jumbo-frame 9100
qos trust vpt
$(generate_vlan_allow_lines $vlan_peer $vlan_ooband $vlan_untagged)
switchport allowed vlan add $vlan_untagged untagged
switchport pvid $vlan_untagged
no shutdown
exit
EOF
fi
cat >> $CPSS_CONFIG <<EOF
interface vlan device all vid $vlan_inband
vlan-mac learning
exit
mac address-table aging-mode auto-removal device 0
$(for n in $(vlan_ranges); do
echo interface range vlan device 0 vid $n
echo jumbo-frame 9100
echo exit
done
)
end
EOF
# QOS scheduling related configuration.
cpss_cmd -f <<EOF || die "QOS scheduling config failed"
configure
qos map vpt-queue device all queue-id 4 vpt 0,1,5
qos map vpt-queue device all queue-id 5 vpt 2
qos map vpt-queue device all queue-id 6 vpt 3,4
qos map vpt-queue device all queue-id 7 vpt 6
qos map vpt-queue device all queue-id 8 vpt 7
qos wrr-queue bandwidth device 0 weight 0,0,0,1,30,60,10,sp
interface range ethernet all
qos default-up 0
exit
end
EOF
# QOS buffer management related configuration.
cpss_cmd -f <<EOF || die "QOS buffer managment config failed"
cpss-api call cpssDxChPortTxTailDropUcEnableSet devNum 0 enable true
cpss-api call cpssDxChPortTxBufferTailDropEnableSet devNum 0 enable true
cpss-api call cpssDxChPortTxBindPortToDpSet devNum 0 portNum $src_modem profileSet CPSS_PORT_TX_DROP_PROFILE_1_E
configure
interface ethernet $port_modem
tail-drop buffer-limit $port_modem_buffers
tail-drop packet-limit $port_modem_buffers
tail-drop-queue queue all dp all buffer-limit $port_modem_tc_buffers
tail-drop-queue queue all dp all packet-limit $port_modem_tc_buffers
end
end
end
EOF
fi
cpss_cmd -f </tmp/cpss_config || die "config failed"
fi
# touch ready-file to let cpss_cmd know
>"$ready"
echo "cpss is ready."
# wait on ptyserver
wait
rm -f $ready
# exit badly to get babysitter to restart
exit 1