#!/bin/bash
# Copyright (c) 2013 Intel Corporation. All rights reserved.
# Copyright (c) 2010 QLogic Corporation.
# All rights reserved.
#
# This software is available to you under a choice of one of two
# licenses. You may choose to be licensed under the terms of the GNU
# General Public License (GPL) Version 2, available from the file
# COPYING in the main directory of this source tree, or the
# OpenIB.org BSD license below:
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# - Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# - Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# This script does truescale (qib) adapter-specific actions, and is
# sourced during boot after the ib_qib module is loaded. The stop
# operation is deprecated. It isn't intended for standalone use.
# base name in /sys/class
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
export PATH
qb=/sys/class/infiniband/qib
serdes_parm=txselect
if [ -r /etc/rdma/rdma.conf ]; then
IB_CONFIG=/etc/rdma/rdma.conf
else
IB_CONFIG=/etc/infiniband/openib.conf
fi
if [ -f $IB_CONFIG ]; then
. $IB_CONFIG
fi
# If user specifies an override or the setting is ommitted from the config file
# then default to new back plane version.
if [ -z $QIB_QME_BPVER ]; then
QIB_QME_BPVER=1
fi
warn_and_log()
{
echo "$0: $@"
logger -t infinipath "$@"
}
setup_qmh()
{
local -i nunit=0 bay bl2xB=0 full=0
local parmf sysinfo bayinfo mez1bus mez2bus mez3bus=0 tbay
local -a parm bay_h1
for parm in parameters/${serdes_parm} ${serdes_parm}; do
if [ -e /sys/module/ib_qib/$parm ]; then
parmf=/sys/module/ib_qib/$parm
break;
fi
done
if [ ! "$parmf" ]; then
warn_and_log Unable to find ${serdes_parm} parameter
return
fi
sysinfo="$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t system | \
sed -e '/^Handle/d' -e '/^[ \t]*$/d' -e 's/[ \t]*$//' )"
if [ ! "$sysinfo" ]; then
warn_and_log Unable to determine system type
return
fi
bayinfo="$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t 204)"
if [ ! "$bayinfo" ]; then
warn_and_log Unable to determine bay
return
fi
case "${bayinfo}" in
*Server*Bay:*) tbay=$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t 204 | \
sed -n -e 's/[ \t]*$//' -e 's/[ \t]*Server Bay:[ \t]*//p') ;;
*) tbay=$(PATH=/sbin:/usr/sbin:$PATH; dmidecode -t 204 | \
sed -n -e '1,/BladeSystem/d' -e 's/ *$//' -e 's/^\t\t*//' \
-e '/^[0-9][AB]*$/p' -e '/^[0-9][0-9][AB]*$/p') ;;
esac
read pbase < $parmf
parm=($(echo ${qb}*))
nunit=${#parm[*]}
# [0] is a dummy in these arrays, bay #'ing starts at 1
# H1 value, per bay (same for both ports)
m1_bay_h1=(0 8 7 7 7 7 6 6 6 8 7 7 7 7 6 6 7)
m2_bay_h1=(0 11 11 11 11 11 11 10 11 11 11 11 11 10 10 10 10)
m3_bay_h1=(0 11 11 11 11 10 10 10 10)
# tx serdes index per bay for mez1 (either port)
mez1p1_idx=(0 2 2 17 17 17 1 1 1 2 1 17 17 16 2 18 16)
# tx serdes setting for mez1 p2 (only used on full-height blades)
mez1p2_idx=(0 4 4 3 3 3 2 4 4)
# tx serdes index per bay for mez2 port 1
mez2p1_idx=(0 2 2 17 17 17 1 1 1 2 1 17 17 16 2 18 1)
# tx serdes index per bay for mez2 port 2
mez2p2_idx=(0 2 2 19 1 1 1 1 1 2 1 18 17 1 19 1 1)
# tx serdes index per bay for mez3 port 1 (mez3 only on full-height blades)
mez3p1_idx=(0 2 1 18 17 1 19 1 1)
# tx serdes index per bay for mez3 port 2 (mez3 only on full-height blades)
mez3p2_idx=(0 2 1 17 17 16 2 18 1)
case "${sysinfo}" in
*BL280[cC]*) mez1bus=3 mez2bus=6 bay=$tbay ;;
# both nodes on the 2x220 blade have bus 3, only one mez, but
# they connect to different switches through different paths
# so A and B have different parameters. They connect to
# the switch as if they were the mez2 on other blade types,
# with port 1 on mez2 for A node and port 2 on mez2
# for the B node
*BL2x220[cC]*)
mez1bus=3 mez2bus=3 bay=${tbay%[AB]}
case "${tbay}" in
*A) bl2xB=${mez2p1_idx[$bay]} ;;
*B) bl2xB=${mez2p2_idx[$bay]} ;;
esac
;;
*BL460[cC]*) mez1bus=6 mez2bus=9 bay=$tbay ;;
*BL465[cC]*) mez1bus=5 mez2bus=8 bay=$tbay ;;
*BL490[cC]*) mez1bus=6 mez2bus=7 bay=$tbay ;;
*BL685[cC]*) mez1bus=41 mez2bus=6 mez3bus=44 full=1 bay=$(($tbay % 9)) ;;
*) warn_and_log Unknown blade type "$sysinfo"
return ;;
esac
# mez1 only has port1 connected, mez2, mez3 can have both ports
# If only one card, and two mez possible, we have to figure out which
# mez we are plugged into.
# On RHEL4U8, we look in the driver subdir, all others
# in the device/driver subdir for the pcie bus.
pciprefix="[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]:"
if [ ${bl2xB} -ne 0 ]; then
pbase="${pbase} 0,1=${bl2xB},${m2_bay_h1[$bay]}"
else while [ $nunit -ne 0 ]; do
(( nunit-- ))
buspath=$(readlink -m ${qb}${nunit}/device)
if [ -n "$(echo ${buspath} | grep "${pciprefix}$(printf "%02d" ${mez1bus}):")" ]; then
pbase="${pbase} ${nunit},1=${mez1p1_idx[$bay]},${m1_bay_h1[$bay]}"
if [ ${full} -eq 1 ]; then
pbase="${pbase} ${nunit},2=${mez1p2_idx[$bay]},${m1_bay_h1[$bay]}"
fi
elif [ -n "$(echo ${buspath} | grep "${pciprefix}$(printf "%02d" ${mez2bus}):")" ]; then
pbase="${pbase} ${nunit},1=${mez2p1_idx[$bay]},${m2_bay_h1[$bay]}"
pbase="${pbase} ${nunit},2=${mez2p2_idx[$bay]},${m2_bay_h1[$bay]}"
elif [ -n "$(echo ${buspath} | grep "${pciprefix}$(printf "%02d" ${mez3bus}):")" ]; then
pbase="${pbase} ${nunit},1=${mez3p1_idx[$bay]},${m3_bay_h1[$bay]}"
pbase="${pbase} ${nunit},2=${mez3p2_idx[$bay]},${m3_bay_h1[$bay]}"
else
warn_and_log Mismatch on mezbus ${mez1_bus},${mez2_bus},${mez3_bus} \
and unit ${nunit}, no serdes setup
fi
done
fi
echo -n ${pbase} > $parmf
}
setup_qme()
{
local parm parmf sn pbase
local -i nunit=0 bay idx bpver=${QIB_QME_BPVER:1}
local -a bp0_idx bp1_idx set
# tx settings for Dell Backplane v1.0
bp0_idx=( 0 22 23 24 25 26 24 27 28 22 23 24 25 26 24 27 28 )
# tx settings for Dell Backplane v1.1
bp1_idx=( 0 29 29 30 31 32 33 30 29 29 29 30 31 32 33 30 29 )
for parm in parameters/${serdes_parm} ${serdes_parm}; do
if [ -e /sys/module/ib_qib/$parm ]; then
parmf=/sys/module/ib_qib/$parm
break;
fi
done
if [ ! "$parmf" ]; then
warn_and_log Unable to find ${serdes_parm} parameter
return
fi
read pbase < $parmf
parm=( $(echo ${qb}*) )
nunit=${#parm[*]}
if [ -e /sys/module/ib_qib/parameters/qme_bp ]; then
read bpver < /sys/module/ib_qib/parameters/qme_bp
if [ ${bpver} -ne 0 -a ${bpver} -ne 1 ]; then
warn_and_log "Invalid Dell backplane version (${bpver}). Defaulting to 1."
bpver=1
fi
fi
eval 'set=( ${bp'${bpver}'_idx[@]} )'
# we get two serial numbers normally, use 2nd if present, else first
sn="$(dmidecode -t 2 | grep -i serial | tail -1)"
case ${sn} in
*[sS]erial\ [nN]umber*)
bay="$(echo $sn | sed -e 's/\.$//' -e 's/.*\.0*//' -e 's/[abcd]$//')"
if [ ${bay} -gt ${#set[@]} ]; then
warn_and_log Unexpected QME7342 bay info: ${sn}, no Tx params
return
fi
idx=${set[bay]}
# H1 is same for all QME bays, so no need to specify.
while [ $nunit -ne 0 ]; do
(( nunit-- ))
pbase="${pbase} ${nunit},1=${idx} ${nunit},2=${idx}"
done
echo -n ${pbase} > $parmf
;;
*) warn_and_log No QME7342 bay information, no Tx params
return;;
esac
}
has_qib=$(lspci -n 2>/dev/null | grep -i "1077\|1fc1")
if [ ! "${has_qib}" ]; then
exit 0
fi
case "$1" in
start)
has_qmh7342=$(grep QMH7342 ${qb}*/hca_type 2>/dev/null)
if [ "${has_qmh7342}" ]; then
setup_qmh
else
has_qme7342=$(grep QME7342 ${qb}*/hca_type 2>/dev/null)
if [ "${has_qme7342}" ]; then
setup_qme
fi
fi
;;
stop)
warn_and_log stop operation deprecated
;;
esac