recover_duts: move reload_network_device from shill/bin/

It's only used by recover_duts, so we should keep it in this directory.
It doesn't belong on base images at all.

BUG=b:112780859
TEST=none

Change-Id: I60a83a2b8826e4deec0f5ba529956d5253abecc8
Signed-off-by: Brian Norris <briannorris@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1565197
Reviewed-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Grant Grundler <grundler@chromium.org>
diff --git a/recover_duts/reload_network_device b/recover_duts/reload_network_device
new file mode 100755
index 0000000..e5285ef
--- /dev/null
+++ b/recover_duts/reload_network_device
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# UDEV event helper script that restarts a hung network device.
+
+POWER_DOWN_TIME_SECONDS=1
+WLAN_POWER_UP_TIME_SECONDS=1
+WLAN_REINITIALIZE_TIME_SECONDS=5
+
+set -e
+
+error () {
+  logger -t $0 "Error: $1"
+  exit 1
+}
+
+if [ -n "${1}" ] ; then
+  eval $(udevadm info --query=property --path="/sys/class/net/${1}" |
+         egrep '^(DEVPATH|DEVTYPE|ID_BUS|INTERFACE|SUBSYSTEM)')
+  EVENT=device_hang
+fi
+
+if [ "${SUBSYSTEM}" != "net" -o \
+     "${EVENT}" != "device_hang" -o \
+     -z "${DEVPATH}" ] ; then
+  exit 0
+fi
+
+logger -t $0 "Restarting network interface ${INTERFACE}"
+
+# The DEVPATH for a network interface should look something like:
+#   /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/net/wlan0
+if [ $(basename $(dirname "${DEVPATH}")) != 'net' ] ; then
+  error "Device path for ${INTERFACE} (${DEVPATH}) is invalid."
+fi
+
+device_path=$(readlink -f "/sys${DEVPATH}/../..")
+module_name=$(basename $(readlink -f "/sys${DEVPATH}/device/driver/module"))
+
+rmmod "${module_name}"
+
+if [ "${ID_BUS}" = "pci" ] ; then
+  device_remove_path="${device_path}/remove"
+  bus_rescan_path=$(readlink -f  "${device_path}/../rescan")
+
+  if [ ! -e "${device_remove_path}" ] ; then
+    error "Device remove path ${device_remove_path} does not exist"
+  fi
+
+  if [ ! -e "${bus_rescan_path}" ] ; then
+    error "Bus rescan path ${bus_rescan_path} does not exist"
+  fi
+
+  echo 1 > "${device_remove_path}"
+  if [ "${DEVTYPE}" = "wlan" ] ; then
+    ectool wireless 0xe  # Disable wireless lan.
+    ectool wireless 0x6  # Power down wireless lan.
+  fi
+
+  sleep ${POWER_DOWN_TIME_SECONDS}
+
+  if [ "${DEVTYPE}" = "wlan" ] ; then
+    ectool wireless 0xe  # Power up wireless lan.
+    sleep ${WLAN_POWER_UP_TIME_SECONDS}
+    ectool wireless 0xf  # Enable wireless lan.
+
+    sleep ${WLAN_REINITIALIZE_TIME_SECONDS}
+  fi
+
+  echo 1 > "${bus_rescan_path}"
+elif [ "${ID_BUS}" = "usb" ] ; then
+  device_authorize_path=$(readlink -f "${device_path}/../authorized")
+  echo 0 > "${device_authorize_path}"
+  sleep ${POWER_DOWN_TIME_SECONDS}
+  echo 1 > "${device_authorize_path}"
+else
+  error "Bus type ${ID_BUS} is unknown"
+fi