[-- Attachment #1: Type: text/plain, Size: 736 bytes --]
2022-02-13 19:56 GMT+03:00, jpegbild@dismail.de <jpegbild@dismail.de>:
>> I'll try the patch and return
> It worked, and as kemal had said the only problem was with the calibration,
> but nothing other than a warning at boot happened for me. someone should
> commit
> the patch [attached just in case]
>
yes, but sadly i didn't manage to fix the issue. the fw does not send the calib
results properly. i tried to change how etheriwl sends the calibration
request cmd
by making it similar to what openbsd and linux does, but it spits a fw
error instead.
i gave up on fixing that error, i see NO reason why it shits itself.
the diff jpegbild sent can be pushed, and here is the recent patch (that doesn't
work and shouldn't be pushed):
[-- Attachment #2: diff.txt --]
[-- Type: text/plain, Size: 21373 bytes --]
diff 60adc40118dda2edf2a238d22d050a7bae5e0d66 uncommitted
--- a/sys/src/9/pc/etheriwl.c
+++ b/sys/src/9/pc/etheriwl.c
@@ -3,7 +3,7 @@
*
* Written without any documentation but Damien Bergamini's
* iwn(4) and Stefan Sperling's iwm(4) OpenBSD driver sources.
- * Requires Intel firmware to be present in /lib/firmware/iw[nm]-*
+ * Requires Intel firmware to be present in /lib/firmware/
* on attach.
*/
@@ -329,7 +329,20 @@
SchedTransTblOff = 0x7E0, // +q*2
};
+/*
+ * uCode capabilities
+ */
enum {
+ UcodeApiMMcc = 9,
+ UcodeApiSta = 30,
+
+ UcodeCapaLar = 1,
+ UcodeCapaMMcc = 29,
+ UcodeCapaQuota = 44,
+ UcodeCapaLar2 = 73,
+};
+
+enum {
FilterPromisc = 1<<0,
FilterCtl = 1<<1,
FilterMulticast = 1<<2,
@@ -565,7 +578,6 @@
uchar type;
uchar step;
uchar dash;
- uchar pnum;
uchar txantmask;
uchar rxantmask;
} rfcfg;
@@ -586,8 +598,6 @@
} eeprom;
struct {
- u32int version;
-
void *buf;
int len;
@@ -634,9 +644,6 @@
Type6005 = 11, /* also Centrino Advanced-N 6030, 6235 */
Type2030 = 12,
Type2000 = 16,
-
- Type7260 = 30,
- Type8265 = 35,
};
static struct ratetab {
@@ -687,10 +694,9 @@
[Type1000] "iwn-1000",
[Type6000] "iwn-6000",
[Type6050] "iwn-6050",
- [Type6005] "iwn-6005", /* see in iwlattach() below */
+ [Type6005] "iwn-6005", /* 6030/6235 uses iwn-6030, see iwlpci() */
[Type2030] "iwn-2030",
[Type2000] "iwn-2000",
- [Type7260] "iwm-7260-17",
};
static char *qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block);
@@ -697,8 +703,10 @@
static char *flushq(Ctlr *ctlr, uint qid);
static char *cmd(Ctlr *ctlr, uint code, uchar *data, int size);
-#define csr32r(c, r) (*((c)->nic+((r)/4)))
-#define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
+#define csr32r(c, r) ((c)->nic[(r)/4])
+#define csr32w(c, r, v) ((c)->nic[(r)/4] = (v))
+/* macro to help with ctlr->fw->(api|capa) */
+#define isset(a, i) ((a)[(i)/32] & 1U<<(i)%32)
static uint
get16(uchar *p){
@@ -728,10 +736,12 @@
int i;
csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) | MacAccessReq);
- for(i=0; i<1000; i++){
+ if(ctlr->family >= 8000)
+ microdelay(2);
+ for(i=0; i<1500; i++){
if((csr32r(ctlr, Gpc) & (NicSleep | MacAccessEna)) == MacAccessEna)
return 0;
- delay(10);
+ microdelay(10);
}
return "niclock: timeout";
}
@@ -944,7 +954,7 @@
for(j=0; j<100; j++){
if(csr32r(ctlr, Cfg) & EepromLocked)
return 0;
- delay(10);
+ microdelay(10);
}
}
return "eepromlock: timeout";
@@ -969,7 +979,7 @@
w = csr32r(ctlr, EepromIo);
if(w & 1)
break;
- delay(5);
+ microdelay(5);
}
if(i == 10)
return "eepromread: timeout";
@@ -990,34 +1000,35 @@
static char*
handover(Ctlr *ctlr)
{
- int i;
+ int n, i, j;
csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | NicReady);
for(i=0; i<5; i++){
if(csr32r(ctlr, Cfg) & NicReady)
goto Ready;
- delay(10);
+ microdelay(10);
}
+
if(ctlr->family >= 7000){
csr32w(ctlr, Dbglinkpwrmgmt, csr32r(ctlr, Dbglinkpwrmgmt) | (1<<31));
delay(1);
}
- csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | Prepare);
- for(i=0; i<15000; i++){
- if((csr32r(ctlr, Cfg) & PrepareDone) == 0)
- break;
- delay(10);
- }
- if(i >= 15000)
- return "handover: timeout";
+ for(n=0; n<10; n++){
+ csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | Prepare);
- csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | NicReady);
- for(i=0; i<5; i++){
- if(csr32r(ctlr, Cfg) & NicReady)
- goto Ready;
- delay(10);
+ for(i=0; i<750; i++){
+ csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | NicReady);
+ for(j=0; j<5; j++){
+ if(csr32r(ctlr, Cfg) & NicReady)
+ goto Ready;
+ microdelay(10);
+ }
+ microdelay(200);
+ }
+ delay(25);
}
+
return "handover: timeout";
Ready:
if(ctlr->family >= 7000)
@@ -1035,7 +1046,7 @@
for(i=0; i<2500; i++){
if(csr32r(ctlr, Gpc) & MacClockReady)
return 0;
- delay(10);
+ microdelay(10);
}
return "clockwait: timeout";
}
@@ -1046,7 +1057,6 @@
int capoff;
char *err;
-
if(ctlr->family >= 7000){
/* Reset entire device */
csr32w(ctlr, Reset, (1<<7));
@@ -1093,14 +1103,13 @@
nicunlock(ctlr);
}
- /* Enable the oscillator to count wake up time for L1 exit. (weird W/A) */
- if(ctlr->type == Type7260){
+ /* Enable the oscillator to count wake up time for L1 exit. (W/A for 7260/3160) */
+ if(ctlr->pdev->did >= 0x08b1 && ctlr->pdev->did <= 0x08b4){
if((err = niclock(ctlr)) != nil)
return err;
prphread(ctlr, OscClk);
prphread(ctlr, OscClk);
- delay(20);
prphwrite(ctlr, OscClk, prphread(ctlr, OscClk) | OscClkCtrl);
@@ -1119,7 +1128,7 @@
prphwrite(ctlr, ApmgClkEna, DmaClkRqt | BsmClkRqt);
else
prphwrite(ctlr, ApmgClkEna, DmaClkRqt);
- delay(20);
+ microdelay(20);
/* Disable L1-Active. */
prphwrite(ctlr, ApmgPciStt, prphread(ctlr, ApmgPciStt) | (1<<11));
@@ -1158,7 +1167,7 @@
for(j = 0; j < 200; j++){
if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
break;
- delay(10);
+ microdelay(20);
}
}
nicunlock(ctlr);
@@ -1168,17 +1177,17 @@
if(niclock(ctlr) == nil){
if(ctlr->mqrx){
prphwrite(ctlr, RfhDmaCfg, 0);
- for(j = 0; j < 200; j++){
+ for(j = 0; j < 1000; j++){
if(prphread(ctlr, RfhGenStatus) & RfhGenStatusDmaIdle)
break;
- delay(10);
+ microdelay(10);
}
} else {
csr32w(ctlr, FhRxConfig, 0);
- for(j = 0; j < 200; j++){
+ for(j = 0; j < 1000; j++){
if(csr32r(ctlr, FhRxStatus) & 0x1000000)
break;
- delay(10);
+ microdelay(10);
}
}
nicunlock(ctlr);
@@ -1190,7 +1199,7 @@
prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
nicunlock(ctlr);
}
- delay(5);
+ microdelay(5);
}
if(ctlr->family >= 7000){
@@ -1206,12 +1215,12 @@
for(j = 0; j < 100; j++){
if(csr32r(ctlr, Reset) & (1<<8))
break;
- delay(10);
+ microdelay(10);
}
/* Reset the entire device. */
csr32w(ctlr, Reset, csr32r(ctlr, Reset) | (1<<7));
- delay(10);
+ delay(5);
/* Clear "initialization complete" bit. */
csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) & ~InitDone);
@@ -1239,7 +1248,7 @@
if((err = niclock(ctlr)) != nil)
return err;
prphwrite(ctlr, ApmgPs, prphread(ctlr, ApmgPs) | ResetReq);
- delay(5);
+ microdelay(5);
prphwrite(ctlr, ApmgPs, prphread(ctlr, ApmgPs) & ~ResetReq);
nicunlock(ctlr);
@@ -1308,11 +1317,12 @@
ctlr->type &= 0x1FF;
ctlr->dash = ctlr->type & 3, ctlr->type >>= 2;
ctlr->step = ctlr->type & 3, ctlr->type >>= 2;
- if(fwname[ctlr->type] == nil){
+ }
+ if(ctlr->fwname == nil)
+ if(ctlr->type >= nelem(fwname) || (ctlr->fwname = fwname[ctlr->type]) == nil){
print("iwl: unsupported controller type %d\n", ctlr->type);
return -1;
}
- }
if((err = handover(ctlr)) != nil)
goto Err;
@@ -1828,34 +1838,34 @@
csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | RadioSi | MacSi);
}
- if(ctlr->family < 8000){
+ if(ctlr->family <= 7000 && ctlr->type != Type4965){
if((err = niclock(ctlr)) != nil)
return err;
- if(ctlr->family == 7000 || ctlr->type != Type4965)
- prphwrite(ctlr, ApmgPs, prphread(ctlr, ApmgPs) | EarlyPwroffDis);
- nicunlock(ctlr);
- }
- if(ctlr->family < 7000){
- if((err = niclock(ctlr)) != nil)
- return err;
- if(ctlr->type == Type1000){
- /*
- * Select first Switching Voltage Regulator (1.32V) to
- * solve a stability issue related to noisy DC2DC line
- * in the silicon of 1000 Series.
- */
+ prphwrite(ctlr, ApmgPs, prphread(ctlr, ApmgPs) | EarlyPwroffDis);
+ /*
+ * Select first Switching Voltage Regulator (1.32V) to
+ * solve a stability issue related to noisy DC2DC line
+ * in the silicon of 1000 Series.
+ */
+ if(ctlr->type == Type1000)
prphwrite(ctlr, ApmgDigitalSvr,
(prphread(ctlr, ApmgDigitalSvr) & ~(0xf<<5)) | (3<<5));
- }
- if((ctlr->type == Type6005 || ctlr->type == Type6050) && ctlr->eeprom.version == 6)
- csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvCalV6);
- if(ctlr->type == Type6005)
- csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrv1X2);
- if(ctlr->type == Type2030 || ctlr->type == Type2000)
- csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvRadioIqInvert);
nicunlock(ctlr);
}
+ switch(ctlr->type){
+ case Type6005:
+ csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrv1X2);
+ case Type6050:
+ if(ctlr->eeprom.version >= 6)
+ csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvCalV6);
+ break;
+ case Type2030:
+ case Type2000:
+ csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvRadioIqInvert);
+ break;
+ }
+
if((err = niclock(ctlr)) != nil)
return err;
@@ -1979,14 +1989,20 @@
{
uchar c[2+1+1+4+5*4], *p;
+ if(!isset(ctlr->fw->capa, UcodeCapaLar))
+ return nil;
+
memset(p = c, 0, sizeof(c));
*p++ = mcc[1];
*p++ = mcc[0];
- *p++ = 0;
- *p++ = 0; // reserved
- if(1){
- p += 4;
- p += 5*4;
+ if(isset(ctlr->fw->api, UcodeApiMMcc) || isset(ctlr->fw->capa, UcodeCapaMMcc))
+ *p++ = 0x10; /* source id */
+ else
+ p++; /* reserved */
+ p++; /* reserved */
+ if(isset(ctlr->fw->capa, UcodeCapaLar2)){
+ p += 4; /* integrity key (???) */
+ p += 5*4; /* reserved */
}
return cmd(ctlr, 200, c, p - c);
}
@@ -2009,10 +2025,9 @@
p = c;
if(ctlr->family >= 7000){
- put32(p, 3);
+ put32(p, 3); /* mode */
p += 4;
- put32(p, (1<<4));
- p += 4;
+ p += 4; /* enabled modules */
} else if(ctlr->type == Type2030){
*p++ = 145; /* flags */
p++; /* lead time */
@@ -2217,45 +2232,31 @@
return o;
}
+static int
+invalidea(uchar *ea)
+{
+ static uchar reserved[] = {0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00};
+
+ return ea[0] & 1 || memcmp(ea, reserved, Eaddrlen) == 0;
+}
+
static char*
readnvmconfig(Ctlr *ctlr)
{
uchar *ea = ctlr->edev->ea;
uchar buf[8];
- uint u;
char *err;
-
- if(readnvmsect(ctlr, 1, buf, 8, 0) != 8)
- return "can't read nvm version";
-
- ctlr->nvm.version = get16(buf);
- if (ctlr->family == 7000) {
- u = get16(buf + 2);
-
- ctlr->rfcfg.type = (u >> 4) & 3;
- ctlr->rfcfg.step = (u >> 2) & 3;
- ctlr->rfcfg.dash = (u >> 0) & 3;
- ctlr->rfcfg.pnum = (u >> 6) & 3;
-
- ctlr->rfcfg.txantmask = (u >> 8) & 15;
- ctlr->rfcfg.rxantmask = (u >> 12) & 15;
-
- } else {
+
+ if(ctlr->family >= 8000){
if(readnvmsect(ctlr, 12, buf, 8, 0) != 8)
return "can't read nvm phy config";
u = get32(buf);
- ctlr->rfcfg.type = (u >> 12) & 0xFFF;
- ctlr->rfcfg.step = (u >> 8) & 15;
- ctlr->rfcfg.dash = (u >> 4) & 15;
- ctlr->rfcfg.pnum = (u >> 6) & 3;
-
ctlr->rfcfg.txantmask = (u >> 24) & 15;
ctlr->rfcfg.rxantmask = (u >> 28) & 15;
- }
- if(ctlr->family >= 8000){
- if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen){
+
+ if(readnvmsect(ctlr, 11, ea, Eaddrlen, 1*2) != Eaddrlen || invalidea(ea)){
u32int a0, a1;
if((err = niclock(ctlr)) != nil)
@@ -2270,9 +2271,18 @@
ea[3] = a0 >> 0;
ea[4] = a1 >> 8;
ea[5] = a1 >> 0;
- }
- } else {
- readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1);
+ }
+ }else{
+ /* fw gets angry if we read 6 bytes, read 8 bytes to make the fw happy. */
+ if(readnvmsect(ctlr, 0, buf, 8, (0x15-1)*2) != 8)
+ return "can't read ea from nvm";
+
+ ea[0] = buf[3];
+ ea[1] = buf[2];
+ ea[2] = buf[5];
+ ea[3] = buf[4];
+ ea[4] = buf[7];
+ ea[5] = buf[6];
}
memmove(ctlr->edev->addr, ea, Eaddrlen);
@@ -2285,18 +2295,20 @@
uchar c[4];
put32(c, val);
- return cmd(ctlr, 152, c, 4);
+ return cmd(ctlr, 152, c, sizeof(c));
}
static char*
-sendphyconfig(Ctlr *ctlr, u32int physku, u32int flowmask, u32int eventmask)
+sendphyconfig(Ctlr *ctlr, u32int flowmask, u32int eventmask)
{
uchar c[3*4];
- put32(c+0, physku);
+ put32(c+0, ctlr->fw->physku & 0xff00ffff |
+ ctlr->rfcfg.txantmask << 16 |
+ ctlr->rfcfg.rxantmask << 20);
put32(c+4, flowmask);
put32(c+8, eventmask);
- return cmd(ctlr, 106, c, 3*4);
+ return cmd(ctlr, 106, c, sizeof(c));
}
static char*
@@ -2311,7 +2323,7 @@
memset(p = c, 0, sizeof(c));
*p = sta->id;
- if((err = cmd(ctlr, 25, c, 4)) != nil)
+ if((err = cmd(ctlr, 25, c, sizeof(c))) != nil)
return err;
sta->id = -1;
@@ -2366,7 +2378,7 @@
p += 2; /* sleep_tx_count */
p++; /* sleep state flags */
- *p++ = (ctlr->fw->api[0] & (1<<30)) != 0 ? type : 0; /* station_type */
+ *p++ = isset(ctlr->fw->api, UcodeApiSta) ? type : 0; /* station_type */
p += 2; /* assoc id */
@@ -2375,7 +2387,7 @@
put32(p, 1<<0);
p += 4; /* tfd_queue_mask */
- if(1){
+ if(isset(ctlr->fw->api, UcodeApiSta)){
p += 2; /* rx_ba_window */
p++; /* sp_length */
p++; /* uapsd_acs */
@@ -2640,7 +2652,7 @@
static char*
settimeevent(Ctlr *ctlr, int amr, int ival)
{
- int duration, delay, timeid;
+ int timeid;
uchar c[9*4], *p;
char *err;
@@ -2662,14 +2674,6 @@
break;
}
- if(ival){
- duration = ival*2;
- delay = ival/2;
- } else {
- duration = 1024;
- delay = 0;
- }
-
memset(p = c, 0, sizeof(c));
put32(p, ctlr->macid);
p += 4;
@@ -2678,23 +2682,27 @@
put32(p, timeid);
p += 4;
- put32(p, 0); // apply time
- p += 4;
- put32(p, delay);
- p += 4;
- put32(p, 0); // depends on
- p += 4;
- put32(p, 1); // interval
- p += 4;
- put32(p, duration);
- p += 4;
- *p++ = 1; // repeat
- *p++ = 0; // max frags
- put16(p, 1<<0 | 1<<1 | 1<<11); // policy
- p += 2;
+ if(amr == CmdRemove)
+ p += 6*4;
+ else{
+ put32(p, 0); // apply time
+ p += 4;
+ put32(p, ival/2); // max delay
+ p += 4;
+ put32(p, 0); // depends on
+ p += 4;
+ put32(p, 1); // interval
+ p += 4;
+ put32(p, ival? ival*2: 1024); // duration
+ p += 4;
+ *p++ = 1; // repeat
+ *p++ = 0; // max frags
+ put16(p, 1<<0 | 1<<1 | 1<<11); // policy
+ p += 2;
+ }
ctlr->te.active = 0;
- if((err = cmd(ctlr, 41, c, p - c)) != nil)
+ if((err = cmd(ctlr, 41, c, p - c)) != nil)
return err;
if(amr == CmdRemove){
@@ -2713,6 +2721,9 @@
uchar c[4*(3*4)], *p;
int i;
+ if(!isset(ctlr->fw->capa, UcodeCapaQuota))
+ return nil;
+
i = 0;
p = c;
@@ -2819,16 +2830,16 @@
uchar c[11*4];
memset(c, 0, sizeof(c));
- return cmd(ctlr, 210, c, 11*4);
+ return cmd(ctlr, 210, c, sizeof(c));
}
-static void
+static char*
tttxbackoff(Ctlr *ctlr)
{
uchar c[4];
put32(c, 0);
- cmd(ctlr, 126, c, sizeof(c));
+ return cmd(ctlr, 126, c, sizeof(c));
}
static char*
@@ -2839,7 +2850,7 @@
memset(c, 0, sizeof(c));
put16(c, 0<<13 | 1<<0); // cont active off, pm enable
- return cmd(ctlr, 119, c, 4);
+ return cmd(ctlr, 119, c, sizeof(c));
}
static char*
@@ -2850,6 +2861,9 @@
if(ctlr->calib.done == 0){
if((err = readnvmconfig(ctlr)) != nil)
return err;
+ if(ctlr->family == 7000)
+ if((err = sendbtcoexadv(ctlr)) != nil)
+ return err;
}
if((err = sendtxantconfig(ctlr, ctlr->rfcfg.txantmask)) != nil)
@@ -2857,7 +2871,6 @@
if(ctlr->calib.done == 0){
if((err = sendphyconfig(ctlr,
- ctlr->fw->physku,
ctlr->fw->init.defcalib.flowmask,
ctlr->fw->init.defcalib.eventmask)) != nil)
return err;
@@ -2871,6 +2884,7 @@
ctlr->calib.done = 1;
}
} else {
+ uchar c[4];
Block *b;
int i;
@@ -2877,8 +2891,23 @@
for(i = 0; i < nelem(ctlr->calib.cmd); i++){
if((b = ctlr->calib.cmd[i]) == nil)
continue;
+ print("iwl: calibration command %d is going to be sent\n", i);
+ if(b == ctlr->calib.cfg)
+ put16(c, 1);
+ else if(b == ctlr->calib.nch)
+ put16(c, 2);
+ else if(ctlr->calib.cmd+i >= ctlr->calib.papd &&
+ ctlr->calib.cmd+i < ctlr->calib.papd+nelem(ctlr->calib.papd))
+ put16(c, 4);
+ else if(ctlr->calib.cmd+i >= ctlr->calib.txp &&
+ ctlr->calib.cmd+i < ctlr->calib.txp+nelem(ctlr->calib.txp))
+ put16(c, 5);
+ else
+ continue;
+ put16(c+2, BLEN(b));
+
b = copyblock(b, BLEN(b));
- if((qcmd(ctlr, 4, 108, nil, 0, b)) != nil){
+ if((qcmd(ctlr, 4, 108, c, sizeof(c), b)) != nil){
freeb(b);
return err;
}
@@ -2887,7 +2916,6 @@
}
if((err = sendphyconfig(ctlr,
- ctlr->fw->physku,
ctlr->fw->main.defcalib.flowmask,
ctlr->fw->main.defcalib.eventmask)) != nil)
return err;
@@ -2895,9 +2923,9 @@
if((err = sendbtcoexadv(ctlr)) != nil)
return err;
- /* Initialize tx backoffs to the minimum. */
if(ctlr->family == 7000)
- tttxbackoff(ctlr);
+ if((err = tttxbackoff(ctlr)) != nil)
+ return err;
if((err = updatedevicepower(ctlr)) != nil){
print("can't update device power: %s\n", err);
@@ -2904,7 +2932,7 @@
return err;
}
if((err = sendmccupdate(ctlr, "ZZ")) != nil){
- print("can't disable beacon filter: %s\n", err);
+ print("can't send mcc update: %s\n", err);
return err;
}
if((err = disablebeaconfilter(ctlr)) != nil){
@@ -3034,10 +3062,9 @@
if((err = sendtxantconfig(ctlr, ctlr->rfcfg.txantmask & 7)) != nil)
return err;
- if(ctlr->type == Type2030){
+ if(ctlr->type == Type2030)
if((err = sendbtcoexadv(ctlr)) != nil)
return err;
- }
}
return nil;
}
@@ -3362,7 +3389,7 @@
for(i=0; i<1000; i++){
if((prphread(ctlr, BsmWrCtrl) & (1<<31)) == 0)
break;
- delay(10);
+ microdelay(10);
}
if(i == 1000){
nicunlock(ctlr);
@@ -3418,6 +3445,7 @@
static char*
qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
{
+ char *err;
int hdrlen;
Block *bcmd;
uchar *d, *c;
@@ -3451,12 +3479,6 @@
iunlock(ctlr);
return "qcmd: broken";
}
- /* wake up the nic (just needed for 7k) */
- if(ctlr->family == 7000 && q->n == 0)
- if(niclock(ctlr) != nil){
- iunlock(ctlr);
- return "qcmd: busy";
- }
q->n++;
q->lastcmd = code;
@@ -3507,6 +3529,13 @@
coherence();
+ /* wake up the nic so it sees the command */
+ if(ctlr->family == 7000 && qid == 4 && q->n == 0)
+ if((err = niclock(ctlr)) != nil){
+ iunlock(ctlr);
+ return err;
+ }
+
q->i = (q->i+1) % Ntx;
csr32w(ctlr, HbusTargWptr, (qid<<8) | q->i);
@@ -3586,9 +3615,16 @@
int i;
for(i = 0; i < nelem(ctlr->tx); i++)
- flushq(ctlr, i);
- settimeevent(ctlr, CmdRemove, 0);
+ if((err = flushq(ctlr, i)) != nil){
+ print("can't flush queue %d: %s\n", i, err);
+ return err;
+ }
+ if((err = settimeevent(ctlr, CmdRemove, 0)) != nil){
+ print("can't remove time event: %s\n", err);
+ return err;
+ }
+
if((err = setbindingquotas(ctlr, -1)) != nil){
print("can't disable quotas: %s\n", err);
return err;
@@ -3630,7 +3666,7 @@
return err;
}
if((err = setbindingcontext(ctlr, CmdAdd)) != nil){
- print("removing bindingcontext: %s\n", err);
+ print("adding bindingcontext: %s\n", err);
return err;
}
if((err = setmcastfilter(ctlr)) != nil){
@@ -3984,7 +4020,6 @@
static void
iwlattach(Ether *edev)
{
- FWImage *fw;
Ctlr *ctlr;
char *err;
@@ -4002,29 +4037,13 @@
error("wifi disabled by switch");
if(ctlr->fw == nil){
- char *fn;
-
- fn = ctlr->fwname;
- if(fn == nil){
- fn = fwname[ctlr->type];
- if(ctlr->type == Type6005){
- switch(ctlr->pdev->did){
- case 0x0082: /* Centrino Advanced-N 6205 */
- case 0x0085: /* Centrino Advanced-N 6205 */
- break;
- default: /* Centrino Advanced-N 6030, 6235 */
- fn = "iwn-6030";
- }
- }
- }
- fw = readfirmware(fn);
+ ctlr->fw = readfirmware(ctlr->fwname);
print("#l%d: firmware: %s, rev %ux, build %ud, size [%d] %ux+%ux + [%d] %ux+%ux + %ux\n",
- edev->ctlrno, fn,
- fw->rev, fw->build,
- fw->main.nsect, fw->main.text.size, fw->main.data.size,
- fw->init.nsect, fw->init.text.size, fw->init.data.size,
- fw->boot.text.size);
- ctlr->fw = fw;
+ edev->ctlrno, ctlr->fwname,
+ ctlr->fw->rev, ctlr->fw->build,
+ ctlr->fw->main.nsect, ctlr->fw->main.text.size, ctlr->fw->main.data.size,
+ ctlr->fw->init.nsect, ctlr->fw->init.text.size, ctlr->fw->init.data.size,
+ ctlr->fw->boot.text.size);
}
if(ctlr->family >= 7000){
@@ -4282,17 +4301,14 @@
freeblist(bb);
if(tx != nil && tx->n > 0){
tx->n--;
- wakeup(tx);
/* unlock 7k family nics as all commands are done */
- if(ctlr->family == 7000 && tx->n == 0)
+ if(ctlr->family == 7000 && qid == 4 && tx->n == 0)
nicunlock(ctlr);
+ wakeup(tx);
}
}
- if(ctlr->mqrx){
- csr32w(ctlr, FhRxQ0Wptr, ((hw+Nrx-1) % Nrx) & ~7);
- }else
- csr32w(ctlr, FhRxWptr, ((hw+Nrx-1) % Nrx) & ~7);
+ csr32w(ctlr, ctlr->mqrx ? FhRxQ0Wptr : FhRxWptr, ((hw+Nrx-1) % Nrx) & ~7);
}
static void
@@ -4354,14 +4370,12 @@
int family;
pdev = nil;
- while(pdev = pcimatch(pdev, 0, 0)) {
+ while(pdev = pcimatch(pdev, 0x8086, 0)){
Ctlr *ctlr;
void *mem;
if(pdev->ccrb != 2 || pdev->ccru != 0x80)
continue;
- if(pdev->vid != 0x8086)
- continue;
if(pdev->mem[0].bar & 1)
continue;
@@ -4389,19 +4403,28 @@
case 0x0891: /* Centrino Wireless-N 2200 */
case 0x0887: /* Centrino Wireless-N 2230 */
case 0x0888: /* Centrino Wireless-N 2230 */
+ family = 0;
+ fwname = nil;
+ break;
case 0x0090: /* Centrino Advanced-N 6030 */
case 0x0091: /* Centrino Advanced-N 6030 */
case 0x088e: /* Centrino Advanced-N 6235 */
case 0x088f: /* Centrino Advanced-N 6235 */
family = 0;
- fwname = nil;
+ fwname = "iwn-6030";
break;
case 0x08b1: /* Wireless AC 7260 */
case 0x08b2: /* Wireless AC 7260 */
family = 7000;
- fwname = nil;
+ fwname = "iwm-7260-17";
break;
+ case 0x08b3: /* Wireless AC 3160 */
+ case 0x08b4: /* Wireless AC 3160 */
+ family = 7000;
+ fwname = "iwm-3160-17";
+ break;
case 0x24f3: /* Wireless AC 8260 */
+ case 0x24f4: /* Wireless AC 8260 */
family = 8000;
fwname = "iwm-8000C-34";
break;