Exemple #1
0
static void
w_timer(void* arg)
{
    Ether* ether = (Ether*) arg;
    Ctlr* ctlr = (Ctlr*)ether->ctlr;

    ctlr->timerproc = up;
    for(;;) {
        tsleep(&up->sleep, return0, 0, MSperTick);
        ctlr = (Ctlr*)ether->ctlr;
        if(ctlr == 0)
            break;
        if((ctlr->state & (Attached|Power)) != (Attached|Power))
            continue;
        ctlr->ticks++;

        ilock(ctlr);

        // Seems that the card gets frames BUT does
        // not send the interrupt; this is a problem because
        // I suspect it runs out of receive buffers and
        // stops receiving until a transmit watchdog
        // reenables the card.
        // The problem is serious because it leads to
        // poor rtts.
        // This can be seen clearly by commenting out
        // the next if and doing a ping: it will stop
        // receiving (although the icmp replies are being
        // issued from the remote) after a few seconds.
        // Of course this `bug' could be because I'm reading
        // the card frames in the wrong way; due to the
        // lack of documentation I cannot know.

        if(csr_ins(ctlr, WR_EvSts)&WEvs) {
            ctlr->tickintr++;
            w_intr(ether);
        }

        if((ctlr->ticks % 10) == 0) {
            if(ctlr->txtmout && --ctlr->txtmout == 0) {
                ctlr->nwatchdogs++;
                w_txdone(ctlr, WTxErrEv);
                if(w_enable(ether)) {
                    DEBUG("wavelan: wdog enable failed\n");
                }
                w_txstart(ether);
            }
            if((ctlr->ticks % 120) == 0)
                if(ctlr->txbusy == 0)
                    w_cmd(ctlr, WCmdEnquire, WTyp_Stats);
            if(ctlr->scanticks > 0)
                if((ctlr->ticks % ctlr->scanticks) == 0)
                    if(ctlr->txbusy == 0)
                        w_cmd(ctlr, WCmdEnquire, WTyp_Scan);
        }
        iunlock(ctlr);
    }
    pexit("terminated", 0);
}
Exemple #2
0
void
w_interrupt(Ureg* ,void* arg)
{
	Ether* ether = (Ether*) arg;
	Ctlr* ctlr = (Ctlr*) ether->ctlr;

	if(ctlr == 0)
		return;
	ilock(ctlr);
	ctlr->nints++;
	w_intr(ether);
	iunlock(ctlr);
}