spawn a kernel process to check the broken state of the controller.
if the firmware crashed, or rfkill was toggled we will reset and
reboot the firmware. also power down the card when rfkill is off.
qunlock(ctlr);
}
+static void
+iwlrecover(void *arg)
+{
+ Ether *edev;
+ Ctlr *ctlr;
+
+ edev = arg;
+ ctlr = edev->ctlr;
+ for(;;){
+ while(waserror())
+ ;
+ tsleep(&up->sleep, return0, 0, 4000);
+ poperror();
+
+ qlock(ctlr);
+ for(;;){
+ if(ctlr->broken == 0)
+ break;
+
+ if(ctlr->power)
+ poweroff(ctlr);
+
+ if((csr32r(ctlr, Gpc) & RfKill) == 0)
+ break;
+
+ if(reset(ctlr) != nil)
+ break;
+ if(boot(ctlr) != nil)
+ break;
+
+ ctlr->bcastnodeid = -1;
+ ctlr->bssnodeid = -1;
+ ctlr->aid = 0;
+ rxon(edev, ctlr->wifi->bss);
+ break;
+ }
+ qunlock(ctlr);
+ }
+}
+
static void
iwlattach(Ether *edev)
{
setoptions(edev);
ctlr->attached = 1;
+
+ kproc("iwlrecover", iwlrecover, edev);
}
qunlock(ctlr);
poperror();
receive(ctlr);
if(isr & Ierr){
ctlr->broken = 1;
- iprint("#l%d: fatal firmware error\n", edev->ctlrno);
+ print("#l%d: fatal firmware error\n", edev->ctlrno);
dumpctlr(ctlr);
}
ctlr->wait.m |= isr;