| #!/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 |