merge
This commit is contained in:
commit
6d7bb96b22
13 changed files with 412 additions and 151 deletions
2
lib/rsc
2
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
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 @@ 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 +1507,75 @@ 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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(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 @@ 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",
|
||||
|
|
|
@ -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*));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ struct Umsc
|
|||
/* partitions */
|
||||
Part part[Maxparts];
|
||||
|
||||
uchar rawcmd[10];
|
||||
uchar rawcmd[16];
|
||||
uchar phase;
|
||||
char *inq;
|
||||
Ums *ums;
|
||||
|
|
Loading…
Reference in a new issue