I am running latest stable 19.07 (OpenWrt 19.07.2 r10947-65030d81f3 ) on Tplink Archer C7. My 2.4GHz wifi no longer is accepting the clients. The log file says,
[ 5542.163778] ath10k_pci 0000:01:00.0: SWBA overrun on vdev 0, skipped old beacon
[ 5542.171214] ath10k_pci 0000:01:00.0: SWBA overrun on vdev 0, skipped old beacon
[ 5542.178683] ath10k_pci 0000:01:00.0: SWBA overrun on vdev 0, skipped old beacon
[ 5542.186141] ath10k_pci 0000:01:00.0: SWBA overrun on vdev 0, skipped old beacon
[ 5542.193591] ath10k_pci 0000:01:00.0: SWBA overrun on vdev 0, skipped old beacon
[ 5542.201037] ath10k_pci 0000:01:00.0: SWBA overrun on vdev 0, skipped old beacon
This problem has already bugged me for a long time since 18+. I made a watchdog script which logread's and waits for this specific error. In case the error occurs it either reboots or reloads the driver with rmmod and modprobe.
This way my wifi availability is perceived very stable.
#/bin/sh
#trap "" SIGHUP
#
# Author: Catfriend1
#
# Info: OpenWRT Watchdog Script
# Filename: wrtwatchdog
# Usage: This script gets called during embedded linux startup.
#
# System -> Startup (scroll all the way down)
#
# # Start wrtwatchdog
# bash /root/wrtwatchdog start
# bash /root/wrtwatchdog debug
#
# # Logging and Monitoring:
# bash /root/wrtwatchdog showlog
# bash /root/wrtwatchdog livelog
#
# Installation:
#
# opkg update
# opkg install bash
# chmod +x "/root/wrtwatchdog"
# chmod +x "/root/wrtwatchdog_main.sh"
# bash "/root/wrtwatchdog start"
#
#
# Variables:
#
SERVICE_MAIN_SRC="/root/wrtwatchdog_main.sh"
SERVICE_MAIN_TMP="/tmp/wrtwatchdog_main.sh"
#
SERVICE_MAIN_LOG="/tmp/wrtwatchdog.log"
SERVICE_PID_FILE="/tmp/wrtwatchdog_main.sh.pid"
SHELL_INTERPRETER="bash"
#
#
# Functions:
#
createInstance ()
{
#
# Usage: createInstance
#
#
# Check prerequisites.
#
if [ ! -f "${SERVICE_MAIN_SRC}" ]; then
echo "$0: Creating service instance FAILED. Install ${SERVICE_MAIN_SRC} first."
return
fi
#
# Update script copies in "/tmp".
#
if [ -f "${SERVICE_MAIN_TMP}" ]; then
rm -f "${SERVICE_MAIN_TMP}"
fi
cat "${SERVICE_MAIN_SRC}" > "${SERVICE_MAIN_TMP}"
#
# Set executable and security permissions.
#
chmod +rx "${SERVICE_MAIN_TMP}"
#
# Run service instance.
#
if [ -f "/bin/${SHELL_INTERPRETER}" ]; then
echo "$0: Creating new service instance ..."
set -m
/bin/${SHELL_INTERPRETER} "${SERVICE_MAIN_TMP}" "${DEBUG_MODE}" > /dev/null &
else
echo "$0: Creating service instance FAILED. Install ${SHELL_INTERPRETER} first."
fi
return
}
findProcess ()
{
#
# Usage: findProcess <ps result line>
#
# Purpose: Searches for previously set environment variable "LOOK_FOR_PROCESS".
#
# We got a line from ps similar to:
# [ ]9396 nobody 13952 S /usr/bin/httpd
#
TEMP_RESULT=$(echo -n "$1" | grep -v grep | grep "$LOOK_FOR_PROCESS")
#
# Check if we found process specified in "LOOK_FOR_PROCESS".
#
if test "$TEMP_RESULT"; then
#
# Exclude our own PID from results.
#
MY_PID=$$
GOT_PID=$(echo -n "$1" | sed 's/ \+/|/g' | sed 's/^|//' | cut -d '|' -f 1)
if [ "$MY_PID" != "$GOT_PID" ]; then
if [ "$NEED_SEPARATOR_ONCE" -eq "0" ]; then
NEED_SEPARATOR_ONCE=1
else
echo -n " "
fi
echo -n "$GOT_PID"
fi
fi
return
}
#
terminateOldInstances ()
{
#
# Usage: terminateOldInstances <name_of_instance>
#
#
# Detect and kill any previously running instances of this service.
#
NEED_SEPARATOR_ONCE=0
LOOK_FOR_PROCESS="$1"
PS_LIST="$(ps w)"
PROC_KILL_LIST=$(echo -e "$PS_LIST" | while read file; do findProcess "${file}"; done)
if test "$PROC_KILL_LIST"; then
echo "$0: Terminating old \"$LOOK_FOR_PROCESS\" instance(s) #$PROC_KILL_LIST ..."
kill $PROC_KILL_LIST
fi
return
}
#
# ! Not supported on BusyBox routers.
#. /lib/lsb/init-functions
#
#
# Service instance control main.
#
DEBUG_MODE=""
case "$1" in
'debug')
# Set DEBUG_MODE to ON.
DEBUG_MODE="debug"
;;
esac
case "$1" in
'start' | 'reset' | 'restart' | 'debug')
sh $0 stop
#
# Hauptprogramm des Dienstes in neuer Instanz ausfuehren.
createInstance
#
exit 0
;;
'stop')
if [ -f "${SERVICE_PID_FILE}" ]; then
kill -INT "$(cat "${SERVICE_PID_FILE}")"
rm "${SERVICE_PID_FILE}"
fi
#
# Speicher von laufenden Instanzen befreien.
terminateOldInstances "${SHELL_INTERPRETER} ${SERVICE_MAIN_TMP}"
#
exit 0
;;
'showlog')
# Zeige Log des Dienstes.
tail -n 60 "${SERVICE_MAIN_LOG}"
exit 0
;;
'livelog')
# Zeige Log des Dienstes.
clear
tail -f "${SERVICE_MAIN_LOG}"
exit 0
;;
'diag')
ps w | egrep "watchdog|tail|logread" | grep -v "grep" | grep -v "livelog" | grep -v "diag"
exit 0
;;
'clean')
exit 0
;;
esac
echo "Usage: $0 {start|debug|stop|reset|restart|showlog|livelog|clean}"
exit 0
/root/wrtwatchdog_main.sh
#/bin/bash
trap "" SIGHUP
#
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
#
# set +m
#
# Info: OpenWRT Watchdog Service Main Loop
# Prerequisites:
#
# * BASH (required for arrays)
#
# Filename: wrtwatchdog_main.sh
# Usage: This script gets instanced by "wrtwatchdog".
#
# Author: Catfriend1
#
# Prerequisites:
#
# wrtwatchdog main service wrapper
# wrtwatchdog_main.sh main service program
#
# For testing purposes only:
# killall logread; killall tail; sh wrtwatchdog stop; bash wrtwatchdog_main.sh debug
# kill -INT "$(cat "/tmp/wrtwatchdog_main.sh.pid")"
#
# Script Configuration.
#
PATH=/usr/bin:/usr/sbin:/sbin:/bin
CURRENT_SCRIPT_PATH="$(cd "$(dirname "$0")"; pwd)"
PID_FILE=/tmp/"$(basename "$0")".pid
LOGFILE="/tmp/wrtwatchdog.log"
LOG_MAX_LINES="1000"
DEBUG_MODE="0"
#
# Variables: RUNTIME.
#
MY_SERVICE_NAME="$(basename "$0")"
#
# -----------------------
# --- Function Import ---
# -----------------------
#
#
# -----------------------------------------------------
# -------------- START OF FUNCTION BLOCK --------------
# -----------------------------------------------------
logAdd ()
{
TMP_DATETIME="$(date '+%Y-%m-%d [%H-%M-%S]')"
TMP_LOGSTREAM="$(tail -n ${LOG_MAX_LINES} ${LOGFILE} 2>/dev/null)"
echo "${TMP_LOGSTREAM}" > "$LOGFILE"
if [ "$1" == "-q" ]; then
#
# Quiet mode.
#
echo "${TMP_DATETIME} ${@:2}" >> "${LOGFILE}"
else
#
# Loud mode.
#
echo "${TMP_DATETIME} $*" | tee -a "${LOGFILE}"
fi
return
}
logreader() {
#
# Called by: MAIN
#
logAdd -q "[INFO] BEGIN logreader_loop"
/sbin/logread -f | while read line; do
if $(echo -n "${line}" | grep -q "kernel.*ath10k_pci.*failed to send pdev bss chan info request"); then
logAdd -q "[ERROR] ath10k_pci 5G WiFi card failed. Restarting driver ..."
rmmod ath10k_pci
sleep 2
modprobe ath10k_pci
sleep 5
logAdd -q "[INFO] Restarting wifi after driver restart ..."
wifi up
fi
done
}
# ---------------------------------------------------
# -------------- END OF FUNCTION BLOCK --------------
# ---------------------------------------------------
#
#
#
#
#
#
#
#
# Check commmand line parameters.
#
case "$1" in
'debug')
# Turn DEBUG_MODE on.
DEBUG_MODE="1"
# Continue script execution.
;;
esac
#
# Service Startup.
#
if [ "${DEBUG_MODE}" == "0" ]; then
logAdd "${MY_SERVICE_NAME} wurde neu gestartet."
sleep 10
else
# Log message.
logAdd "${MY_SERVICE_NAME} wurde im DEBUG_MODE neu gestartet."
fi
#
# Service Main.
#
# Store script PID.
echo "$$" > "${PID_FILE}"
#
# Fork three permanently running background processes.
logreader &
#
# Wait for kill -INT from service stub.
wait
#
# We should never reach here.
#
logAdd "${MY_SERVICE_NAME}: End of script reached."
exit 0
Autorun setup:
Edit /etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
/bin/bash /root/wrtwatchdog start
exit 0