From 092fd361547c9beef9cf0ffbee46b2de579b4214 Mon Sep 17 00:00:00 2001 From: ftrvxmtrx Date: Sun, 10 Feb 2013 20:46:56 +0100 Subject: mp.h: fix typo --- sys/include/mp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/include/mp.h b/sys/include/mp.h index 0cfc9e211..c7179c959 100644 --- a/sys/include/mp.h +++ b/sys/include/mp.h @@ -45,7 +45,7 @@ int mpfmt(Fmt*); char* mptoa(mpint*, int, char*, int); mpint* letomp(uchar*, uint, mpint*); /* byte array, little-endian */ int mptole(mpint*, uchar*, uint, uchar**); -mpint* betomp(uchar*, uint, mpint*); /* byte array, little-endian */ +mpint* betomp(uchar*, uint, mpint*); /* byte array, big-endian */ int mptobe(mpint*, uchar*, uint, uchar**); uint mptoui(mpint*); /* unsigned int */ mpint* uitomp(uint, mpint*); -- cgit v1.2.3 From ffb3ded366b7878c4fa70773bcc3f8260a010f90 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 11 Feb 2013 00:09:41 +0100 Subject: etheriwl: automatic channel scanning, transmission handling, promisc mode the channel= plan9.ini parameter isnt needed anymore as we now hop the channels to scan for beacons. the status is also indicated with the link led :-) handle all these flags on packet transmission like RTS for big packets and sending data packets to the AP instead of broadcasting everything. properly setup bss hardware node table and filtering. now promisc mode is only used when requested. handle deauth message from ap. increase node table to 32 entries. --- sys/src/9/pc/etheriwl.c | 283 +++++++++++++++++++++++++++++++++++++++++------- sys/src/9/pc/mkfile | 1 + sys/src/9/pc/wifi.c | 55 +++++++--- sys/src/9/pc/wifi.h | 6 +- 4 files changed, 283 insertions(+), 62 deletions(-) diff --git a/sys/src/9/pc/etheriwl.c b/sys/src/9/pc/etheriwl.c index 19fd2db70..9fff050bc 100644 --- a/sys/src/9/pc/etheriwl.c +++ b/sys/src/9/pc/etheriwl.c @@ -222,6 +222,28 @@ enum { SchedTransTblOff5000 = 0x7e0, }; +enum { + FilterPromisc = 1<<0, + FilterCtl = 1<<1, + FilterMulticast = 1<<2, + FilterNoDecrypt = 1<<3, + FilterBSS = 1<<5, + FilterBeacon = 1<<6, +}; + +enum { + RFlag24Ghz = 1<<0, + RFlagCCK = 1<<1, + RFlagAuto = 1<<2, + RFlagShSlot = 1<<4, + RFlagShPreamble = 1<<5, + RFlagNoDiversity = 1<<7, + RFlagAntennaA = 1<<8, + RFlagAntennaB = 1<<9, + RFlagTSF = 1<<15, + RFlagCTSToSelf = 1<<30, +}; + typedef struct FWInfo FWInfo; typedef struct FWImage FWImage; typedef struct FWSect FWSect; @@ -303,7 +325,14 @@ struct Ctlr { u32int *nic; uchar *kwpage; + /* assigned node ids in hardware node table or -1 if unassigned */ + int bcastnodeid; + int bssnodeid; + + /* current receiver settings */ int channel; + int prom; + int aid; RXQ rx; TXQ tx[20]; @@ -1019,12 +1048,11 @@ qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block) q = &ctlr->tx[qid]; while(q->n >= Ntx){ iunlock(ctlr); - eqlock(q); - if(waserror()){ - qunlock(q); - nexterror(); + qlock(q); + if(!waserror()){ + tsleep(q, txqready, q, 10); + poperror(); } - tsleep(q, txqready, q, 10); qunlock(q); ilock(ctlr); } @@ -1067,12 +1095,42 @@ qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block) iunlock(ctlr); } +static int +txqempty(void *arg) +{ + TXQ *q = arg; + return q->n == 0; +} + +static void +flushq(Ctlr *ctlr, uint qid) +{ + TXQ *q; + + q = &ctlr->tx[qid]; + while(q->n > 0){ + qlock(q); + if(!waserror()){ + tsleep(q, txqempty, q, 10); + poperror(); + } + qunlock(q); + } +} + + static void cmd(Ctlr *ctlr, uint code, uchar *data, int size) { qcmd(ctlr, 4, code, data, size, nil); } +static void +flushcmd(Ctlr *ctlr) +{ + flushq(ctlr, 4); +} + static void setled(Ctlr *ctlr, int which, int on, int off) { @@ -1099,9 +1157,6 @@ postboot(Ctlr *ctlr) char *err; int i, q; - /* main led turn on! (verify that firmware processes commands) */ - setled(ctlr, 2, 0, 1); - if((err = niclock(ctlr)) != nil) error(err); @@ -1228,12 +1283,42 @@ rxon(Ether *edev, Wnode *bss) { uchar c[Tcmdsize], *p; Ctlr *ctlr; + uchar *bssid; + int filter, flags; ctlr = edev->ctlr; + bssid = edev->bcast; + filter = FilterMulticast | FilterBeacon; + if(ctlr->prom) + filter |= FilterPromisc; + if(bss != nil){ + ctlr->channel = bss->channel; + if(bss->aid != 0){ + bssid = bss->bssid; + filter |= FilterBSS; + filter &= ~FilterBeacon; + ctlr->aid = bss->aid; + + ctlr->bssnodeid = -1; + } else { + filter &= ~FilterBSS; + filter |= FilterBeacon; + ctlr->aid = 0; + + ctlr->bcastnodeid = -1; + } + } else { + ctlr->bcastnodeid = -1; + ctlr->bssnodeid = -1; + } + flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto; + + if(0) print("rxon: bssid %E, aid %x, channel %d, filter %x, flags %x\n", + bssid, ctlr->aid, ctlr->channel, filter, flags); + memset(p = c, 0, sizeof(c)); memmove(p, edev->ea, 6); p += 8; /* myaddr */ - memmove(p, (bss != nil) ? bss->bssid : edev->bcast, 6); - p += 8; /* bssid */ + memmove(p, bssid, 6); p += 8; /* bssid */ memmove(p, edev->ea, 6); p += 8; /* wlap */ *p++ = 3; /* mode (STA) */ *p++ = 0; /* air (?) */ @@ -1242,14 +1327,13 @@ rxon(Ether *edev, Wnode *bss) p += 2; *p++ = 0xff; /* ofdm mask (not yet negotiated) */ *p++ = 0x0f; /* cck mask (not yet negotiated) */ - if(bss != nil) - put16(p, bss->aid & ~0xc000); + put16(p, ctlr->aid & 0x3fff); p += 2; /* aid */ - put32(p, (1<<15)|(1<<30)|(1<<0)); /* flags (TSF | CTS_TO_SELF | 24GHZ) */ + put32(p, flags); p += 4; - put32(p, 8|4|1); /* filter (NODECRYPT|MULTICAST|PROMISC) */ + put32(p, filter); p += 4; - *p++ = bss != nil ? bss->channel : ctlr->channel; + *p++ = ctlr->channel; p++; /* reserved */ *p++ = 0xff; /* ht single mask */ *p++ = 0xff; /* ht dual mask */ @@ -1260,10 +1344,14 @@ rxon(Ether *edev, Wnode *bss) p += 2; /* reserved */ } cmd(ctlr, 16, c, p - c); - - addnode(ctlr, (ctlr->type != Type4965) ? 15 : 31, edev->bcast); - if(bss != nil) - addnode(ctlr, 0, bss->bssid); + if(ctlr->bcastnodeid == -1){ + ctlr->bcastnodeid = (ctlr->type != Type4965) ? 15 : 31; + addnode(ctlr, ctlr->bcastnodeid, edev->bcast); + } + if(ctlr->bssnodeid == -1 && bss != nil && ctlr->aid != 0){ + ctlr->bssnodeid = 0; + addnode(ctlr, ctlr->bssnodeid, bss->bssid); + } } static struct ratetab { @@ -1271,10 +1359,10 @@ static struct ratetab { uchar plcp; uchar flags; } ratetab[] = { - { 2, 10, 1<<1 }, - { 4, 20, 1<<1 }, - { 11, 55, 1<<1 }, - { 22, 110, 1<<1 }, + { 2, 10, RFlagCCK }, + { 4, 20, RFlagCCK }, + { 11, 55, RFlagCCK }, + { 22, 110, RFlagCCK }, { 12, 0xd, 0 }, { 18, 0xf, 0 }, { 24, 0x5, 0 }, @@ -1286,32 +1374,76 @@ static struct ratetab { { 120, 0x3, 0 } }; +enum { + TFlagNeedProtection = 1<<0, + TFlagNeedRTS = 1<<1, + TFlagNeedCTS = 1<<2, + TFlagNeedACK = 1<<3, + TFlagLinkq = 1<<4, + TFlagImmBa = 1<<6, + TFlagFullTxOp = 1<<7, + TFlagBtDis = 1<<12, + TFlagAutoSeq = 1<<13, + TFlagMoreFrag = 1<<14, + TFlagInsertTs = 1<<16, + TFlagNeedPadding = 1<<20, +}; + static void -transmit(Wifi *wifi, Wnode *, Block *b) +transmit(Wifi *wifi, Wnode *wn, Block *b) { uchar c[Tcmdsize], *p; + Ether *edev; Ctlr *ctlr; + Wifipkt *w; + int flags, nodeid, rate; + + w = (Wifipkt*)b->rp; + edev = wifi->ether; + ctlr = edev->ctlr; + + qlock(ctlr); + if(wn != nil && (wn->aid != ctlr->aid || wn->channel != ctlr->channel)) + rxon(edev, wn); + + rate = 0; + flags = 0; + nodeid = ctlr->bcastnodeid; + if((w->a1[0] & 1) == 0){ + flags |= TFlagNeedACK; + + if(BLEN(b) > 512-4) + flags |= TFlagNeedRTS; - ctlr = wifi->ether->ctlr; + if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){ + nodeid = ctlr->bssnodeid; + rate = 2; /* BUG: hardcode 11Mbit */ + } + + if(flags & (TFlagNeedRTS|TFlagNeedCTS)){ + if(ctlr->type != Type4965){ + flags &= ~(TFlagNeedRTS|TFlagNeedCTS); + flags |= TFlagNeedProtection; + } else + flags |= TFlagFullTxOp; + } + } + qunlock(ctlr); memset(p = c, 0, sizeof(c)); put16(p, BLEN(b)); p += 2; p += 2; /* lnext */ - put32(p, 0); /* flags */ + put32(p, flags); p += 4; put32(p, 0); p += 4; /* scratch */ - /* BUG: hardcode 11Mbit */ - *p++ = ratetab[2].plcp; /* plcp */ - *p++ = ratetab[2].flags | (1<<6); /* rflags */ + *p++ = ratetab[rate].plcp; + *p++ = ratetab[rate].flags | (1<<6); p += 2; /* xflags */ - - /* BUG: we always use broadcast node! */ - *p++ = (ctlr->type != Type4965) ? 15 : 31; - + *p++ = nodeid; *p++ = 0; /* security */ *p++ = 0; /* linkq */ p++; /* reserved */ @@ -1379,11 +1511,7 @@ setoptions(Ether *edev) int i; ctlr = edev->ctlr; - ctlr->channel = 3; for(i = 0; i < edev->nopt; i++){ - if(strncmp(edev->opt[i], "channel=", 8) == 0) - ctlr->channel = atoi(edev->opt[i]+8); - else if(strncmp(edev->opt[i], "essid=", 6) == 0){ snprint(buf, sizeof(buf), "essid %s", edev->opt[i]+6); if(!waserror()){ @@ -1394,9 +1522,78 @@ setoptions(Ether *edev) } } +static void +iwlpromiscuous(void *arg, int on) +{ + Ether *edev; + Ctlr *ctlr; + + edev = arg; + ctlr = edev->ctlr; + qlock(ctlr); + ctlr->prom = on; + if(ctlr->prom) + rxon(edev, nil); + else + rxon(edev, ctlr->wifi->bss); + qunlock(ctlr); +} + +static void +iwlproc(void *arg) +{ + Ether *edev; + Ctlr *ctlr; + Wifi *wifi; + Wnode *bss; + + edev = arg; + ctlr = edev->ctlr; + wifi = ctlr->wifi; + + for(;;){ + /* hop channels for catching beacons */ + setled(ctlr, 2, 5, 5); + while(wifi->bss == nil){ + qlock(ctlr); + if(wifi->bss != nil){ + qunlock(ctlr); + break; + } + ctlr->channel = 1 + ctlr->channel % 11; + ctlr->aid = 0; + rxon(edev, nil); + qunlock(ctlr); + tsleep(&up->sleep, return0, 0, 1000); + } + + /* wait for association */ + setled(ctlr, 2, 10, 10); + while((bss = wifi->bss) != nil){ + if(bss->aid != 0) + break; + tsleep(&up->sleep, return0, 0, 1000); + } + + if(bss == nil) + continue; + + /* wait for disassociation */ + edev->link = 1; + setled(ctlr, 2, 0, 1); + while((bss = wifi->bss) != nil){ + if(bss->aid == 0) + break; + tsleep(&up->sleep, return0, 0, 1000); + } + edev->link = 0; + } +} + static void iwlattach(Ether *edev) { + char name[32]; FWImage *fw; Ctlr *ctlr; char *err; @@ -1528,12 +1725,16 @@ iwlattach(Ether *edev) bootfirmware(ctlr); postboot(ctlr); + ctlr->bcastnodeid = -1; + ctlr->bssnodeid = -1; + ctlr->channel = 1; + ctlr->aid = 0; + setoptions(edev); - rxon(edev, nil); + snprint(name, sizeof(name), "#l%diwl", edev->ctlrno); + kproc(name, iwlproc, edev); - edev->prom = 1; - edev->link = 1; ctlr->attached = 1; } qunlock(ctlr); @@ -1783,7 +1984,7 @@ again: edev->attach = iwlattach; edev->ifstat = iwlifstat; edev->ctl = iwlctl; - edev->promiscuous = nil; + edev->promiscuous = iwlpromiscuous; edev->multicast = nil; edev->mbps = 10; diff --git a/sys/src/9/pc/mkfile b/sys/src/9/pc/mkfile index 6965ffc7c..5b68b85a2 100644 --- a/sys/src/9/pc/mkfile +++ b/sys/src/9/pc/mkfile @@ -121,6 +121,7 @@ trap.$O: /sys/include/tos.h uartaxp.$O: uartaxp.i etherm10g.$O: etherm10g2k.i etherm10g4k.i etheriwl.$O: wifi.h +wifi.$O: wifi.h init.h:D: ../port/initcode.c init9.c $CC ../port/initcode.c diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index 3f5cb8153..04410d615 100644 --- a/sys/src/9/pc/wifi.c +++ b/sys/src/9/pc/wifi.c @@ -93,12 +93,12 @@ drop: } static void -wifitx(Wifi *wifi, Block *b) +wifitx(Wifi *wifi, Wnode *wn, Block *b) { Wifipkt *w; uint seq; - seq = wifi->txseq++; + seq = incref(&wifi->txseq); seq <<= 4; w = (Wifipkt*)b->rp; @@ -107,7 +107,7 @@ wifitx(Wifi *wifi, Block *b) w->seq[0] = seq; w->seq[1] = seq>>8; - (*wifi->transmit)(wifi, wifi->bss, b); + (*wifi->transmit)(wifi, wn, b); } @@ -118,18 +118,29 @@ nodelookup(Wifi *wifi, uchar *bssid, int new) if(memcmp(bssid, wifi->ether->bcast, Eaddrlen) == 0) return nil; + if((wn = wifi->bss) != nil){ + if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){ + wn->lastseen = MACHP(0)->ticks; + return wn; + } + } for(wn = nn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){ + if(wn == wifi->bss) + continue; if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){ wn->lastseen = MACHP(0)->ticks; return wn; } - if(wn != wifi->bss && wn->lastseen < nn->lastseen) + if(wn->lastseen < nn->lastseen) nn = wn; } if(!new) return nil; memmove(nn->bssid, bssid, Eaddrlen); nn->lastseen = MACHP(0)->ticks; + nn->channel = 0; + nn->cap = 0; + nn->aid = 0; return nn; } @@ -156,7 +167,7 @@ sendauth(Wifi *wifi, Wnode *bss) *p++ = 0; /* status */ *p++ = 0; b->wp = p; - wifitx(wifi, b); + wifitx(wifi, bss, b); } static void @@ -190,7 +201,7 @@ sendassoc(Wifi *wifi, Wnode *bss) *p++ = 0x8b; *p++ = 0x96; b->wp = p; - wifitx(wifi, b); + wifitx(wifi, bss, b); } static void @@ -210,13 +221,14 @@ recvassoc(Wifi *wifi, Wnode *wn, uchar *d, int len) wifi->status = Sassoc; break; default: + wn->aid = 0; wifi->status = Sunassoc; return; } } static void -recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len) +recvbeacon(Wifi *, Wnode *wn, uchar *d, int len) { uchar *e, *x; uchar t, m[256/8]; @@ -251,11 +263,6 @@ recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len) if(len != strlen(wn->ssid) || strncmp(wn->ssid, (char*)d, len) != 0){ strncpy(wn->ssid, (char*)d, len); wn->ssid[len] = 0; - if(wifi->bss == nil && strcmp(wifi->essid, wn->ssid) == 0){ - wifi->bss = wn; - wifi->status = Sconn; - sendauth(wifi, wn); - } } break; case 3: /* DSPARAMS */ @@ -289,6 +296,11 @@ wifiproc(void *arg) continue; b->rp += WIFIHDRSIZE; recvbeacon(wifi, wn, b->rp, BLEN(b)); + if(wifi->bss == nil && wifi->essid[0] != 0 && strcmp(wifi->essid, wn->ssid) == 0){ + wifi->bss = wn; + wifi->status = Sconn; + sendauth(wifi, wn); + } continue; } if((wn = nodelookup(wifi, w->a3, 0)) == nil) @@ -306,7 +318,9 @@ wifiproc(void *arg) sendassoc(wifi, wn); break; case 0xc0: /* deauth */ + wn->aid = 0; wifi->status = Sunauth; + sendauth(wifi, wn); break; } } @@ -318,6 +332,7 @@ wifietheroq(Wifi *wifi, Block *b) { Etherpkt e; Wifipkt *w; + Wnode *bss; SNAP *s; if(BLEN(b) < ETHERHDRSIZE){ @@ -332,7 +347,8 @@ wifietheroq(Wifi *wifi, Block *b) w = (Wifipkt*)b->rp; w->fc[0] = 0x08; /* data */ w->fc[1] = 0x01; /* STA->AP */ - memmove(w->a1, wifi->bss ? wifi->bss->bssid : wifi->ether->bcast, Eaddrlen); + bss = wifi->bss; + memmove(w->a1, bss != nil ? bss->bssid : wifi->ether->bcast, Eaddrlen); memmove(w->a2, e.s, Eaddrlen); memmove(w->a3, e.d, Eaddrlen); @@ -344,7 +360,7 @@ wifietheroq(Wifi *wifi, Block *b) s->orgcode[2] = 0; memmove(s->type, e.type, 2); - wifitx(wifi, b); + wifitx(wifi, bss, b); } static void @@ -364,6 +380,7 @@ wifoproc(void *arg) Wifi* wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*)) { + char name[32]; Wifi *wifi; wifi = malloc(sizeof(Wifi)); @@ -372,8 +389,10 @@ wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*)) wifi->transmit = transmit; wifi->status = Snone; - kproc("wifi", wifiproc, wifi); - kproc("wifo", wifoproc, wifi); + snprint(name, sizeof(name), "#l%dwifi", ether->ctlrno); + kproc(name, wifiproc, wifi); + snprint(name, sizeof(name), "#l%dwifo", ether->ctlrno); + kproc(name, wifoproc, wifi); return wifi; } @@ -392,7 +411,6 @@ wifictl(Wifi *wifi, void *buf, long n) cb = parsecmd(buf, n); if(cb->f[0] && strcmp(cb->f[0], "essid") == 0){ if(cb->f[1] == nil){ - /* TODO senddeauth(wifi); */ wifi->essid[0] = 0; wifi->bss = nil; } else { @@ -425,7 +443,8 @@ wifistat(Wifi *wifi, void *buf, long n, ulong off) p = seprint(p, e, "status: %s\n", wifi->status); p = seprint(p, e, "essid: %s\n", wifi->essid); - p = seprint(p, e, "bssid: %E\n", wifi->bss ? wifi->bss->bssid : zeros); + wn = wifi->bss; + p = seprint(p, e, "bssid: %E\n", wn != nil ? wn->bssid : zeros); now = MACHP(0)->ticks; for(wn=wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){ diff --git a/sys/src/9/pc/wifi.h b/sys/src/9/pc/wifi.h index 25a290d6c..1b04933b6 100644 --- a/sys/src/9/pc/wifi.h +++ b/sys/src/9/pc/wifi.h @@ -34,13 +34,13 @@ struct Wifi Queue *iq; char *status; + Ref txseq; void (*transmit)(Wifi*, Wnode*, Block*); - Wnode node[16]; + char essid[32+2]; Wnode *bss; - uint txseq; - char essid[32+2]; + Wnode node[32]; }; Wifi *wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*)); -- cgit v1.2.3 From 8f991a3faaae210d8acfd5e0c56d699643410041 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 11 Feb 2013 00:53:51 +0100 Subject: create /lib/firmware in rootstub --- sys/lib/rootstub | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/lib/rootstub b/sys/lib/rootstub index 0589d98bf..7a11765ed 100755 --- a/sys/lib/rootstub +++ b/sys/lib/rootstub @@ -107,6 +107,7 @@ mkdir -p cron mkdir -p dist/plan9front mkdir -p fd mkdir -p lib/audio +mkdir -p lib/firmware mkdir -p lib/ndb mkdir -p lib/tftpd mkdir -p mail/box -- cgit v1.2.3 From 3376977d06e6dc8132dee443c20be6e045321c2f Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 11 Feb 2013 01:29:10 +0100 Subject: wifi: actually check if management replies are for us --- sys/src/9/pc/wifi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index 04410d615..6212be029 100644 --- a/sys/src/9/pc/wifi.c +++ b/sys/src/9/pc/wifi.c @@ -303,6 +303,8 @@ wifiproc(void *arg) } continue; } + if(memcmp(w->a1, wifi->ether->ea, Eaddrlen)) + continue; if((wn = nodelookup(wifi, w->a3, 0)) == nil) continue; if(wn != wifi->bss) -- cgit v1.2.3 From 6e0835f7d8255c0f9f66ec349871e2c8da6efaf4 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 11 Feb 2013 02:02:44 +0100 Subject: wifi: clear out ssid in node table entry, cleanup --- sys/src/9/pc/wifi.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index 6212be029..66a130246 100644 --- a/sys/src/9/pc/wifi.c +++ b/sys/src/9/pc/wifi.c @@ -124,7 +124,9 @@ nodelookup(Wifi *wifi, uchar *bssid, int new) return wn; } } - for(wn = nn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){ + if((nn = wifi->node) == wn) + nn++; + for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){ if(wn == wifi->bss) continue; if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){ @@ -137,10 +139,12 @@ nodelookup(Wifi *wifi, uchar *bssid, int new) if(!new) return nil; memmove(nn->bssid, bssid, Eaddrlen); - nn->lastseen = MACHP(0)->ticks; - nn->channel = 0; + nn->ssid[0] = 0; + nn->ival = 0; nn->cap = 0; nn->aid = 0; + nn->channel = 0; + nn->lastseen = MACHP(0)->ticks; return nn; } @@ -418,7 +422,7 @@ wifictl(Wifi *wifi, void *buf, long n) } else { strncpy(wifi->essid, cb->f[1], 32); wifi->essid[32] = 0; - for(wn=wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++) + for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++) if(strcmp(wifi->essid, wn->ssid) == 0){ wifi->bss = wn; wifi->status = Sconn; @@ -449,7 +453,7 @@ wifistat(Wifi *wifi, void *buf, long n, ulong off) p = seprint(p, e, "bssid: %E\n", wn != nil ? wn->bssid : zeros); now = MACHP(0)->ticks; - for(wn=wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){ + for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){ if(wn->lastseen == 0) continue; p = seprint(p, e, "node: %E %.4x %d %ld %d %s\n", -- cgit v1.2.3 From 1f6a402c46d5f95c656b14e4fa9a5de933576f01 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 11 Feb 2013 02:10:36 +0100 Subject: wifi: reset status when clearing essid --- sys/src/9/pc/wifi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index 66a130246..cc880ac49 100644 --- a/sys/src/9/pc/wifi.c +++ b/sys/src/9/pc/wifi.c @@ -419,6 +419,7 @@ wifictl(Wifi *wifi, void *buf, long n) if(cb->f[1] == nil){ wifi->essid[0] = 0; wifi->bss = nil; + wifi->status = Snone; } else { strncpy(wifi->essid, cb->f[1], 32); wifi->essid[32] = 0; -- cgit v1.2.3 From 8d271549cdc06d7c1cbc8496261be118e90f5e24 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 11 Feb 2013 16:02:16 +0100 Subject: wifi: filter SNAP ethernet orgcode only --- sys/src/9/pc/wifi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index cc880ac49..0aef25d68 100644 --- a/sys/src/9/pc/wifi.c +++ b/sys/src/9/pc/wifi.c @@ -63,9 +63,13 @@ wifiiq(Wifi *wifi, Block *b) default: goto drop; } - if(BLEN(b) < SNAPHDRSIZE || b->rp[0] != 0xAA || b->rp[1] != 0xAA || b->rp[2] != 0x03) + if(BLEN(b) < SNAPHDRSIZE) break; memmove(&s, b->rp, SNAPHDRSIZE); + if(s.dsap != 0xAA || s.ssap != 0xAA || s.control != 3) + break; + if(s.orgcode[0] != 0 || s.orgcode[1] != 0 || s.orgcode[2] != 0) + break; b->rp += SNAPHDRSIZE-ETHERHDRSIZE; e = (Etherpkt*)b->rp; switch(w.fc[1] & 0x03){ -- cgit v1.2.3 From 78fc90ec86481dac7d9528a446fa4624631e5a26 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Tue, 12 Feb 2013 14:28:22 +0100 Subject: etheriwl: support for WiFi Link 4965 --- sys/src/9/pc/etheriwl.c | 160 ++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 86 deletions(-) diff --git a/sys/src/9/pc/etheriwl.c b/sys/src/9/pc/etheriwl.c index 9fff050bc..9e2b68860 100644 --- a/sys/src/9/pc/etheriwl.c +++ b/sys/src/9/pc/etheriwl.c @@ -19,7 +19,6 @@ #include "wifi.h" enum { - Ntxlog = 8, Ntx = 1<nic+((r)/4))) @@ -754,7 +728,7 @@ Tooshort: return "bad firmware signature"; p += 4; strncpy(i->descr, (char*)p, 64); - i->descr[sizeof(i->descr)-1] = 0; + i->descr[64] = 0; p += 64; i->rev = get32(p); p += 4; i->build = get32(p); p += 4; @@ -776,7 +750,7 @@ Tooshort: default:s = &dummy; } p += 2; - if(get16(p) != alt) + if(get16(p) != 0 && get16(p) != alt) s = &dummy; p += 2; s->size = get32(p); p += 4; @@ -942,6 +916,7 @@ bootfirmware(Ctlr *ctlr) return err; if((err = loadfirmware1(ctlr, 0x00800000, fw->main.data.data, fw->main.data.size)) != nil) return err; + csr32w(ctlr, Reset, 0); goto bootmain; } @@ -966,6 +941,12 @@ bootfirmware(Ctlr *ctlr) prphwrite(ctlr, BsmDramTextAddr, PCIWADDR(p) >> 4); prphwrite(ctlr, BsmDramTextSize, fw->init.text.size); + nicunlock(ctlr); + if((err = niclock(ctlr)) != nil){ + free(dma); + return err; + } + p = fw->boot.text.data; n = fw->boot.text.size/4; for(i=0; isched.base = prphread(ctlr, SchedSramAddr); - for(i=0; i < ctxlen/4; i++) - memwrite(ctlr, ctlr->sched.base + ctxoff + i*4, 0); + for(i=0; i < ctxlen; i += 4) + memwrite(ctlr, ctlr->sched.base + ctxoff + i, 0); prphwrite(ctlr, dramaddr, PCIWADDR(ctlr->sched.s)>>10); @@ -1185,7 +1166,7 @@ postboot(Ctlr *ctlr) prphwrite(ctlr, SchedQChainSel5000, 0xfffef); prphwrite(ctlr, SchedAggrSel5000, 0); - for(q=0; qtx); q++){ + for(q=0; q<20; q++){ prphwrite(ctlr, SchedQueueRdptr5000 + q*4, 0); csr32w(ctlr, HbusTargWptr, q << 8); @@ -1217,25 +1198,26 @@ postboot(Ctlr *ctlr) /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */ for(q=0; q<7; q++){ - static uchar qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 }; - if(ctlr->type != Type4965) + if(ctlr->type != Type4965){ + static uchar qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 }; prphwrite(ctlr, SchedQueueStatus5000 + q*4, 0x00ff0018 | qid2fifo[q]); - else - prphwrite(ctlr, SchedQueueStatus4965 + q*4, 0x0007fc01 | qid2fifo[q]); + } else { + static uchar qid2fifo[] = { 3, 2, 1, 0, 4, 5, 6 }; + prphwrite(ctlr, SchedQueueStatus4965 + q*4, 0x0007fc01 | qid2fifo[q]<<1); + } } nicunlock(ctlr); - if(ctlr->type != Type5150){ - memset(c, 0, sizeof(c)); - c[0] = 15; /* code */ - c[1] = 0; /* grup */ - c[2] = 1; /* ngroup */ - c[3] = 1; /* isvalid */ - put16(c+4, ctlr->eeprom.crystal); - cmd(ctlr, 176, c, 8); - } - if(ctlr->type != Type4965){ + if(ctlr->type != Type5150){ + memset(c, 0, sizeof(c)); + c[0] = 15; /* code */ + c[1] = 0; /* grup */ + c[2] = 1; /* ngroup */ + c[3] = 1; /* isvalid */ + put16(c+4, ctlr->eeprom.crystal); + cmd(ctlr, 176, c, 8); + } put32(c, ctlr->rfcfg.txantmask & 7); cmd(ctlr, 152, c, 4); } @@ -1266,15 +1248,15 @@ addnode(Ctlr *ctlr, uchar id, uchar *addr) p += 8; /* tcs */ p += 8; /* rxmic */ p += 8; /* txmic */ - p += 4; /* htflags */ - p += 4; /* mask */ - p += 2; /* disable tid */ - p += 2; /* reserved */ - p++; /* add ba tid */ - p++; /* del ba tid */ - p += 2; /* add ba ssn */ - p += 4; /* reserved */ } + p += 4; /* htflags */ + p += 4; /* mask */ + p += 2; /* disable tid */ + p += 2; /* reserved */ + p++; /* add ba tid */ + p++; /* del ba tid */ + p += 2; /* add ba ssn */ + p += 4; /* reserved */ cmd(ctlr, 24, c, p - c); } @@ -1344,6 +1326,7 @@ rxon(Ether *edev, Wnode *bss) p += 2; /* reserved */ } cmd(ctlr, 16, c, p - c); + if(ctlr->bcastnodeid == -1){ ctlr->bcastnodeid = (ctlr->type != Type4965) ? 15 : 31; addnode(ctlr, ctlr->bcastnodeid, edev->bcast); @@ -1617,10 +1600,10 @@ iwlattach(Ether *edev) ctlr->wifi = wifiattach(edev, transmit); if(ctlr->fw == nil){ - fw = readfirmware(ctlrtype[ctlr->type].fwname); + fw = readfirmware(fwname[ctlr->type]); print("#l%d: firmware: %s, rev %ux, build %ud, size %ux+%ux+%ux+%ux+%ux\n", edev->ctlrno, - ctlrtype[ctlr->type].fwname, + fwname[ctlr->type], fw->rev, fw->build, fw->main.text.size, fw->main.data.size, fw->init.text.size, fw->init.data.size, @@ -1699,18 +1682,20 @@ iwlattach(Ether *edev) if((err = niclock(ctlr)) != nil) error(err); - prphwrite(ctlr, SchedTxFact5000, 0); + if(ctlr->type != Type4965) + prphwrite(ctlr, SchedTxFact5000, 0); + else + prphwrite(ctlr, SchedTxFact4965, 0); csr32w(ctlr, FhKwAddr, PCIWADDR(ctlr->kwpage) >> 4); - for(q=0; qtx); q++) - if(q < 15 || ctlr->type != Type4965) - csr32w(ctlr, FhCbbcQueue + q*4, PCIWADDR(ctlr->tx[q].d) >> 8); + for(q = (ctlr->type != Type4965) ? 19 : 15; q >= 0; q--) + csr32w(ctlr, FhCbbcQueue + q*4, PCIWADDR(ctlr->tx[q].d) >> 8); + nicunlock(ctlr); - for(i=0; i<8; i++) - if(i < 7 || ctlr->type != Type4965) - csr32w(ctlr, FhTxConfig + i*32, FhTxConfigDmaEna | FhTxConfigDmaCreditEna); + for(i = (ctlr->type != Type4965) ? 7 : 6; i >= 0; i--) + csr32w(ctlr, FhTxConfig + i*32, FhTxConfigDmaEna | FhTxConfigDmaCreditEna); csr32w(ctlr, UcodeGp1Clr, UcodeGp1RfKill); csr32w(ctlr, UcodeGp1Clr, UcodeGp1CmdBlocked); @@ -1820,9 +1805,10 @@ receive(Ctlr *ctlr) case 192: /* rx phy */ break; case 195: /* rx done */ - if(d + 60 > b->lim) + if(d + 2 > b->lim) break; - d += 60; + d += d[1]; + d += 56; case 193: /* mpdu rx done */ if(d + 4 > b->lim) break; @@ -1906,6 +1892,8 @@ iwlpci(void) switch(pdev->did){ default: continue; + case 0x4229: /* WiFi Link 4965 */ + case 0x4230: /* WiFi Link 4965 */ case 0x4236: /* WiFi Link 5300 AGN */ case 0x4237: /* Wifi Link 5100 AGN */ break; @@ -1940,7 +1928,7 @@ iwlpci(void) ctlr->pdev = pdev; ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0xF; - if(ctlrtype[ctlr->type].fwname == nil){ + if(fwname[ctlr->type] == nil){ print("iwl: unsupported controller type %d\n", ctlr->type); vunmap(mem, pdev->mem[0].size); free(ctlr); -- cgit v1.2.3 From 194094683a641d99335aa941188a7698ff3dd550 Mon Sep 17 00:00:00 2001 From: stanley lieber Date: Tue, 12 Feb 2013 16:43:02 -0600 Subject: fortunes: Monument To Steve Jobs Goes Up In St. Petersburg --- lib/rsc | 2 ++ lib/troll | 3 +++ sys/games/lib/fortunes | 12 ++++++++++++ 3 files changed, 17 insertions(+) diff --git a/lib/rsc b/lib/rsc index d2f94a019..23816c6e8 100644 --- a/lib/rsc +++ b/lib/rsc @@ -71,3 +71,5 @@ Ouch Please don't. Test? sure +NOT LGTM sorry +i lost the ability to use rio a few years ago when they moved wireless configuration into the gnome window manager, making it impossible to have rio and a network connection at the same time. diff --git a/lib/troll b/lib/troll index 144068a4e..bd8b0839d 100644 --- a/lib/troll +++ b/lib/troll @@ -114,3 +114,6 @@ did anyone at iwp9 give an update about osprey? anyone ask when it'll be availab just run linux -- aiju I'm fairly new to plan9, and am having trouble ssh'ing to my mac. Subject: [golang-dev] not reading code +Is Trolling Ever Okay? +I've downloaded the nix bits from http://code.google.com/p/nix-os/ and compiled it under 9vx on OSX, but I'm having some trouble getting the resultant kernel to boot. +Subject: [nix] servers down diff --git a/sys/games/lib/fortunes b/sys/games/lib/fortunes index 674707e9f..9bdc0ad1f 100644 --- a/sys/games/lib/fortunes +++ b/sys/games/lib/fortunes @@ -4799,3 +4799,15 @@ I don't want Javascript promises --- you can reply above this line --- MIT OpenCourseware >> Electrical Engineering and Computer Science >> Introduction to Electrical Engineering and Computer Science I >> Python Tutorial (#plan9) semka → May be I should ask at #cat-v :) +Monument To Steve Jobs Goes Up In St. Petersburg +But without moving the directory specifics out of user space code like it was V7 and earlier, it would have been hard to create something as clean as VFS. +(#cat-v) aiju → what's weird is that uriel loved gay colours +rcirc on GNU Emacs 24.2.1 +Decade Old KDE Bug Fixed +Fix the value of TWO +Fedora 18 Installer: Counterintuitive and Confusing? +when all you understand is trivial bullshit, trivial bullshit is what's important +hjfs: ending +If it’s done right this is not wrong. -- 20h +Just today I found out that the Chrome JS editor can ‘hot-swap’ your code. +A programming language, even with its libraries, is not enough, nor is it always the right place to solve all the problems of the network. -- cgit v1.2.3 From 0243f52bae9eba9d80510916573764c859616ef6 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Wed, 13 Feb 2013 08:23:54 +0100 Subject: etheriwl: dont let transmit change back receiver settings when in promisc mode, cleanup --- sys/src/9/pc/etheriwl.c | 41 ++++++++++++++++++++--------------------- sys/src/9/pc/wifi.c | 6 +++--- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/sys/src/9/pc/etheriwl.c b/sys/src/9/pc/etheriwl.c index 9e2b68860..94e5f3229 100644 --- a/sys/src/9/pc/etheriwl.c +++ b/sys/src/9/pc/etheriwl.c @@ -327,6 +327,7 @@ struct Ctlr { int bssnodeid; /* current receiver settings */ + uchar bssid[Eaddrlen]; int channel; int prom; int aid; @@ -1264,43 +1265,39 @@ void rxon(Ether *edev, Wnode *bss) { uchar c[Tcmdsize], *p; - Ctlr *ctlr; - uchar *bssid; int filter, flags; + Ctlr *ctlr; ctlr = edev->ctlr; - bssid = edev->bcast; filter = FilterMulticast | FilterBeacon; - if(ctlr->prom) + if(ctlr->prom){ filter |= FilterPromisc; + bss = nil; + } if(bss != nil){ ctlr->channel = bss->channel; - if(bss->aid != 0){ - bssid = bss->bssid; + memmove(ctlr->bssid, bss->bssid, Eaddrlen); + ctlr->aid = bss->aid; + if(ctlr->aid != 0){ filter |= FilterBSS; filter &= ~FilterBeacon; - ctlr->aid = bss->aid; - ctlr->bssnodeid = -1; - } else { - filter &= ~FilterBSS; - filter |= FilterBeacon; - ctlr->aid = 0; - + } else ctlr->bcastnodeid = -1; - } } else { + memmove(ctlr->bssid, edev->bcast, Eaddrlen); + ctlr->aid = 0; ctlr->bcastnodeid = -1; ctlr->bssnodeid = -1; } flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto; if(0) print("rxon: bssid %E, aid %x, channel %d, filter %x, flags %x\n", - bssid, ctlr->aid, ctlr->channel, filter, flags); + ctlr->bssid, ctlr->aid, ctlr->channel, filter, flags); memset(p = c, 0, sizeof(c)); memmove(p, edev->ea, 6); p += 8; /* myaddr */ - memmove(p, bssid, 6); p += 8; /* bssid */ + memmove(p, ctlr->bssid, 6); p += 8; /* bssid */ memmove(p, edev->ea, 6); p += 8; /* wlap */ *p++ = 3; /* mode (STA) */ *p++ = 0; /* air (?) */ @@ -1335,6 +1332,7 @@ rxon(Ether *edev, Wnode *bss) ctlr->bssnodeid = 0; addnode(ctlr, ctlr->bssnodeid, bss->bssid); } + flushcmd(ctlr); } static struct ratetab { @@ -1386,7 +1384,11 @@ transmit(Wifi *wifi, Wnode *wn, Block *b) ctlr = edev->ctlr; qlock(ctlr); - if(wn != nil && (wn->aid != ctlr->aid || wn->channel != ctlr->channel)) + + if(ctlr->prom == 0) + if(wn->aid != ctlr->aid + || wn->channel != ctlr->channel + || memcmp(wn->bssid, ctlr->bssid, Eaddrlen) != 0) rxon(edev, wn); rate = 0; @@ -1515,10 +1517,7 @@ iwlpromiscuous(void *arg, int on) ctlr = edev->ctlr; qlock(ctlr); ctlr->prom = on; - if(ctlr->prom) - rxon(edev, nil); - else - rxon(edev, ctlr->wifi->bss); + rxon(edev, ctlr->wifi->bss); qunlock(ctlr); } diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index 0aef25d68..e03d6a368 100644 --- a/sys/src/9/pc/wifi.c +++ b/sys/src/9/pc/wifi.c @@ -345,7 +345,8 @@ wifietheroq(Wifi *wifi, Block *b) Wnode *bss; SNAP *s; - if(BLEN(b) < ETHERHDRSIZE){ + bss = wifi->bss; + if(bss == nil || BLEN(b) < ETHERHDRSIZE){ freeb(b); return; } @@ -357,8 +358,7 @@ wifietheroq(Wifi *wifi, Block *b) w = (Wifipkt*)b->rp; w->fc[0] = 0x08; /* data */ w->fc[1] = 0x01; /* STA->AP */ - bss = wifi->bss; - memmove(w->a1, bss != nil ? bss->bssid : wifi->ether->bcast, Eaddrlen); + memmove(w->a1, bss->bssid, Eaddrlen); memmove(w->a2, e.s, Eaddrlen); memmove(w->a3, e.d, Eaddrlen); -- cgit v1.2.3 From af3dad549023fe8417c27a053812b103fd7b66ae Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Wed, 13 Feb 2013 10:03:53 +0100 Subject: nusb/disk: allow 12 and 16 byte raw scsi commands (from erik quanstro) --- sys/src/cmd/nusb/disk/disk.c | 2 +- sys/src/cmd/nusb/disk/ums.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/src/cmd/nusb/disk/disk.c b/sys/src/cmd/nusb/disk/disk.c index 60052922b..0bffaa0ba 100644 --- a/sys/src/cmd/nusb/disk/disk.c +++ b/sys/src/cmd/nusb/disk/disk.c @@ -812,7 +812,7 @@ dwrite(Req *req) } switch(lun->phase){ case Pcmd: - if(count != 6 && count != 10){ + if(count != 6 && count != 10 && count != 12 && count != 16){ respond(req, "bad command length"); break; } diff --git a/sys/src/cmd/nusb/disk/ums.h b/sys/src/cmd/nusb/disk/ums.h index 27572a1c9..f8dbfa4fc 100644 --- a/sys/src/cmd/nusb/disk/ums.h +++ b/sys/src/cmd/nusb/disk/ums.h @@ -79,7 +79,7 @@ struct Umsc /* partitions */ Part part[Maxparts]; - uchar rawcmd[10]; + uchar rawcmd[16]; uchar phase; char *inq; Ums *ums; -- cgit v1.2.3 From 42fc57d54371d12c49847d39dc4a24d5b6ffdb5b Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Wed, 13 Feb 2013 10:57:47 +0100 Subject: plan9.ini(8): document iwl options --- sys/man/8/plan9.ini | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini index a4d7326a2..3a563e5fa 100644 --- a/sys/man/8/plan9.ini +++ b/sys/man/8/plan9.ini @@ -381,6 +381,29 @@ programming interface. Currently the only tested cards are those based on the Intersil Prism 2.5 chipset. . +.TP +.B iwl +Intel Wireless WiFi Link mini PCI-Express adapters require +firmware from +.B http://firmware.openbsd.org/firmware/ +to be present on attach in +.B /lib/firmware +or +.B /boot. +To select the access point, the +.B essid= +parameter can be specified at boot or set during runtime +like: +.EX + echo essid left-armpit >/net/ether1/clone +.EE +Scan results appear in the +.B ifstats +file and can be read out like: +.EX + cat /net/ether1/ifstats +.EE +Ad-hoc mode or encryption is currently not supported. .SS DISKS, TAPES (S)ATA controllers are autodetected. .SS \fL*nodma=\fP -- cgit v1.2.3 From 3c3808b28077672fe3568943a0a633465e50608c Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Wed, 13 Feb 2013 11:03:19 +0100 Subject: plan9.ini(8): make more clear what firmware file to get for iwl --- sys/man/8/plan9.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini index 3a563e5fa..941f03867 100644 --- a/sys/man/8/plan9.ini +++ b/sys/man/8/plan9.ini @@ -385,7 +385,7 @@ Intersil Prism 2.5 chipset. .B iwl Intel Wireless WiFi Link mini PCI-Express adapters require firmware from -.B http://firmware.openbsd.org/firmware/ +.B http://firmware.openbsd.org/firmware/iwn-firmware*.tgz to be present on attach in .B /lib/firmware or -- cgit v1.2.3 From e7127522296d64f9ef908ab53f1df86e2e0ba632 Mon Sep 17 00:00:00 2001 From: ftrvxmtrx Date: Thu, 14 Feb 2013 01:04:45 +0100 Subject: pci: add intel qm67 pch --- sys/src/9/pc/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/src/9/pc/pci.c b/sys/src/9/pc/pci.c index 0391ca700..cb37c88e7 100644 --- a/sys/src/9/pc/pci.c +++ b/sys/src/9/pc/pci.c @@ -681,6 +681,7 @@ static Bridge southbridges[] = { { 0x8086, 0x3b06, pIIxget, pIIxset }, /* Intel 82801? ibex peak */ { 0x8086, 0x3b14, pIIxget, pIIxset }, /* Intel 82801? 3420 */ { 0x8086, 0x1c49, pIIxget, pIIxset }, /* Intel 82hm65 cougar point pch */ + { 0x8086, 0x1c4f, pIIxget, pIIxset }, /* Intel 82qm67 cougar point pch */ { 0x8086, 0x1c52, pIIxget, pIIxset }, /* Intel 82q65 cougar point pch */ { 0x8086, 0x1c54, pIIxget, pIIxset }, /* Intel 82q67 cougar point pch */ { 0x1106, 0x0586, viaget, viaset }, /* Viatech 82C586 */ -- cgit v1.2.3