ref: a14eb5ac1a8cac780246536b6c398b6d8c0cc1b2
parent: 512973f9c43f1fbd690583e6a5e0e39efe82a04a
parent: 0ebaa881d3ac3f1516ede3c93358287420c2dfb8
author: ppatience0 <ppatience0@gmail.com>
date: Wed Feb 13 02:37:26 EST 2013
merge
--- a/lib/rsc
+++ b/lib/rsc
@@ -71,3 +71,5 @@
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.
--- a/lib/troll
+++ b/lib/troll
@@ -114,3 +114,6 @@
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
--- a/sys/games/lib/fortunes
+++ b/sys/games/lib/fortunes
@@ -4799,3 +4799,15 @@
--- 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.
--- a/sys/include/mp.h
+++ b/sys/include/mp.h
@@ -45,7 +45,7 @@
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*);
--- a/sys/lib/rootstub
+++ b/sys/lib/rootstub
@@ -107,6 +107,7 @@
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
--- a/sys/man/8/plan9.ini
+++ b/sys/man/8/plan9.ini
@@ -381,6 +381,29 @@
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
--- 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 {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,13 +216,33 @@
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;
typedef struct FWImage FWImage;
typedef struct FWSect FWSect;
@@ -231,8 +252,6 @@
typedef struct Ctlr Ctlr;
-typedef struct Ctlrtype Ctlrtype;
-
struct FWSect
{uchar *data;
@@ -303,7 +322,15 @@
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,41 +376,18 @@
Type6005 = 11,
};
-struct Ctlrtype
-{- char *fwname;
+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",
};
-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",
- },
-};
-
#define csr32r(c, r) (*((c)->nic+((r)/4)))
#define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
@@ -725,7 +729,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
/* 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
{ 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;
- ctlr = wifi->ether->ctlr;
+ w = (Wifipkt*)b->rp;
+ edev = wifi->ether;
+ ctlr = edev->ctlr;
+ qlock(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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
edev->attach = iwlattach;
edev->ifstat = iwlifstat;
edev->ctl = iwlctl;
- edev->promiscuous = nil;
+ edev->promiscuous = iwlpromiscuous;
edev->multicast = nil;
edev->mbps = 10;
--- a/sys/src/9/pc/mkfile
+++ b/sys/src/9/pc/mkfile
@@ -121,6 +121,7 @@
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
--- a/sys/src/9/pc/pci.c
+++ b/sys/src/9/pc/pci.c
@@ -681,6 +681,7 @@
{ 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 */--- a/sys/src/9/pc/wifi.c
+++ b/sys/src/9/pc/wifi.c
@@ -63,9 +63,13 @@
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 @@
}
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 @@
w->seq[0] = seq;
w->seq[1] = seq>>8;
- (*wifi->transmit)(wifi, wifi->bss, b);
+ (*wifi->transmit)(wifi, wn, b);
}
@@ -118,17 +122,32 @@
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(wn != wifi->bss && wn->lastseen < nn->lastseen)
+ }
+ 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->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 @@
*p++ = 0; /* status */
*p++ = 0;
b->wp = p;
- wifitx(wifi, b);
+ wifitx(wifi, bss, b);
}
static void
@@ -190,7 +209,7 @@
*p++ = 0x8b;
*p++ = 0x96;
b->wp = p;
- wifitx(wifi, b);
+ wifitx(wifi, bss, b);
}
static void
@@ -210,6 +229,7 @@
wifi->status = Sassoc;
break;
default:
+ wn->aid = 0;
wifi->status = Sunassoc;
return;
}
@@ -216,7 +236,7 @@
}
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 @@
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 @@
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 @@
sendassoc(wifi, wn);
break;
case 0xc0: /* deauth */
+ wn->aid = 0;
wifi->status = Sunauth;
+ sendauth(wifi, wn);
break;
}
}
@@ -318,9 +342,11 @@
{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 @@
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 @@
s->orgcode[2] = 0;
memmove(s->type, e.type, 2);
- wifitx(wifi, b);
+ wifitx(wifi, bss, b);
}
static void
@@ -364,6 +390,7 @@
Wifi*
wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
{+ char name[32];
Wifi *wifi;
wifi = malloc(sizeof(Wifi));
@@ -372,8 +399,10 @@
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 @@
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 @@
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",
--- a/sys/src/9/pc/wifi.h
+++ b/sys/src/9/pc/wifi.h
@@ -34,13 +34,13 @@
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*));
--- a/sys/src/cmd/nusb/disk/disk.c
+++ b/sys/src/cmd/nusb/disk/disk.c
@@ -812,7 +812,7 @@
}
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;
}
--- a/sys/src/cmd/nusb/disk/ums.h
+++ b/sys/src/cmd/nusb/disk/ums.h
@@ -79,7 +79,7 @@
/* partitions */
Part part[Maxparts];
- uchar rawcmd[10];
+ uchar rawcmd[16];
uchar phase;
char *inq;
Ums *ums;
--
⑨