Add MwifiexFirmwareRecovery experiment in wifi.py

This experiment will enable a debug flag firmware_recover in mwifiex
so that it will attempt a reset when it does not respond under certain
conditions.

See b/31916833

Change-Id: Iceb5a6f495c0343ef3a561a0d819a5b34173160d
diff --git a/wifi/configs.py b/wifi/configs.py
index 240dd63..4dcdaab 100644
--- a/wifi/configs.py
+++ b/wifi/configs.py
@@ -23,6 +23,7 @@
     'WifiShortAggTimeout',
     'WifiNoAggTimeout',
     'WifiNoAliveMonitor',
+    'MwifiexFirmwareRecovery',
 ]
 for _i in EXPERIMENTS:
   experiment.register(_i)
diff --git a/wifi/mwifiex.py b/wifi/mwifiex.py
new file mode 100755
index 0000000..8cad3ac
--- /dev/null
+++ b/wifi/mwifiex.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python -S
+
+"""Special handling for mwifiex driver.
+
+   The mwifiex driver has a mechanism to detect when the firmware is
+   stuck and attempt a reset. It is disabled by default and can be
+   configured with this helper.
+"""
+import glob
+import utils
+
+_MWIFIEX_SYS_RECOVERY = '/sys/kernel/debug/mwifiex/*/firmware_recover'
+
+
+def set_recovery(recovery_flag):
+  # Marvell's firmware can get into a non-recovery state
+  # that hangs forever. The driver can detect this state and perform a
+  # a reset when enabled with a debug flag, which is done here when the
+  # corresponding experiment is active.
+  recovery_flag = int(recovery_flag)
+  for sys_path in glob.glob(_MWIFIEX_SYS_RECOVERY):
+    utils.log('mwifiex.py: set %r to %r.' % (sys_path, recovery_flag))
+    open(sys_path, 'w').write(str(recovery_flag))
diff --git a/wifi/wifi.py b/wifi/wifi.py
index a0aa84b..19e2d13 100755
--- a/wifi/wifi.py
+++ b/wifi/wifi.py
@@ -17,6 +17,7 @@
 import configs
 import experiment
 import iw
+import mwifiex
 import options
 import persist
 import qca9880_cal
@@ -252,6 +253,7 @@
 
   # Check for calibration errors on ath10k.
   qca9880_cal.qca8990_calibration()
+  mwifiex.set_recovery(experiment.enabled('MwifiexFirmwareRecovery'))
 
   client_interface = iw.find_interface_from_phy(
       phy, iw.INTERFACE_TYPE.client, opt.interface_suffix)
@@ -987,6 +989,8 @@
   if band == '5' and quantenna.set_client_wifi(opt):
     return True
 
+  mwifiex.set_recovery(experiment.enabled('MwifiexFirmwareRecovery'))
+
   phy = iw.find_phy(band, 'auto')
   if phy is None:
     utils.log("Couldn't find phy for band %s", band)