| #!/bin/sh |
| . /etc/utils.sh |
| |
| |
| redistribute_irqs() |
| { |
| if is-storage-box; then |
| # Storage Box serves MoCA and Ethernet simultaneously, |
| # so we move them to different CPUs. |
| # TV Box mostly uses MoCA *or* Ethernet, and keeps |
| # CPU1 free to handle the video interrupts. |
| mocacpu=1 |
| eth0cpu=2 |
| else |
| mocacpu=2 |
| eth0cpu=2 |
| fi |
| |
| wifi_irq= |
| if grep BCM7425 /proc/cpuinfo >/dev/null; then |
| echo 1 >/proc/irq/62/smp_affinity |
| echo $eth0cpu >/proc/irq/18/smp_affinity |
| echo $eth0cpu >/proc/irq/19/smp_affinity |
| echo $mocacpu >/proc/irq/20/smp_affinity |
| echo $mocacpu >/proc/irq/21/smp_affinity |
| echo $mocacpu >/proc/irq/31/smp_affinity |
| wifi_irq=34 |
| elif grep BCM7429 /proc/cpuinfo >/dev/null; then |
| echo 1 >/proc/irq/52/smp_affinity |
| echo $eth0cpu >/proc/irq/16/smp_affinity |
| echo $eth0cpu >/proc/irq/17/smp_affinity |
| echo $mocacpu >/proc/irq/18/smp_affinity |
| echo $mocacpu >/proc/irq/19/smp_affinity |
| echo $mocacpu >/proc/irq/28/smp_affinity |
| wifi_irq=57 |
| fi |
| |
| if has_wifi && is-tv-box && [ ! -z ${wifi_irq} ]; then |
| # Partial fix for "micro-stuttering" seen in video playback. |
| # Wifi driver needs to be on cpu1 and video on cpu0 so that wifi |
| # can't lock out scheduling of the video player. |
| echo "forcing wifi onto cpu1" |
| echo 2 >/proc/irq/${wifi_irq}/smp_affinity |
| fi |
| } |
| |
| |
| case "$1" in |
| start) |
| # TODO(apenwarr): remove this once all devices use 'moca0' as the name. |
| if [ -e /sys/class/net/moca0 ]; then |
| # GFRG200 |
| mocaifc=moca0 |
| else |
| # GFMS100/GFHD100/GFHD200 |
| mocaifc=eth1 |
| fi |
| |
| [ -e /usr/lib/modules/bmoca.ko ] && insmod /usr/lib/modules/bmoca.ko |
| |
| # if the file exists and it isn't empty |
| if [ -s /config/tcp_congestion_control ]; then |
| algorithm=$(cat /config/tcp_congestion_control) |
| echo "Registering congestion control algorithm $algorithm" |
| sysctl net.ipv4.tcp_congestion_control=$algorithm |
| fi |
| |
| # create a default resolv.conf and /etc/hosts in case DHCP doesn't. |
| # (this is always true if using nfsroot). |
| # 8.8.8.8 and 8.8.4.4 are well-known Google public DNS servers |
| # that can be used from anywhere, so it makes a good place to start. |
| # DHCP will just overwrite this file when it's ready to go. |
| if [ ! -r /etc/resolv.conf ]; then |
| #TODO(apenwarr): add IPv6 DNS once our uClibc can handle it. |
| (echo 'nameserver 8.8.8.8'; |
| echo 'nameserver 8.8.4.4') >/etc/resolv.conf |
| fi |
| if [ ! -r /etc/hosts ]; then |
| echo "127.0.0.1 localhost $(hostname)" >/etc/hosts |
| fi |
| |
| # Configure dhclient with the right hostname etc. |
| setup-dhclient |
| |
| # configure loopback |
| ifup lo |
| echo -n "Creating bridge... " |
| brctl addbr br0 || exit 1 |
| brctl setfd br0 1 |
| brctl stp br0 on |
| # Storage and network boxes should have higher precedence (lower value) |
| # when choosing the root of the spanning tree. |
| # The default in Linux is 0x8000. |
| if is-network-box; then |
| brctl setbridgeprio br0 0x7980 |
| elif is-storage-box; then |
| brctl setbridgeprio br0 0x7990 |
| fi |
| [ -e /sys/class/net/eth0/address ] && \ |
| ip link set br0 address \ |
| $(cat /sys/class/net/eth0/address) |
| echo "done" |
| ip link set br0 up |
| ip link set br0 up # kernel 3.2.26 bug: fails the first time |
| |
| # VLAN tag for MoCA interface |
| ip link add link $mocaifc name $mocaifc.0 type vlan id 0 |
| # SO_PRIORITY -> 802.1p mapping |
| for prio in 0 1 2 3 4 5 6 7; do |
| vconfig set_egress_map $mocaifc.0 $prio $prio >/dev/null 2>&1 |
| done |
| |
| echo "Adding interfaces... " |
| # Move any existing network info from primary network interfaces to |
| # the bridge. |
| for x in \ |
| /sys/class/net/[ea]th[0-9] \ |
| /sys/class/net/lan[0-9] \ |
| /sys/class/net/moca[0-9]; do |
| x=${x#/sys/class/net/} |
| echo "Adding interface $x..." |
| ip link set $x up && |
| ip -o -f inet addr show $x | |
| while read a b c ip d brd junk; do |
| ip addr add $ip broadcast $brd dev br0 |
| done && |
| if [ $x = $mocaifc ]; then |
| x=$mocaifc.0 |
| fi && |
| brctl addif br0 $x && |
| ip -o -f inet route list dev $x | |
| while read dst routeinfo; do |
| if [ "$dst" = "default" ]; then |
| echo "Moving route '$dst' from $x to br0" && |
| ip route del dev $x $dst $routeinfo && |
| ip route add dev br0 $dst $routeinfo |
| fi |
| done && |
| ip -o -f inet addr show $x | |
| while read a b c ip junk; do |
| ip addr del $ip dev $x |
| done |
| done |
| kernopt ip | |
| while IFS=: read ip serverip gatewayip netmask hostname ifc junk; do |
| # $ip should be already setup by simpleramfs. |
| # TODO(apenwarr): simpleramfs should set up $gatewayip too. |
| # But right now its included networking commands are too limited. |
| if [ -n "$gatewayip" ]; then |
| echo "IP: adding default gateway '$gatewayip'" |
| ip route add default via "$gatewayip" |
| fi |
| done |
| echo "Bringing up the bridge..." |
| ifup br0 |
| |
| echo "distribute IRQ handling between cores" |
| redistribute_irqs |
| |
| if [ -e /dev/bmoca0 ]; then |
| echo "starting moca..." |
| babysit 30 runmoca 2>&1 | logos mocad & |
| fi |
| |
| if [ -e /sys/class/net/wan0 ]; then |
| echo "Bringing up the WAN port..." |
| ifup wan0 |
| sysctl net.ipv4.conf.all.forwarding=1 |
| sysctl net.ipv6.conf.all.forwarding=1 |
| fi |
| |
| # Enable hardware offloads, do this at the end to avoid |
| # invalid access caused by powered down core |
| ethtool -K eth0 rx on tx on sg on gso on gro on |
| ethtool -K $mocaifc rx on tx on sg on gso on gro on |
| |
| ;; |
| stop) |
| if [ ! -e /tmp/NFS ]; then |
| if [ -e /sys/class/net/wan0 ]; then |
| echo "Shutting down the WAN port..." |
| ifdown wan0 |
| fi |
| for x in $(ls /sys/class/net); do |
| if [ -n /sys/class/net/$x/bridge ]; then |
| ifdown $x |
| echo "Shutting down $x interface" |
| fi |
| if [ -e /sys/class/net/$x/device ]; then |
| brctl delif br0 $x |
| fi |
| done |
| ifdown br0 |
| # Kill mocad and mocactl |
| if [ -e /dev/bmoca0 ]; then |
| echo -n "mocacfg kill" |
| pkillwait mocad |
| fi |
| fi |
| [ -e /sys/class/net/br0 ] && brctl delbr br0 |
| ;; |
| restart|reload) |
| "$0" stop |
| "$0" start |
| ;; |
| *) |
| echo "Usage: $0 {start|stop|restart}" |
| exit 1 |
| esac |