File: //usr/share/flash-kernel/dtb-probe/kirkwood-qnap
#!/bin/sh
# Copyright (C) 2014 Ian Campbell <ijc@debian.org>
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
# USA.
# This script attempts to determine the correct device tree blob to
# use on kirkwood based QNAP devices, which varies according to the
# SoC used either MV88F6281 or MV88F6282.
#
# This is made more complicated because we need to be able to
# determine which DTB to use even if we are running under a kernel
# using the older board-file mechanism (in order to support upgrades).
#
# The SoC ID is exposed via the SoC bus driver and via the PCI device ID of the
# PCI host bridge. However on older board file based kernels neither of these
# are reliably available (SoC ID is only available with multiplatform MVEBU
# kernels, not the kirkwood kernels even when running DTB and is only availavle
# from v3.16 onwards meanwhile older PCI host drivers didn't create the host
# bridge if no devices were present). Therefore we try the following in order:
#
# * soc bus id in sysfs.
# * PCI devid of host bridge
# * Ethernet PHY IDs
#
# Possible values for /proc/cpuinfo:Hardware:
# - QNAP TS-119/TS-219
# - QNAP TS-41x
#
# Possible values for /proc/device-tree/model:
# - QNAP TS219 family
# - QNAP TS419 family
# (NB: TS-119 uses TS-219 DTB)
#
# Example SoC bus fields:
# $ cat /sys/bus/soc/devices/soc0/family
# Marvell
# $ cat /sys/bus/soc/devices/soc0/soc_id
# 6281
# $ cat /sys/bus/soc/devices/soc0/revision
# 2
#
# Example PCI device ids:
#
# Example PHY IDs: (6281 have ID 8 and 0 while 6282 have 0 and 1)
# $ ls /sys/bus/mdio_bus/devices/
# 0:00 0:08
# $ ls /sys/bus/mdio_bus/devices/
# 0:00 0:01
# $ ls /sys/bus/mdio_bus/devices/
# 0:08
# System | Board File | Device Tree (kirkwood or mvebu)
# ------------+--------------------------------+--------------------------------
# TS-119 | |
# ------------+--------------------------------+--------------------------------
# TS-219 6281 | N (MV88F6281-A1 @ 3.2[0]) |
# TS-219 6282 | |
# ------------+--------------------------------+--------------------------------
# TS-419 6281 | Y (MV88F6281-A0 @ 3.14) |
# TS-419 6282 | Y (MV88F6282-Rev-A1 @ 3.2) |
# ------------+--------------------------------+--------------------------------
#
# [0] No visible PCI bus.
# My systems: qnap: TS-419P??? MV88F6281-A0
# celaeno: TS-419??? MV88F6282-Rev-A1
# armitage:TS-219??? MV88F6281-A1
set -e
FK_DIR="/usr/share/flash-kernel"
. "${FK_CHECKOUT:-$FK_DIR}/functions"
info=0
if [ "x$1" = "x--info" ] ; then
info=1
[ -n "$2" ] && kvers=$2
elif [ "x$2" = "x--info" ] ; then
info=1
kvers=$1
elif [ -n "$1" ]; then
kvers=$1
fi
last_result=
success() {
local what=$1
local res=$2
if [ $info -gt 0 ] ; then
echo "kirkwood-qnap: success: $what => $res" >&2
if [ -n "$last_result" -a "x$res" != "x$last_result" ] ; then
echo "kirkwood-qnap: result mismatch" >&2
fi
last_result=$res
else
echo $res
exit 0
fi
}
if [ $info -gt 0 ] ; then
(
/bin/echo -e "Kernel:\t\t$(uname -a)"
/bin/echo -e -n "cpuinfo:\t" ; grep ^Hardware /proc/cpuinfo
/bin/echo -e -n "dt model:\t"
if [ -e /proc/device-tree/model ] ; then
cat /proc/device-tree/model
/bin/echo
else
/bin/echo "n/a"
fi
/bin/echo
/bin/echo "PCI devices:"
lspci -n
/bin/echo
/bin/echo "PHY devices (/sys/bus/mdio_bus/devices/):"
ls /sys/bus/mdio_bus/devices/
/bin/echo
/bin/echo -ne "Soc Bus:\t"
if [ -e "/sys/bus/soc/devices/soc0" ] ; then
/bin/echo
ls /sys/bus/soc/devices/soc0
else
/bin/echo "n/a"
fi
/bin/echo
) >&2
fi
get_machine
if [ -z "$machine" -a $info -gt 0 ] ; then
machine=`get_machine`
fi
echo "kirkwood-qnap: machine: $machine" >&2
case $machine in
"QNAP TS-119/TS-219"|"QNAP TS219 family")
dtb_0x6281="kirkwood-ts219-6281.dtb"
dtb_0x6282="kirkwood-ts219-6282.dtb"
;;
"QNAP TS-41x"|"QNAP TS419 family")
dtb_0x6281="kirkwood-ts419-6281.dtb"
dtb_0x6282="kirkwood-ts419-6282.dtb"
;;
*)
error "Unknown machine $machine"
;;
esac
if [ -e "/sys/bus/soc/devices/soc0/soc_id" ] ; then
case $(cat /sys/bus/soc/devices/soc0/soc_id) in
6281) success "SoC ID" $dtb_0x6281;;
6282) success "SoC ID" $dtb_0x6282;;
esac
fi
for device in /sys/bus/pci/devices/* ; do
if [ ! -e "$device" ] ; then
continue
fi
if [ ! -e "$device/class" -o \
! -e "$device/vendor" -o \
! -e "$device/device" ] ; then
echo "$device is missing sysfs entries" >&2
continue
fi
class=$(cat $device/class)
# Host/PCI bride 0x60000 or PCI/PCI bride 0x60400
if [ x$class != x0x060000 ] && [ x$class != x0x060400 ] ; then
echo "$device is not a PCI bridge ($class)" >&2
continue
fi
vid=$(cat $device/vendor)
if [ x$vid != x0x11ab ] ; then
echo "$device vendor is not Marvell ($vid)" >&2
continue
fi
did=$(cat $device/device)
case $did in
0x6281) success "PCI" ${dtb_0x6281}; break;;
0x6282) success "PCI" ${dtb_0x6282}; break;;
*) echo "$device is not a known Marvell device ($did)" >&2 ;;
esac
done
have_phy() {
local phy=$1
test -e "/sys/bus/mdio_bus/devices/0:$phy" -o \
-e "/sys/bus/mdio_bus/devices/orion-mdio-mii:$phy" -o \
-e "/sys/bus/mdio_bus/devices/f1072004.mdio-bu:$phy"
}
case $machine in
"QNAP TS-119/TS-219"|"QNAP TS219 family")
# TS-219??? MV88F6281-A1 # ls /sys/bus/mdio_bus/devices/ => 0:08@
if have_phy 08; then
success "PHY" "$dtb_0x6281"
elif have_phy 00; then
success "PHY" "$dtb_0x6282"
fi
;;
"QNAP TS-41x"|"QNAP TS419 family")
# TS-419P??? MV88F6281-A0 # ls /sys/bus/mdio_bus/devices/ => 0:00@ 0:08@
# TS-419??? MV88F6282-Rev-A1# ls /sys/bus/mdio_bus/devices/ => 0:00@ 0:01@
if have_phy 08 && have_phy 00; then
success "PHY" "$dtb_0x6281"
elif have_phy 00 && have_phy 01; then
success "PHY" "$dtb_0x6282"
fi
;;
esac
if [ $info -gt 0 ] ; then
exit 0
fi
echo "kirkwood-qnap: Unable to determine $machine variant " >&2
exit 1