mirror of https://github.com/aredn/aredn.git
Alternate ath9k and ath10k radio reset for deaf nodes (#857)
* A scan, especially if we have to do both active and passive, essentially mutes the radio to AREDN traffic for 10-20 seconds, which isn't good. If the radio is completely deaf then it doesn't matter, but particularly on the 9K radios we do this when things are looking a bit dodgy, though not deaf. * Provide hook to reset ath9k from userspace. This hook is attributed to: Linus Lüssing <ll@simonwunderlich.de> * User /sys reset hooks rather than iw scan
This commit is contained in:
parent
0890ab210f
commit
a61dfcdafe
|
@ -33,10 +33,9 @@
|
|||
|
||||
--]]
|
||||
|
||||
local periodic_scan_time = 300 -- 5 minutes
|
||||
local periodic_scan_tick = 5
|
||||
|
||||
local wifiiface
|
||||
local last_scan_time = 0
|
||||
|
||||
function rssi_monitor_10k()
|
||||
if not string.match(get_ifname("wifi"), "^wlan") then
|
||||
|
@ -67,9 +66,13 @@ if not file_exists(logfile) then
|
|||
io.open(logfile, "w+"):close()
|
||||
end
|
||||
|
||||
local last_station_count = 0
|
||||
local station_zero = 0
|
||||
local log = aredn.log.open(logfile, 16000)
|
||||
|
||||
local function reset_network()
|
||||
write_all("/sys/kernel/debug/ieee80211/" .. phy .. "/ath10k/simulate_fw_crash", "hw-restart")
|
||||
end
|
||||
|
||||
function run_monitor_10k()
|
||||
|
||||
local station_count = 0
|
||||
|
@ -79,15 +82,16 @@ function run_monitor_10k()
|
|||
station_count = station_count + 1
|
||||
end
|
||||
|
||||
if station_count == 0 and (last_station_count ~= 0 or nixio.sysinfo().uptime > periodic_scan_time + last_scan_time) then
|
||||
-- reset
|
||||
last_scan_time = nixio.sysinfo().uptime
|
||||
os.execute("/usr/sbin/iw " .. wifiiface .. " scan > /dev/null 2>&1")
|
||||
os.execute("/usr/sbin/iw " .. wifiiface .. " scan passive > /dev/null 2>&1")
|
||||
log:write("No stations detected")
|
||||
log:flush()
|
||||
if station_count ~= 0 then
|
||||
station_zero = periodic_scan_tick - 1
|
||||
else
|
||||
station_zero = station_zero + 1
|
||||
if math.mod(station_zero, periodic_scan_tick) == 0 then
|
||||
reset_network()
|
||||
log:write("No stations detected")
|
||||
log:flush()
|
||||
end
|
||||
end
|
||||
last_station_count = station_count
|
||||
end
|
||||
|
||||
return rssi_monitor_10k
|
||||
|
|
|
@ -75,9 +75,14 @@ if not file_exists(logfile) then
|
|||
io.open(logfile, "w+"):close()
|
||||
end
|
||||
|
||||
local last_station_count = 0
|
||||
local station_zero = 0
|
||||
local periodic_scan_tick = 5
|
||||
local log = aredn.log.open(logfile, 16000)
|
||||
|
||||
local function reset_network()
|
||||
write_all("/sys/kernel/debug/ieee80211/" .. phy .. "/ath9k/reset", "1")
|
||||
end
|
||||
|
||||
function run_monitor_9k()
|
||||
|
||||
local now = nixio.sysinfo().uptime
|
||||
|
@ -105,13 +110,6 @@ function run_monitor_9k()
|
|||
end
|
||||
end
|
||||
local amac = nil
|
||||
|
||||
-- avoid node going deaf while trying to obtain 'normal' statistics of neighbor strength
|
||||
-- in first few minutes after boot
|
||||
if now > 119 and now < 750 then
|
||||
os.execute("/usr/sbin/iw " .. wifiiface .. " scan > /dev/null 2>&1")
|
||||
end
|
||||
|
||||
local station_count = 0
|
||||
local rssi = get_rssi(wifiiface)
|
||||
for mac, info in pairs(rssi)
|
||||
|
@ -166,9 +164,7 @@ function run_monitor_9k()
|
|||
end
|
||||
|
||||
if amac then
|
||||
-- reset
|
||||
os.execute("/usr/sbin/iw " .. wifiiface .. " scan > /dev/null 2>&1")
|
||||
os.execute("/usr/sbin/iw " .. wifiiface .. " scan passive > /dev/null 2>&1")
|
||||
reset_network()
|
||||
wait_for_ticks(5)
|
||||
-- update time
|
||||
now = nixio.sysinfo().uptime
|
||||
|
@ -202,13 +198,18 @@ function run_monitor_9k()
|
|||
rssih.num = rssih.num + 1
|
||||
end
|
||||
end
|
||||
elseif station_count == 0 and last_station_count ~= 0 then
|
||||
-- reset
|
||||
os.execute("/usr/sbin/iw " .. wifiiface .. " scan > /dev/null 2>&1")
|
||||
wait_for_ticks(5)
|
||||
log:write("No stations detected")
|
||||
else
|
||||
if station_count ~= 0 then
|
||||
station_zero = periodic_scan_tick - 1
|
||||
else
|
||||
station_zero = station_zero + 1
|
||||
if math.mod(station_zero, periodic_scan_tick) == 0 then
|
||||
reset_network()
|
||||
wait_for_ticks(5)
|
||||
log:write("No stations detected")
|
||||
end
|
||||
end
|
||||
end
|
||||
last_station_count = station_count
|
||||
|
||||
local f = io.open(datfile, "w")
|
||||
if f then
|
||||
|
|
|
@ -51,7 +51,6 @@ local log = aredn.log.open(logfile, 8000)
|
|||
|
||||
function rejoin_network()
|
||||
os.execute(IW .. " " .. wifiiface .. " ibss leave")
|
||||
nixio.nanosleep(1, 0)
|
||||
os.execute(IW .. " " .. wifiiface .. " ibss join " .. ssid .. " " .. frequency .. " fixed-freq")
|
||||
log:write("Rejoining network")
|
||||
log:flush()
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
--- /dev/null
|
||||
+++ b/package/kernel/mac80211/patches/ath/301-ath-reset.patch
|
||||
@@ -0,0 +1,96 @@
|
||||
+diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+index 4c81b1d7f417..fb7a2952d0ce 100644
|
||||
+--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
++++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+@@ -749,9 +749,9 @@ static int read_file_misc(struct seq_file *file, void *data)
|
||||
+
|
||||
+ static int read_file_reset(struct seq_file *file, void *data)
|
||||
+ {
|
||||
+- struct ieee80211_hw *hw = dev_get_drvdata(file->private);
|
||||
+- struct ath_softc *sc = hw->priv;
|
||||
++ struct ath_softc *sc = file->private;
|
||||
+ static const char * const reset_cause[__RESET_TYPE_MAX] = {
|
||||
++ [RESET_TYPE_USER] = "User reset",
|
||||
+ [RESET_TYPE_BB_HANG] = "Baseband Hang",
|
||||
+ [RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog",
|
||||
+ [RESET_TYPE_FATAL_INT] = "Fatal HW Error",
|
||||
+@@ -779,6 +779,55 @@ static int read_file_reset(struct seq_file *file, void *data)
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
++static int open_file_reset(struct inode *inode, struct file *f)
|
||||
++{
|
||||
++ return single_open(f, read_file_reset, inode->i_private);
|
||||
++}
|
||||
++
|
||||
++static ssize_t write_file_reset(struct file *file,
|
||||
++ const char __user *user_buf,
|
||||
++ size_t count, loff_t *ppos)
|
||||
++{
|
||||
++ struct ath_softc *sc = file_inode(file)->i_private;
|
||||
++ struct ath_hw *ah = sc->sc_ah;
|
||||
++ struct ath_common *common = ath9k_hw_common(ah);
|
||||
++ unsigned long val;
|
||||
++ char buf[32];
|
||||
++ ssize_t len;
|
||||
++
|
||||
++ len = min(count, sizeof(buf) - 1);
|
||||
++ if (copy_from_user(buf, user_buf, len))
|
||||
++ return -EFAULT;
|
||||
++
|
||||
++ buf[len] = '\0';
|
||||
++ if (kstrtoul(buf, 0, &val))
|
||||
++ return -EINVAL;
|
||||
++
|
||||
++ if (val != 1)
|
||||
++ return -EINVAL;
|
||||
++
|
||||
++ /* avoid rearming hw_reset_work on shutdown */
|
||||
++ mutex_lock(&sc->mutex);
|
||||
++ if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
|
||||
++ mutex_unlock(&sc->mutex);
|
||||
++ return -EBUSY;
|
||||
++ }
|
||||
++
|
||||
++ ath9k_queue_reset(sc, RESET_TYPE_USER);
|
||||
++ mutex_unlock(&sc->mutex);
|
||||
++
|
||||
++ return count;
|
||||
++}
|
||||
++
|
||||
++static const struct file_operations fops_reset = {
|
||||
++ .read = seq_read,
|
||||
++ .write = write_file_reset,
|
||||
++ .open = open_file_reset,
|
||||
++ .owner = THIS_MODULE,
|
||||
++ .llseek = seq_lseek,
|
||||
++ .release = single_release,
|
||||
++};
|
||||
++
|
||||
+ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
+ struct ath_tx_status *ts, struct ath_txq *txq,
|
||||
+ unsigned int flags)
|
||||
+@@ -1393,8 +1442,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
+ read_file_queues);
|
||||
+ debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy,
|
||||
+ read_file_misc);
|
||||
+- debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy,
|
||||
+- read_file_reset);
|
||||
++ debugfs_create_file("reset", 0600, sc->debug.debugfs_phy,
|
||||
++ sc, &fops_reset);
|
||||
+
|
||||
+ ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
|
||||
+ ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
|
||||
+diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
|
||||
+index 33826aa13687..389459c04d14 100644
|
||||
+--- a/drivers/net/wireless/ath/ath9k/debug.h
|
||||
++++ b/drivers/net/wireless/ath/ath9k/debug.h
|
||||
+@@ -39,6 +39,7 @@ struct fft_sample_tlv;
|
||||
+ #endif
|
||||
+
|
||||
+ enum ath_reset_type {
|
||||
++ RESET_TYPE_USER,
|
||||
+ RESET_TYPE_BB_HANG,
|
||||
+ RESET_TYPE_BB_WATCHDOG,
|
||||
+ RESET_TYPE_FATAL_INT,
|
||||
+
|
|
@ -2,6 +2,7 @@
|
|||
001-ath79-cpe220v3-sysupgrade-supported.patch
|
||||
001-ath79-reverse-wpad-basic-wolfssl.patch
|
||||
006-rocket-m-flash-fix.patch
|
||||
701-ath9k-reset.patch
|
||||
701-extended-spectrum.patch
|
||||
702-enable-country-hx.patch
|
||||
703-fix-dnsmasq.patch
|
||||
|
|
Loading…
Reference in New Issue