diff options
| author | ppatience0 <ppatience0@gmail.com> | 2013-02-13 07:37:26 -0500 |
|---|---|---|
| committer | ppatience0 <ppatience0@gmail.com> | 2013-02-13 07:37:26 -0500 |
| commit | 6d7bb96b22c8d16a86e8dccb52961abc7d094300 (patch) | |
| tree | e647f57ed838c461fd8338d015f76ac8aae0d909 | |
| parent | 0734a0b8367b29898ca2a8bf0bfd155450d9e5f6 (diff) | |
| parent | e7127522296d64f9ef908ab53f1df86e2e0ba632 (diff) | |
| download | plan9front-6d7bb96b22c8d16a86e8dccb52961abc7d094300.tar.xz | |
merge
| -rw-r--r-- | lib/rsc | 2 | ||||
| -rw-r--r-- | lib/troll | 3 | ||||
| -rw-r--r-- | sys/games/lib/fortunes | 12 | ||||
| -rw-r--r-- | sys/include/mp.h | 2 | ||||
| -rwxr-xr-x | sys/lib/rootstub | 1 | ||||
| -rw-r--r-- | sys/man/8/plan9.ini | 23 | ||||
| -rw-r--r-- | sys/src/9/pc/etheriwl.c | 432 | ||||
| -rw-r--r-- | sys/src/9/pc/mkfile | 1 | ||||
| -rw-r--r-- | sys/src/9/pc/pci.c | 1 | ||||
| -rw-r--r-- | sys/src/9/pc/wifi.c | 76 | ||||
| -rw-r--r-- | sys/src/9/pc/wifi.h | 6 | ||||
| -rw-r--r-- | sys/src/cmd/nusb/disk/disk.c | 2 | ||||
| -rw-r--r-- | sys/src/cmd/nusb/disk/ums.h | 2 |
13 files changed, 412 insertions, 151 deletions
@@ -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. @@ -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. 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*); 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 diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini index a4d7326a2..941f03867 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/iwn-firmware*.tgz +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 diff --git a/sys/src/9/pc/etheriwl.c b/sys/src/9/pc/etheriwl.c index 19fd2db70..94e5f3229 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<<Ntxlog, Nrxlog = 8, @@ -197,16 +196,18 @@ enum { enum { SchedBase = 0xa02c00, SchedSramAddr = SchedBase, - SchedDramAddr5000 = SchedBase+0x008, + SchedDramAddr4965 = SchedBase+0x010, - SchedTxFact5000 = SchedBase+0x010, SchedTxFact4965 = SchedBase+0x01c, SchedQueueRdptr4965 = SchedBase+0x064, // +q*4 - SchedQueueRdptr5000 = SchedBase+0x068, // +q*4 SchedQChainSel4965 = SchedBase+0x0d0, SchedIntrMask4965 = SchedBase+0x0e4, - SchedQChainSel5000 = SchedBase+0x0e8, SchedQueueStatus4965 = SchedBase+0x104, // +q*4 + + SchedDramAddr5000 = SchedBase+0x008, + SchedTxFact5000 = SchedBase+0x010, + SchedQueueRdptr5000 = SchedBase+0x068, // +q*4 + SchedQChainSel5000 = SchedBase+0x0e8, SchedIntrMask5000 = SchedBase+0x108, SchedQueueStatus5000 = SchedBase+0x10c, // +q*4 SchedAggrSel5000 = SchedBase+0x248, @@ -215,11 +216,31 @@ enum { enum { SchedCtxOff4965 = 0x380, SchedCtxLen4965 = 416, - SchedTransTblOff4965 = 0x500, SchedCtxOff5000 = 0x600, SchedCtxLen5000 = 512, - 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; @@ -231,8 +252,6 @@ typedef struct RXQ RXQ; typedef struct Ctlr Ctlr; -typedef struct Ctlrtype Ctlrtype; - struct FWSect { uchar *data; @@ -303,7 +322,15 @@ struct Ctlr { u32int *nic; uchar *kwpage; + /* assigned node ids in hardware node table or -1 if unassigned */ + int bcastnodeid; + int bssnodeid; + + /* current receiver settings */ + uchar bssid[Eaddrlen]; int channel; + int prom; + int aid; RXQ rx; TXQ tx[20]; @@ -349,39 +376,16 @@ enum { Type6005 = 11, }; -struct Ctlrtype -{ - char *fwname; -}; - -static Ctlrtype ctlrtype[16] = { - [Type4965] { - .fwname = "iwn-4965", - }, - [Type5300] { - .fwname = "iwn-5000", - }, - [Type5350] { - .fwname = "iwn-5000", - }, - [Type5150] { - .fwname = "iwn-5150", - }, - [Type5100] { - .fwname = "iwn-5000", - }, - [Type1000] { - .fwname = "iwn-1000", - }, - [Type6000] { - .fwname = "iwn-6000", - }, - [Type6050] { - .fwname = "iwn-6050", - }, - [Type6005] { - .fwname = "iwn-6005", - }, +static char *fwname[16] = { + [Type4965] "iwn-4965", + [Type5300] "iwn-5000", + [Type5350] "iwn-5000", + [Type5150] "iwn-5150", + [Type5100] "iwn-5000", + [Type1000] "iwn-1000", + [Type6000] "iwn-6000", + [Type6050] "iwn-6050", + [Type6005] "iwn-6005", }; #define csr32r(c, r) (*((c)->nic+((r)/4))) @@ -725,7 +729,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; @@ -747,7 +751,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; @@ -913,6 +917,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; } @@ -937,6 +942,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; i<n; i++, p += 4) @@ -990,7 +1001,6 @@ bootfirmware(Ctlr *ctlr) nicunlock(ctlr); bootmain: - csr32w(ctlr, Reset, 0); if(irqwait(ctlr, Ierr|Ialive, 5000) != Ialive){ free(dma); return "main firmware boot failed"; @@ -1019,12 +1029,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 +1076,43 @@ 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 +flushcmd(Ctlr *ctlr) +{ + flushq(ctlr, 4); +} + static void cmd(Ctlr *ctlr, uint code, uchar *data, int size) { qcmd(ctlr, 4, code, data, size, nil); } + static void setled(Ctlr *ctlr, int which, int on, int off) { @@ -1099,9 +1139,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); @@ -1118,8 +1155,8 @@ postboot(Ctlr *ctlr) } ctlr->sched.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); @@ -1130,7 +1167,7 @@ postboot(Ctlr *ctlr) prphwrite(ctlr, SchedQChainSel5000, 0xfffef); prphwrite(ctlr, SchedAggrSel5000, 0); - for(q=0; q<nelem(ctlr->tx); q++){ + for(q=0; q<20; q++){ prphwrite(ctlr, SchedQueueRdptr5000 + q*4, 0); csr32w(ctlr, HbusTargWptr, q << 8); @@ -1162,25 +1199,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); } @@ -1211,15 +1249,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); } @@ -1227,13 +1265,39 @@ void rxon(Ether *edev, Wnode *bss) { uchar c[Tcmdsize], *p; + int filter, flags; Ctlr *ctlr; ctlr = edev->ctlr; + filter = FilterMulticast | FilterBeacon; + if(ctlr->prom){ + filter |= FilterPromisc; + bss = nil; + } + if(bss != nil){ + ctlr->channel = bss->channel; + memmove(ctlr->bssid, bss->bssid, Eaddrlen); + ctlr->aid = bss->aid; + if(ctlr->aid != 0){ + filter |= FilterBSS; + filter &= ~FilterBeacon; + ctlr->bssnodeid = -1; + } 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", + ctlr->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, ctlr->bssid, 6); p += 8; /* bssid */ memmove(p, edev->ea, 6); p += 8; /* wlap */ *p++ = 3; /* mode (STA) */ *p++ = 0; /* air (?) */ @@ -1242,14 +1306,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 */ @@ -1261,9 +1324,15 @@ rxon(Ether *edev, Wnode *bss) } 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); + } + flushcmd(ctlr); } static struct ratetab { @@ -1271,10 +1340,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 +1355,80 @@ 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); - ctlr = wifi->ether->ctlr; + 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; + flags = 0; + nodeid = ctlr->bcastnodeid; + if((w->a1[0] & 1) == 0){ + flags |= TFlagNeedACK; + + if(BLEN(b) > 512-4) + flags |= TFlagNeedRTS; + + 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 +1496,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()){ @@ -1395,8 +1508,74 @@ setoptions(Ether *edev) } static void +iwlpromiscuous(void *arg, int on) +{ + Ether *edev; + Ctlr *ctlr; + + edev = arg; + ctlr = edev->ctlr; + qlock(ctlr); + ctlr->prom = on; + 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; @@ -1420,10 +1599,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, @@ -1502,18 +1681,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; q<nelem(ctlr->tx); 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); @@ -1528,12 +1709,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); @@ -1619,9 +1804,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; @@ -1705,6 +1891,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; @@ -1739,7 +1927,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); @@ -1783,7 +1971,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/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 */ diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index 3f5cb8153..e03d6a368 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){ @@ -93,12 +97,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 +111,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,17 +122,32 @@ nodelookup(Wifi *wifi, uchar *bssid, int new) if(memcmp(bssid, wifi->ether->bcast, Eaddrlen) == 0) return nil; - for(wn = nn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){ + if((wn = wifi->bss) != nil){ + if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){ + wn->lastseen = MACHP(0)->ticks; + return 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){ 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->ssid[0] = 0; + nn->ival = 0; + nn->cap = 0; + nn->aid = 0; + nn->channel = 0; nn->lastseen = MACHP(0)->ticks; return nn; } @@ -156,7 +175,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 +209,7 @@ sendassoc(Wifi *wifi, Wnode *bss) *p++ = 0x8b; *p++ = 0x96; b->wp = p; - wifitx(wifi, b); + wifitx(wifi, bss, b); } static void @@ -210,13 +229,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 +271,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,8 +304,15 @@ 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(memcmp(w->a1, wifi->ether->ea, Eaddrlen)) + continue; if((wn = nodelookup(wifi, w->a3, 0)) == nil) continue; if(wn != wifi->bss) @@ -306,7 +328,9 @@ wifiproc(void *arg) sendassoc(wifi, wn); break; case 0xc0: /* deauth */ + wn->aid = 0; wifi->status = Sunauth; + sendauth(wifi, wn); break; } } @@ -318,9 +342,11 @@ wifietheroq(Wifi *wifi, Block *b) { Etherpkt e; Wifipkt *w; + Wnode *bss; SNAP *s; - if(BLEN(b) < ETHERHDRSIZE){ + bss = wifi->bss; + if(bss == nil || BLEN(b) < ETHERHDRSIZE){ freeb(b); return; } @@ -332,7 +358,7 @@ 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); + memmove(w->a1, bss->bssid, Eaddrlen); memmove(w->a2, e.s, Eaddrlen); memmove(w->a3, e.d, Eaddrlen); @@ -344,7 +370,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 +390,7 @@ wifoproc(void *arg) Wifi* wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*)) { + char name[32]; Wifi *wifi; wifi = malloc(sizeof(Wifi)); @@ -372,8 +399,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,13 +421,13 @@ 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; + wifi->status = Snone; } 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; @@ -425,10 +454,11 @@ 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++){ + 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", 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*)); 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; |
