diff --git a/package/gluon-ath9k-workaround/Makefile b/package/gluon-ath9k-workaround/Makefile new file mode 100644 index 00000000..bc809df8 --- /dev/null +++ b/package/gluon-ath9k-workaround/Makefile @@ -0,0 +1,35 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=gluon-ath9k-workaround +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/gluon-ath9k-workaround + SECTION:=gluon + CATEGORY:=Gluon + TITLE:=ATH9K Workaround + DEPENDS:=+gluon-cron +endef + +define Package/gluon-ath9k-workaround/description + Gluon community wifi mesh firmware framework: ath9k wifi bug workaround +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/gluon-ath9k-workaround/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,gluon-ath9k-workaround)) diff --git a/package/gluon-ath9k-workaround/files/lib/gluon/cron/ath9k-workaround b/package/gluon-ath9k-workaround/files/lib/gluon/cron/ath9k-workaround new file mode 100644 index 00000000..73552f9b --- /dev/null +++ b/package/gluon-ath9k-workaround/files/lib/gluon/cron/ath9k-workaround @@ -0,0 +1 @@ +* * * * * /usr/sbin/ath9k-workaround diff --git a/package/gluon-ath9k-workaround/files/lib/gluon/upgrade/ath9k-workaround/invariant/010-monitor b/package/gluon-ath9k-workaround/files/lib/gluon/upgrade/ath9k-workaround/invariant/010-monitor new file mode 100755 index 00000000..ac696247 --- /dev/null +++ b/package/gluon-ath9k-workaround/files/lib/gluon/upgrade/ath9k-workaround/invariant/010-monitor @@ -0,0 +1,12 @@ +#!/usr/bin/lua + +local site = require 'gluon.site_config' +local uci = require 'luci.model.uci' + +local c = uci.cursor() + +local f = io.open('/lib/gluon/cron/ath9k-workaround','w') +if f and site.monitor ~= nil then + f:write('* * * * * /usr/sbin/ath9k-workaround | nc ' .. site.monitor) + f:close() +end diff --git a/package/gluon-ath9k-workaround/files/usr/sbin/ath9k-workaround b/package/gluon-ath9k-workaround/files/usr/sbin/ath9k-workaround new file mode 100755 index 00000000..fccd218f --- /dev/null +++ b/package/gluon-ath9k-workaround/files/usr/sbin/ath9k-workaround @@ -0,0 +1,61 @@ +#!/bin/sh + +check_stopped_queue(){ + local device=$1 + grep -q -E 'stopped: 1$' "${device}/queues" +} + +get_tx_pkts() { + local device=$1 + grep 'TX-Pkts-All' "${device}/xmit" \ + | sed -e 's/^TX-Pkts-All: *\([0-9]*\) .*$/\1/' +} + +inc_fatal() { + local qs=$(cat /tmp/ath9k_workaround_trigger 2>/dev/null || echo 0) + expr ${qs} + 1 > /tmp/ath9k_workaround_trigger +} + +check_ath9k_bug() { + local device=$1 + check_stopped_queue $device && { + local tx_first=$(get_tx_pkts $device) + sleep 5 + check_stopped_queue $device && { + local tx_second=$(get_tx_pkts $device) + test $tx_first == $tx_second && { + local hostname=$(uci get -q system.@system[0].hostname) + echo "Hostname: ${hostname}" + echo "------------ Trigger workaround: ${tx_first} -> ${tx_second} ----------------" + echo "Model:" + cat /tmp/sysinfo/model + echo "Release:" + cat /lib/gluon/release + echo "Uptime:" + uptime + echo "Batctl Neighbours:" + batctl o | grep wlan0-1 + echo "Queues:" + cat $device/queues + echo "Reset:" + cat $device/reset + echo "------------ Interupts #1 ---------------------------------------------------" + cat $device/interrupt + sleep 10 + echo "------------ Interupts #2 ---------------------------------------------------" + cat $device/interrupt + echo "Batctl Neighbours:" + batctl o | grep wlan0-1 + + #BE queue hangs + inc_fatal + wifi + exit 1; + } + } + } +} + +for device in /sys/kernel/debug/ieee80211/phy*/ath9k ; do + check_ath9k_bug $device +done