--- /sys/src/9/pc/etheriwl.c +++ /sys/src/9/pc/etheriwl.c @@ -329,7 +329,18 @@ SchedTransTblOff = 0x7E0, // +q*2 }; +/* + * uCode capabilities + */ enum { + /* capa[0] */ + UcodeCapLar = 1<<1, + + /* capa[2] */ + UcodeCapLar2 = 1<<9, +}; + +enum { FilterPromisc = 1<<0, FilterCtl = 1<<1, FilterMulticast = 1<<2, @@ -418,6 +429,7 @@ uint build; char descr[64+1]; + u32int flags; u32int capa[4]; u32int api[4]; @@ -635,7 +647,7 @@ Type2030 = 12, Type2000 = 16, - Type7260 = 30, + Type7260 = 20, Type8265 = 35, }; @@ -1478,6 +1490,11 @@ s = &i->boot.text; s->addr = 0x00000000; goto Sect; + case 18: + if(l < 4) + goto Tooshort; + i->flags = get32(p); + break; case 19: if(i->main.nsect >= nelem(i->main.sect)) return "too many main sections"; @@ -1984,7 +2001,7 @@ *p++ = mcc[0]; *p++ = 0; *p++ = 0; // reserved - if(1){ + if(ctlr->fw->capa[2] & UcodeCapLar2){ p += 4; p += 5*4; } @@ -2272,7 +2289,9 @@ ea[5] = a1 >> 0; } } else { - readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1); + /* fw gets angry if we read 6 bytes instead of 8 */ + readnvmsect(ctlr, 0, buf, 8, 0x15<<1); + memmove(ea, buf, Eaddrlen); } memmove(ctlr->edev->addr, ea, Eaddrlen); @@ -2655,6 +2674,9 @@ amr = CmdModify; } break; + case CmdRemove: + if(!ctlr->te.active) + return nil; default: timeid = ctlr->te.id; if(timeid == -1) @@ -2678,20 +2700,24 @@ put32(p, timeid); p += 4; - put32(p, 0); // apply time - p += 4; - put32(p, delay); - p += 4; - put32(p, 0); // depends on - p += 4; - put32(p, 1); // interval - p += 4; - put32(p, duration); - p += 4; - *p++ = 1; // repeat - *p++ = 0; // max frags - put16(p, 1<<0 | 1<<1 | 1<<11); // policy - p += 2; + if(amr == CmdRemove) + p += 6*4; + else{ + put32(p, 0); // apply time + p += 4; + put32(p, delay); + p += 4; + put32(p, 0); // depends on + p += 4; + put32(p, 1); // interval + p += 4; + put32(p, duration); + p += 4; + *p++ = 1; // repeat + *p++ = 0; // max frags + put16(p, 1<<0 | 1<<1 | 1<<11); // policy + p += 2; + } ctlr->te.active = 0; if((err = cmd(ctlr, 41, c, p - c)) != nil) @@ -2822,13 +2848,13 @@ return cmd(ctlr, 210, c, 11*4); } -static void +static char* tttxbackoff(Ctlr *ctlr) { uchar c[4]; put32(c, 0); - cmd(ctlr, 126, c, sizeof(c)); + return cmd(ctlr, 126, c, sizeof(c)); } static char* @@ -2897,16 +2923,16 @@ /* Initialize tx backoffs to the minimum. */ if(ctlr->family == 7000) - tttxbackoff(ctlr); + if((err = tttxbackoff(ctlr)) != nil) + return err; if((err = updatedevicepower(ctlr)) != nil){ print("can't update device power: %s\n", err); return err; } - if((err = sendmccupdate(ctlr, "ZZ")) != nil){ - print("can't disable beacon filter: %s\n", err); - return err; - } + if(ctlr->fw->capa[0] & UcodeCapLar) + if((err = sendmccupdate(ctlr, "ZZ")) != nil) + return err; if((err = disablebeaconfilter(ctlr)) != nil){ print("can't disable beacon filter: %s\n", err); return err; @@ -3418,6 +3444,7 @@ static char* qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block) { + char *err; int hdrlen; Block *bcmd; uchar *d, *c; @@ -3452,10 +3479,10 @@ return "qcmd: broken"; } /* wake up the nic (just needed for 7k) */ - if(ctlr->family == 7000 && q->n == 0) - if(niclock(ctlr) != nil){ + if(ctlr->family == 7000 && qid == 4 && q->n == 0) + if((err = niclock(ctlr)) != nil){ iunlock(ctlr); - return "qcmd: busy"; + return err; } q->n++; q->lastcmd = code; @@ -3586,9 +3613,16 @@ int i; for(i = 0; i < nelem(ctlr->tx); i++) - flushq(ctlr, i); - settimeevent(ctlr, CmdRemove, 0); + if((err = flushq(ctlr, i)) != nil){ + print("can't flush queue %d: %s", i, err); + return err; + } + if((err = settimeevent(ctlr, CmdRemove, 0)) != nil){ + print("can't remove time event: %s", err); + return err; + } + if((err = setbindingquotas(ctlr, -1)) != nil){ print("can't disable quotas: %s\n", err); return err; @@ -4283,8 +4317,8 @@ if(tx != nil && tx->n > 0){ tx->n--; wakeup(tx); - /* unlock 7k family nics as all commands are done */ - if(ctlr->family == 7000 && tx->n == 0) + /* unlock 7k family nics as the command is done */ + if(ctlr->family == 7000 && qid == 4 && tx->n == 0) nicunlock(ctlr); } }