Exemple #1
0
void
w_power(Ether* ether, int on)
{
	Ctlr *ctlr;

	ctlr = (Ctlr*) ether->ctlr;
	ilock(ctlr);
iprint("w_power %d\n", on);
	if(on){
		if((ctlr->state & Power) == 0){
			if (wavelanreset(ether, ctlr) < 0){
				iprint("w_power: reset failed\n");
				iunlock(ctlr);
				w_detach(ether);
				free(ctlr);
				return;
			}
			if(ctlr->state & Attached)
				w_enable(ether);
			ctlr->state |= Power;
		}
	}else{
		if(ctlr->state & Power){
			if(ctlr->state & Attached)
				w_intdis(ctlr);
			ctlr->state &= ~Power;
		}
	}
	iunlock(ctlr);
}
Exemple #2
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 #3
0
void
w_attach(Ether* ether)
{
	Ctlr* ctlr;
	char name[64];
	int rc;

	if(ether->ctlr == 0)
		return;

	snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno);
	ctlr = (Ctlr*) ether->ctlr;
	if((ctlr->state & Attached) == 0){
		ilock(ctlr);
		rc = w_enable(ether);
		iunlock(ctlr);
		if(rc == 0){
			ctlr->state |= Attached;
			kproc(name, w_timer, ether);
		} else
			print("#l%d: enable failed\n",ether->ctlrno);
	}
}
Exemple #4
0
long
w_ctl(Ether* ether, void* buf, long n)
{
	Ctlr *ctlr;

	if((ctlr = ether->ctlr) == nil)
		error(Enonexist);
	if((ctlr->state & Attached) == 0)
		error(Eshutdown);

	ilock(ctlr);
	if(w_option(ctlr, buf, n)){
		iunlock(ctlr);
		error(Ebadctl);
	}
	if(ctlr->txbusy)
		w_txdone(ctlr, WTxErrEv);
	w_enable(ether);
	w_txstart(ether);
	iunlock(ctlr);

	return n;
}