#!/bin/sh
# Keep the WCN (Marlin3 Lite / SC2355) CP2 out of deep sleep.
#
# NOT ENABLED BY DEFAULT:
#
#   systemctl enable --now rotate-wcn-nosleep.service
#
# What it fixes: after an idle period the first 1-2 s of outbound traffic is lost
# or delayed (ping seq 1 gone, seq 2 at 1.2-2.2 s, then normal). That is all.
#
# What it does NOT fix, despite looking the same from another machine: the board
# becoming unreachable from the LAN when left idle. That was the firmware never
# being told the interface's IPv4 address, and it is fixed in the kernel fork
# ("wifi: sc23xx: notify the firmware of the interface's IPv4 address").
#
# What it costs: about 10 mA on a ~114 mA idle draw, measured with the backlight
# off, associated and silent, three runs of two minutes per state interleaved
# 1/0/1 to cancel drift. On this board's 1900 mAh battery that is standby down
# from 16.6 h to 15.3 h - roughly 8% for a 1-2 s latency nicety, hence off by
# default.
#
# The knob sends "at+debug=1" to the CP2 firmware. The setting does not survive a
# CP2 reboot, so this runs at boot, on wlan0 (re)appearing, and after resume. The
# wake-path bug it papers over is in the vendor sleep manager / sdiohal pub_int
# handshake.
set -u
KNOB=/sys/class/misc/wcn/devices/sleep_state

i=0
while [ ! -w "$KNOB" ]; do
	i=$((i + 1))
	if [ "$i" -gt 60 ]; then
		echo "rotate-wcn-nosleep: $KNOB never appeared" >&2
		exit 1
	fi
	sleep 1
done

if echo 1 > "$KNOB"; then
	echo "rotate-wcn-nosleep: CP2 sleep disabled"
else
	echo "rotate-wcn-nosleep: write to $KNOB failed" >&2
	exit 1
fi
