OK, turing.

<- leave blank

Sat Sep 18 19:53:50 EDT 2021

diff 8f4842d3465e96d264f5c2f7fa2d61db871aae9f 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,24 @@
	SchedTransTblOff = 0x7E0, // +q*2
 };

+/*
+ * uCode capabilities
+ */
 enum {
+ /* api[0] */
+ UcodeApiSta = 1<<30,
+
+ /* capa[0] */
+ UcodeCapLar = 1<<1,
+
+ /* capa[1] */
+ UcodeCapQuota = 1<<12,
+
+ /* capa[2] */
+ UcodeCapLar2 = 1<<9,
+};
+
+enum {
	FilterPromisc = 1<<0,
	FilterCtl = 1<<1,
	FilterMulticast = 1<<2,
@@ -418,6 +435,7 @@
	uint build;
	char descr[64+1];

+ u32int flags;
	u32int capa[4];
	u32int api[4];

@@ -565,7 +583,6 @@
		uchar type;
		uchar step;
		uchar dash;
- uchar pnum;
		uchar txantmask;
		uchar rxantmask;
	} rfcfg;
@@ -586,7 +603,7 @@
	} eeprom;

	struct {
- u32int version;
+ int read;

		void *buf;
		int len;
@@ -635,8 +652,7 @@
	Type2030 = 12,
	Type2000 = 16,

- Type7260 = 30,
- Type8265 = 35,
+ Type7260 = 20,
 };

 static struct ratetab {
@@ -690,7 +706,6 @@
	[Type6005] "iwn-6005", /* see in iwlattach() below */
	[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);
@@ -728,10 +743,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 +961,7 @@
		for(j=0; j<100; j++){
			if(csr32r(ctlr, Cfg) & EepromLocked)
				return 0;
- delay(10);
+ microdelay(10);
		}
	}
	return "eepromlock: timeout";
@@ -969,7 +986,7 @@
			w = csr32r(ctlr, EepromIo);
			if(w & 1)
				break;
- delay(5);
+ microdelay(5);
		}
		if(i == 10)
			return "eepromread: timeout";
@@ -990,34 +1007,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 +1053,7 @@
	for(i=0; i<2500; i++){
		if(csr32r(ctlr, Gpc) & MacClockReady)
			return 0;
- delay(10);
+ microdelay(10);
	}
	return "clockwait: timeout";
 }
@@ -1046,7 +1064,6 @@
	int capoff;
	char *err;

-
	if(ctlr->family >= 7000){
		/* Reset entire device */
		csr32w(ctlr, Reset, (1<<7));
@@ -1100,7 +1117,6 @@

		prphread(ctlr, OscClk);
		prphread(ctlr, OscClk);
- delay(20);

		prphwrite(ctlr, OscClk, prphread(ctlr, OscClk) | OscClkCtrl);

@@ -1119,7 +1135,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 +1174,7 @@
			for(j = 0; j < 200; j++){
				if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
					break;
- delay(10);
+ microdelay(20);
			}
		}
		nicunlock(ctlr);
@@ -1168,17 +1184,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 +1206,7 @@
			prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
			nicunlock(ctlr);
		}
- delay(5);
+ microdelay(5);
	}

	if(ctlr->family >= 7000){
@@ -1206,12 +1222,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 +1255,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,7 +1324,7 @@
		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 && fwname[ctlr->type] == nil){
			print("iwl: unsupported controller type %d\n",
			ctlr->type);
			return -1;
		}
@@ -1478,6 +1494,11 @@
				s = &i->boot.text;
				s->addr = 0x00000000;
				goto Sect;
+ case 18:
+ if(l < 4)
+ goto Tooshort;
+ i->flags = get32(p);
+ break;
			case 19:
				if(i->main.nsect >= nelem(i->main.sect))
					return "too many main sections";
@@ -1984,7 +2005,7 @@
	*p++ = mcc[0];
	*p++ = 0;
	*p++ = 0; // reserved
- if(1){
+ if(ctlr->fw->capa[2] & UcodeCapLar2){
		p += 4;
		p += 5*4;
	}
@@ -2217,45 +2238,40 @@
	return o;
 }

+static int
+validea(uchar *ea)
+{
+ static uchar reservedea[] = {0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00},
zeros[Eaddrlen];
+
+ if(ea[0] & 1 ||
+ memcmp(ea, reservedea, Eaddrlen) == 0 ||
+ memcmp(ea, zeros, Eaddrlen) == 0)
+ return 0;
+ return 1;
+}
+
 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";
+ if(ctlr->nvm.read)
+ return nil;

- 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(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(readnvmsect(ctlr, ctlr->family >= 8000 ? 12 : 1, buf, 1, 3) != 1)
+ return "can't read antenna data from nvm";
+ if(*buf & 15 & ctlr->rfcfg.txantmask)
+ ctlr->rfcfg.txantmask &= *buf & 15;
+ if(*buf >> 4 & ctlr->rfcfg.rxantmask)
+ ctlr->rfcfg.rxantmask &= *buf >> 4;
+ ctlr->fw->physku &= 0xff00ffffUL;
+ ctlr->fw->physku |= ctlr->rfcfg.txantmask << 16;
+ ctlr->fw->physku |= ctlr->rfcfg.rxantmask << 20;
+
	if(ctlr->family >= 8000){
- if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen){
+ if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen ||
!validea(ea)){
			u32int a0, a1;

			if((err = niclock(ctlr)) != nil)
@@ -2270,12 +2286,23 @@
			ea[3] = a0 >> 0;
			ea[4] = a1 >> 8;
			ea[5] = a1 >> 0;
- }
- } else {
- readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1);
+ }
+ }else{
+ /* reading 6 bytes from 0x15 seems to cause an ADVANCED_SYSASSERT.  */
+ if(readnvmsect(ctlr, 0, buf, 8, 0x14<<1) != 8)
+ return "can't read ea from nvm";
+
+ /* byte order is 16 bit little endian.  */
+ 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);

+ ctlr->nvm.read = 1;
	return nil;
 }

@@ -2366,7 +2393,7 @@
		p += 2; /* sleep_tx_count */
		p++; /* sleep state flags */

- *p++ = (ctlr->fw->api[0] & (1<<30)) != 0 ? type : 0; /* station_type
*/
+ *p++ = ctlr->fw->api[0] & UcodeApiSta ? type : 0; /* station_type */

		p += 2; /* assoc id */

@@ -2375,7 +2402,7 @@
		put32(p, 1<<0);
		p += 4; /* tfd_queue_mask */

- if(1){
+ if(ctlr->fw->api[0] & UcodeApiSta){
			p += 2; /* rx_ba_window */
			p++; /* sp_length */
			p++; /* uapsd_acs */
@@ -2640,7 +2667,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 +2689,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 +2697,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 +2736,9 @@
	uchar c[4*(3*4)], *p;
	int i;

+ if((ctlr->fw->capa[1] & UcodeCapQuota) == 0)
+ return nil;
+
	i = 0;
	p = c;

@@ -2822,13 +2848,13 @@
	return cmd(ctlr, 210, c, 11*4);
 }

-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*
@@ -2848,6 +2874,9 @@
	char *err;

	if(ctlr->calib.done == 0){
+ if(ctlr->family == 7000)
+ if((err = sendbtcoexadv(ctlr)) != nil)
+ return err;
		if((err = readnvmconfig(ctlr)) != nil)
			return err;
	}
@@ -2897,16 +2926,16 @@

		/* 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);
			return err;
		}
- if((err = sendmccupdate(ctlr, "ZZ")) != nil){
- print("can't disable beacon filter: %s\n", err);
- return err;
- }
+ if(ctlr->fw->capa[0] & UcodeCapLar)
+ if((err = sendmccupdate(ctlr, "ZZ")) != nil)
+ return err;
		if((err = disablebeaconfilter(ctlr)) != nil){
			print("can't disable beacon filter: %s\n", err);
			return err;
@@ -3362,7 +3391,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 +3447,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 +3481,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 +3531,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 +3617,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 +3668,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){
@@ -4283,8 +4321,8 @@
		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)
+ /* unlock 7k family nics as the command is done */
+ if(ctlr->family == 7000 && qid == 4 && tx->n == 0)
				nicunlock(ctlr);
		}
	}
@@ -4354,14 +4392,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;

@@ -4399,9 +4435,10 @@
		case 0x08b1: /* Wireless AC 7260 */
		case 0x08b2: /* Wireless AC 7260 */
			family = 7000;
- fwname = nil;
+ fwname = "iwm-7260-17";
			break;
		case 0x24f3: /* Wireless AC 8260 */
+ case 0x24f4: /* Wireless AC 8260 */
			family = 8000;
			fwname = "iwm-8000C-34";
			break;


Sat Sep 18 19:44:54 EDT 2021
diff 8f4842d3465e96d264f5c2f7fa2d61db871aae9f 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,27 @@
	SchedTransTblOff = 0x7E0, // +q*2
 };

+/*
+ * uCode capabilities
+ */
 enum {
+ /* flags */
+ UcodeFlgDwBc = 1<<4,
+
+ /* api[0] */
+ UcodeApiSta = 1<<30,
+
+ /* capa[0] */
+ UcodeCapLar = 1<<1,
+
+ /* capa[1] */
+ UcodeCapQuota = 1<<12,
+
+ /* capa[2] */
+ UcodeCapLar2 = 1<<9,
+};
+
+enum {
	FilterPromisc = 1<<0,
	FilterCtl = 1<<1,
	FilterMulticast = 1<<2,
@@ -418,6 +438,7 @@
	uint build;
	char descr[64+1];

+ u32int flags;
	u32int capa[4];
	u32int api[4];

@@ -565,7 +586,6 @@
		uchar type;
		uchar step;
		uchar dash;
- uchar pnum;
		uchar txantmask;
		uchar rxantmask;
	} rfcfg;
@@ -586,7 +606,7 @@
	} eeprom;

	struct {
- u32int version;
+ int read;

		void *buf;
		int len;
@@ -635,8 +655,7 @@
	Type2030 = 12,
	Type2000 = 16,

- Type7260 = 30,
- Type8265 = 35,
+ Type7260 = 20,
 };

 static struct ratetab {
@@ -690,7 +709,6 @@
	[Type6005] "iwn-6005", /* see in iwlattach() below */
	[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);
@@ -728,10 +746,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 +964,7 @@
		for(j=0; j<100; j++){
			if(csr32r(ctlr, Cfg) & EepromLocked)
				return 0;
- delay(10);
+ microdelay(10);
		}
	}
	return "eepromlock: timeout";
@@ -969,7 +989,7 @@
			w = csr32r(ctlr, EepromIo);
			if(w & 1)
				break;
- delay(5);
+ microdelay(5);
		}
		if(i == 10)
			return "eepromread: timeout";
@@ -990,34 +1010,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 +1056,7 @@
	for(i=0; i<2500; i++){
		if(csr32r(ctlr, Gpc) & MacClockReady)
			return 0;
- delay(10);
+ microdelay(10);
	}
	return "clockwait: timeout";
 }
@@ -1046,7 +1067,6 @@
	int capoff;
	char *err;

-
	if(ctlr->family >= 7000){
		/* Reset entire device */
		csr32w(ctlr, Reset, (1<<7));
@@ -1100,7 +1120,6 @@

		prphread(ctlr, OscClk);
		prphread(ctlr, OscClk);
- delay(20);

		prphwrite(ctlr, OscClk, prphread(ctlr, OscClk) | OscClkCtrl);

@@ -1119,7 +1138,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 +1177,7 @@
			for(j = 0; j < 200; j++){
				if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
					break;
- delay(10);
+ microdelay(20);
			}
		}
		nicunlock(ctlr);
@@ -1168,17 +1187,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 +1209,7 @@
			prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
			nicunlock(ctlr);
		}
- delay(5);
+ microdelay(5);
	}

	if(ctlr->family >= 7000){
@@ -1206,12 +1225,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 +1258,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,7 +1327,7 @@
		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 && fwname[ctlr->type] == nil){
			print("iwl: unsupported controller type %d\n",
			ctlr->type);
			return -1;
		}
@@ -1478,6 +1497,11 @@
				s = &i->boot.text;
				s->addr = 0x00000000;
				goto Sect;
+ case 18:
+ if(l < 4)
+ goto Tooshort;
+ i->flags = get32(p);
+ break;
			case 19:
				if(i->main.nsect >= nelem(i->main.sect))
					return "too many main sections";
@@ -1984,7 +2008,7 @@
	*p++ = mcc[0];
	*p++ = 0;
	*p++ = 0; // reserved
- if(1){
+ if(ctlr->fw->capa[2] & UcodeCapLar2){
		p += 4;
		p += 5*4;
	}
@@ -2217,45 +2241,40 @@
	return o;
 }

+static int
+validea(uchar *ea)
+{
+ static uchar reservedea[] = {0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00},
zeros[Eaddrlen];
+
+ if(ea[0] & 1 ||
+ memcmp(ea, reservedea, Eaddrlen) == 0 ||
+ memcmp(ea, zeros, Eaddrlen) == 0)
+ return 0;
+ return 1;
+}
+
 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";
+ if(ctlr->nvm.read)
+ return nil;

- 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(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(readnvmsect(ctlr, ctlr->family >= 8000 ? 12 : 1, buf, 2, 0x01<<1)
!= 2)
+ return "can't read antenna data from nvm";
+ if(buf[1] & 15 & ctlr->rfcfg.txantmask)
+ ctlr->rfcfg.txantmask &= buf[1] & 15;
+ if(buf[1] >> 4 & ctlr->rfcfg.rxantmask)
+ ctlr->rfcfg.rxantmask &= buf[1] >> 4;
+ ctlr->fw->physku &= 0xff00ffffUL;
+ ctlr->fw->physku |= ctlr->rfcfg.txantmask << 16;
+ ctlr->fw->physku |= ctlr->rfcfg.rxantmask << 20;
+
	if(ctlr->family >= 8000){
- if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen){
+ if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen ||
!validea(ea)){
			u32int a0, a1;

			if((err = niclock(ctlr)) != nil)
@@ -2270,12 +2289,23 @@
			ea[3] = a0 >> 0;
			ea[4] = a1 >> 8;
			ea[5] = a1 >> 0;
- }
- } else {
- readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1);
+ }
+ }else{
+ /* reading 6 bytes from 0x15 seems to cause an ADVANCED_SYSASSERT.  */
+ if(readnvmsect(ctlr, 0, buf, 8, 0x14<<1) != 8)
+ return "can't read ea from nvm";
+
+ /* byte order is 16 bit little endian.  */
+ 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);

+ ctlr->nvm.read = 1;
	return nil;
 }

@@ -2366,7 +2396,7 @@
		p += 2; /* sleep_tx_count */
		p++; /* sleep state flags */

- *p++ = (ctlr->fw->api[0] & (1<<30)) != 0 ? type : 0; /* station_type
*/
+ *p++ = ctlr->fw->api[0] & UcodeApiSta ? type : 0; /* station_type */

		p += 2; /* assoc id */

@@ -2375,7 +2405,7 @@
		put32(p, 1<<0);
		p += 4; /* tfd_queue_mask */

- if(1){
+ if(ctlr->fw->api[0] & UcodeApiSta){
			p += 2; /* rx_ba_window */
			p++; /* sp_length */
			p++; /* uapsd_acs */
@@ -2640,7 +2670,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 +2692,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 +2700,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 +2739,9 @@
	uchar c[4*(3*4)], *p;
	int i;

+ if((ctlr->fw->capa[1] & UcodeCapQuota) == 0)
+ return nil;
+
	i = 0;
	p = c;

@@ -2822,13 +2851,13 @@
	return cmd(ctlr, 210, c, 11*4);
 }

-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*
@@ -2848,6 +2877,9 @@
	char *err;

	if(ctlr->calib.done == 0){
+ if(ctlr->family == 7000)
+ if((err = sendbtcoexadv(ctlr)) != nil)
+ return err;
		if((err = readnvmconfig(ctlr)) != nil)
			return err;
	}
@@ -2897,16 +2929,16 @@

		/* 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);
			return err;
		}
- if((err = sendmccupdate(ctlr, "ZZ")) != nil){
- print("can't disable beacon filter: %s\n", err);
- return err;
- }
+ if(ctlr->fw->capa[0] & UcodeCapLar)
+ if((err = sendmccupdate(ctlr, "ZZ")) != nil)
+ return err;
		if((err = disablebeaconfilter(ctlr)) != nil){
			print("can't disable beacon filter: %s\n", err);
			return err;
@@ -3362,7 +3394,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 +3450,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 +3484,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 +3534,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 +3620,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 +3671,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){
@@ -4283,8 +4324,8 @@
		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)
+ /* unlock 7k family nics as the command is done */
+ if(ctlr->family == 7000 && qid == 4 && tx->n == 0)
				nicunlock(ctlr);
		}
	}
@@ -4354,14 +4395,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;

@@ -4399,9 +4438,10 @@
		case 0x08b1: /* Wireless AC 7260 */
		case 0x08b2: /* Wireless AC 7260 */
			family = 7000;
- fwname = nil;
+ fwname = "iwm-7260-17";
			break;
		case 0x24f3: /* Wireless AC 8260 */
+ case 0x24f4: /* Wireless AC 8260 */
			family = 8000;
			fwname = "iwm-8000C-34";
			break;


Sat Sep 18 19:39:20 EDT 2021
diff 8f4842d3465e96d264f5c2f7fa2d61db871aae9f 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,27 @@
	SchedTransTblOff = 0x7E0, // +q*2
 };

+/*
+ * uCode capabilities
+ */
 enum {
+ /* flags */
+ UcodeFlgDwBc = 1<<4,
+
+ /* api[0] */
+ UcodeApiSta = 1<<30,
+
+ /* capa[0] */
+ UcodeCapLar = 1<<1,
+
+ /* capa[1] */
+ UcodeCapQuota = 1<<12,
+
+ /* capa[2] */
+ UcodeCapLar2 = 1<<9,
+};
+
+enum {
	FilterPromisc = 1<<0,
	FilterCtl = 1<<1,
	FilterMulticast = 1<<2,
@@ -418,6 +438,7 @@
	uint build;
	char descr[64+1];

+ u32int flags;
	u32int capa[4];
	u32int api[4];

@@ -565,7 +586,6 @@
		uchar type;
		uchar step;
		uchar dash;
- uchar pnum;
		uchar txantmask;
		uchar rxantmask;
	} rfcfg;
@@ -586,7 +606,7 @@
	} eeprom;

	struct {
- u32int version;
+ int read;

		void *buf;
		int len;
@@ -635,8 +655,7 @@
	Type2030 = 12,
	Type2000 = 16,

- Type7260 = 30,
- Type8265 = 35,
+ Type7260 = 20,
 };

 static struct ratetab {
@@ -690,7 +709,6 @@
	[Type6005] "iwn-6005", /* see in iwlattach() below */
	[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);
@@ -728,10 +746,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 +964,7 @@
		for(j=0; j<100; j++){
			if(csr32r(ctlr, Cfg) & EepromLocked)
				return 0;
- delay(10);
+ microdelay(10);
		}
	}
	return "eepromlock: timeout";
@@ -969,7 +989,7 @@
			w = csr32r(ctlr, EepromIo);
			if(w & 1)
				break;
- delay(5);
+ microdelay(5);
		}
		if(i == 10)
			return "eepromread: timeout";
@@ -990,34 +1010,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 +1056,7 @@
	for(i=0; i<2500; i++){
		if(csr32r(ctlr, Gpc) & MacClockReady)
			return 0;
- delay(10);
+ microdelay(10);
	}
	return "clockwait: timeout";
 }
@@ -1046,7 +1067,6 @@
	int capoff;
	char *err;

-
	if(ctlr->family >= 7000){
		/* Reset entire device */
		csr32w(ctlr, Reset, (1<<7));
@@ -1100,7 +1120,6 @@

		prphread(ctlr, OscClk);
		prphread(ctlr, OscClk);
- delay(20);

		prphwrite(ctlr, OscClk, prphread(ctlr, OscClk) | OscClkCtrl);

@@ -1119,7 +1138,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 +1177,7 @@
			for(j = 0; j < 200; j++){
				if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
					break;
- delay(10);
+ microdelay(20);
			}
		}
		nicunlock(ctlr);
@@ -1168,17 +1187,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 +1209,7 @@
			prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
			nicunlock(ctlr);
		}
- delay(5);
+ microdelay(5);
	}

	if(ctlr->family >= 7000){
@@ -1206,12 +1225,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 +1258,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,7 +1327,7 @@
		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 && fwname[ctlr->type] == nil){
			print("iwl: unsupported controller type %d\n",
			ctlr->type);
			return -1;
		}
@@ -1478,6 +1497,11 @@
				s = &i->boot.text;
				s->addr = 0x00000000;
				goto Sect;
+ case 18:
+ if(l < 4)
+ goto Tooshort;
+ i->flags = get32(p);
+ break;
			case 19:
				if(i->main.nsect >= nelem(i->main.sect))
					return "too many main sections";
@@ -1984,7 +2008,7 @@
	*p++ = mcc[0];
	*p++ = 0;
	*p++ = 0; // reserved
- if(1){
+ if(ctlr->fw->capa[2] & UcodeCapLar2){
		p += 4;
		p += 5*4;
	}
@@ -2217,45 +2241,40 @@
	return o;
 }

+static int
+validea(uchar *ea)
+{
+ static uchar reservedea[] = {0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00},
zeros[Eaddrlen];
+
+ if(ea[0] & 1 ||
+ memcmp(ea, reservedea, Eaddrlen) == 0 ||
+ memcmp(ea, zeros, Eaddrlen) == 0)
+ return 0;
+ return 1;
+}
+
 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";
+ if(ctlr->nvm.read)
+ return nil;

- 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(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(readnvmsect(ctlr, ctlr->family >= 8000 ? 12 : 1, buf, 2, 0x01<<1)
!= 2)
+ return "can't read antenna data from nvm";
+ if(buf[1] & 15 & ctlr->rfcfg.txantmask)
+ ctlr->rfcfg.txantmask &= buf[1] & 15;
+ if(buf[1] >> 4 & ctlr->rfcfg.rxantmask)
+ ctlr->rfcfg.rxantmask &= buf[1] >> 4;
+ ctlr->fw->physku &= 0xff00ffffUL;
+ ctlr->fw->physku |= ctlr->rfcfg.txantmask << 16;
+ ctlr->fw->physku |= ctlr->rfcfg.rxantmask << 20;
+
	if(ctlr->family >= 8000){
- if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen){
+ if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen ||
!validea(ea)){
			u32int a0, a1;

			if((err = niclock(ctlr)) != nil)
@@ -2270,12 +2289,23 @@
			ea[3] = a0 >> 0;
			ea[4] = a1 >> 8;
			ea[5] = a1 >> 0;
- }
- } else {
- readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1);
+ }
+ }else{
+ /* reading 6 bytes from 0x15 seems to cause an ADVANCED_SYSASSERT.  */
+ if(readnvmsect(ctlr, 0, buf, 8, 0x14<<1) != 8)
+ return "can't read ea from nvm";
+
+ /* byte order is 16 bit little endian.  */
+ 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);

+ ctlr->nvm.read = 1;
	return nil;
 }

@@ -2366,7 +2396,7 @@
		p += 2; /* sleep_tx_count */
		p++; /* sleep state flags */

- *p++ = (ctlr->fw->api[0] & (1<<30)) != 0 ? type : 0; /* station_type
*/
+ *p++ = ctlr->fw->api[0] & UcodeApiSta ? type : 0; /* station_type */

		p += 2; /* assoc id */

@@ -2375,7 +2405,7 @@
		put32(p, 1<<0);
		p += 4; /* tfd_queue_mask */

- if(1){
+ if(ctlr->fw->api[0] & UcodeApiSta){
			p += 2; /* rx_ba_window */
			p++; /* sp_length */
			p++; /* uapsd_acs */
@@ -2640,7 +2670,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 +2692,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 +2700,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 +2739,9 @@
	uchar c[4*(3*4)], *p;
	int i;

+ if((ctlr->fw->capa[1] & UcodeCapQuota) == 0)
+ return nil;
+
	i = 0;
	p = c;

@@ -2822,13 +2851,13 @@
	return cmd(ctlr, 210, c, 11*4);
 }

-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*
@@ -2848,6 +2877,9 @@
	char *err;

	if(ctlr->calib.done == 0){
+ if(ctlr->family == 7000)
+ if((err = sendbtcoexadv(ctlr)) != nil)
+ return err;
		if((err = readnvmconfig(ctlr)) != nil)
			return err;
	}
@@ -2897,16 +2929,16 @@

		/* 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);
			return err;
		}
- if((err = sendmccupdate(ctlr, "ZZ")) != nil){
- print("can't disable beacon filter: %s\n", err);
- return err;
- }
+ if(ctlr->fw->capa[0] & UcodeCapLar)
+ if((err = sendmccupdate(ctlr, "ZZ")) != nil)
+ return err;
		if((err = disablebeaconfilter(ctlr)) != nil){
			print("can't disable beacon filter: %s\n", err);
			return err;
@@ -3121,7 +3153,7 @@
			f = 4;
		else {
			static char qid2fifo[] = {
- 3, 2, 1, 0, 7, 5, 6,
+ 3, 2, 1, 7, 4, 5, 6,
			};
			f = qid2fifo[i];
		}
@@ -3362,7 +3394,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 +3450,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 +3484,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 +3534,12 @@

	coherence();

+ 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 +3619,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 +3670,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){
@@ -4283,8 +4323,8 @@
		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)
+ /* unlock 7k family nics as the command is done */
+ if(ctlr->family == 7000 && qid == 4 && tx->n == 0)
				nicunlock(ctlr);
		}
	}
@@ -4354,14 +4394,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;

@@ -4399,9 +4437,10 @@
		case 0x08b1: /* Wireless AC 7260 */
		case 0x08b2: /* Wireless AC 7260 */
			family = 7000;
- fwname = nil;
+ fwname = "iwm-7260-17";
			break;
		case 0x24f3: /* Wireless AC 8260 */
+ case 0x24f4: /* Wireless AC 8260 */
			family = 8000;
			fwname = "iwm-8000C-34";
			break;


Sat Sep 18 19:38:34 EDT 2021
diff 8f4842d3465e96d264f5c2f7fa2d61db871aae9f 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,27 @@
	SchedTransTblOff = 0x7E0, // +q*2
 };

+/*
+ * uCode capabilities
+ */
 enum {
+ /* flags */
+ UcodeFlgDwBc = 1<<4,
+
+ /* api[0] */
+ UcodeApiSta = 1<<30,
+
+ /* capa[0] */
+ UcodeCapLar = 1<<1,
+
+ /* capa[1] */
+ UcodeCapQuota = 1<<12,
+
+ /* capa[2] */
+ UcodeCapLar2 = 1<<9,
+};
+
+enum {
	FilterPromisc = 1<<0,
	FilterCtl = 1<<1,
	FilterMulticast = 1<<2,
@@ -418,6 +438,7 @@
	uint build;
	char descr[64+1];

+ u32int flags;
	u32int capa[4];
	u32int api[4];

@@ -565,7 +586,6 @@
		uchar type;
		uchar step;
		uchar dash;
- uchar pnum;
		uchar txantmask;
		uchar rxantmask;
	} rfcfg;
@@ -586,7 +606,7 @@
	} eeprom;

	struct {
- u32int version;
+ int read;

		void *buf;
		int len;
@@ -635,8 +655,7 @@
	Type2030 = 12,
	Type2000 = 16,

- Type7260 = 30,
- Type8265 = 35,
+ Type7260 = 20,
 };

 static struct ratetab {
@@ -690,7 +709,6 @@
	[Type6005] "iwn-6005", /* see in iwlattach() below */
	[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);
@@ -728,10 +746,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 +964,7 @@
		for(j=0; j<100; j++){
			if(csr32r(ctlr, Cfg) & EepromLocked)
				return 0;
- delay(10);
+ microdelay(10);
		}
	}
	return "eepromlock: timeout";
@@ -969,7 +989,7 @@
			w = csr32r(ctlr, EepromIo);
			if(w & 1)
				break;
- delay(5);
+ microdelay(5);
		}
		if(i == 10)
			return "eepromread: timeout";
@@ -990,34 +1010,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 +1056,7 @@
	for(i=0; i<2500; i++){
		if(csr32r(ctlr, Gpc) & MacClockReady)
			return 0;
- delay(10);
+ microdelay(10);
	}
	return "clockwait: timeout";
 }
@@ -1046,7 +1067,6 @@
	int capoff;
	char *err;

-
	if(ctlr->family >= 7000){
		/* Reset entire device */
		csr32w(ctlr, Reset, (1<<7));
@@ -1100,7 +1120,6 @@

		prphread(ctlr, OscClk);
		prphread(ctlr, OscClk);
- delay(20);

		prphwrite(ctlr, OscClk, prphread(ctlr, OscClk) | OscClkCtrl);

@@ -1119,7 +1138,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 +1177,7 @@
			for(j = 0; j < 200; j++){
				if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
					break;
- delay(10);
+ microdelay(20);
			}
		}
		nicunlock(ctlr);
@@ -1168,17 +1187,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 +1209,7 @@
			prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
			nicunlock(ctlr);
		}
- delay(5);
+ microdelay(5);
	}

	if(ctlr->family >= 7000){
@@ -1206,12 +1225,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 +1258,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,7 +1327,7 @@
		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 && fwname[ctlr->type] == nil){
			print("iwl: unsupported controller type %d\n",
			ctlr->type);
			return -1;
		}
@@ -1478,6 +1497,11 @@
				s = &i->boot.text;
				s->addr = 0x00000000;
				goto Sect;
+ case 18:
+ if(l < 4)
+ goto Tooshort;
+ i->flags = get32(p);
+ break;
			case 19:
				if(i->main.nsect >= nelem(i->main.sect))
					return "too many main sections";
@@ -1984,7 +2008,7 @@
	*p++ = mcc[0];
	*p++ = 0;
	*p++ = 0; // reserved
- if(1){
+ if(ctlr->fw->capa[2] & UcodeCapLar2){
		p += 4;
		p += 5*4;
	}
@@ -2217,45 +2241,40 @@
	return o;
 }

+static int
+validea(uchar *ea)
+{
+ static uchar reservedea[] = {0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00},
zeros[Eaddrlen];
+
+ if(ea[0] & 1 ||
+ memcmp(ea, reservedea, Eaddrlen) == 0 ||
+ memcmp(ea, zeros, Eaddrlen) == 0)
+ return 0;
+ return 1;
+}
+
 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";
+ if(ctlr->nvm.read)
+ return nil;

- 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(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(readnvmsect(ctlr, ctlr->family >= 8000 ? 12 : 1, buf, 2, 0x01<<1)
!= 2)
+ return "can't read antenna data from nvm";
+ if(buf[1] & 15 & ctlr->rfcfg.txantmask)
+ ctlr->rfcfg.txantmask &= buf[1] & 15;
+ if(buf[1] >> 4 & ctlr->rfcfg.rxantmask)
+ ctlr->rfcfg.rxantmask &= buf[1] >> 4;
+ ctlr->fw->physku &= 0xff00ffffUL;
+ ctlr->fw->physku |= ctlr->rfcfg.txantmask << 16;
+ ctlr->fw->physku |= ctlr->rfcfg.rxantmask << 20;
+
	if(ctlr->family >= 8000){
- if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen){
+ if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen ||
!validea(ea)){
			u32int a0, a1;

			if((err = niclock(ctlr)) != nil)
@@ -2270,12 +2289,23 @@
			ea[3] = a0 >> 0;
			ea[4] = a1 >> 8;
			ea[5] = a1 >> 0;
- }
- } else {
- readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1);
+ }
+ }else{
+ /* reading 6 bytes from 0x15 seems to cause an ADVANCED_SYSASSERT.  */
+ if(readnvmsect(ctlr, 0, buf, 8, 0x14<<1) != 8)
+ return "can't read ea from nvm";
+
+ /* byte order is 16 bit little endian.  */
+ 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);

+ ctlr->nvm.read = 1;
	return nil;
 }

@@ -2366,7 +2396,7 @@
		p += 2; /* sleep_tx_count */
		p++; /* sleep state flags */

- *p++ = (ctlr->fw->api[0] & (1<<30)) != 0 ? type : 0; /* station_type
*/
+ *p++ = ctlr->fw->api[0] & UcodeApiSta ? type : 0; /* station_type */

		p += 2; /* assoc id */

@@ -2375,7 +2405,7 @@
		put32(p, 1<<0);
		p += 4; /* tfd_queue_mask */

- if(1){
+ if(ctlr->fw->api[0] & UcodeApiSta){
			p += 2; /* rx_ba_window */
			p++; /* sp_length */
			p++; /* uapsd_acs */
@@ -2640,7 +2670,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 +2692,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 +2700,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 +2739,9 @@
	uchar c[4*(3*4)], *p;
	int i;

+ if((ctlr->fw->capa[1] & UcodeCapQuota) == 0)
+ return nil;
+
	i = 0;
	p = c;

@@ -2822,13 +2851,13 @@
	return cmd(ctlr, 210, c, 11*4);
 }

-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*
@@ -2848,6 +2877,9 @@
	char *err;

	if(ctlr->calib.done == 0){
+ if(ctlr->family == 7000)
+ if((err = sendbtcoexadv(ctlr)) != nil)
+ return err;
		if((err = readnvmconfig(ctlr)) != nil)
			return err;
	}
@@ -2897,16 +2929,16 @@

		/* 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);
			return err;
		}
- if((err = sendmccupdate(ctlr, "ZZ")) != nil){
- print("can't disable beacon filter: %s\n", err);
- return err;
- }
+ if(ctlr->fw->capa[0] & UcodeCapLar)
+ if((err = sendmccupdate(ctlr, "ZZ")) != nil)
+ return err;
		if((err = disablebeaconfilter(ctlr)) != nil){
			print("can't disable beacon filter: %s\n", err);
			return err;
@@ -3121,7 +3153,7 @@
			f = 4;
		else {
			static char qid2fifo[] = {
- 3, 2, 1, 0, 7, 5, 6,
+ 3, 2, 1, 7, 4, 5, 6,
			};
			f = qid2fifo[i];
		}
@@ -3362,7 +3394,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 +3450,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 +3484,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 +3534,12 @@

	coherence();

+ 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 +3619,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 +3670,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){
@@ -4281,10 +4321,16 @@
		}
		freeblist(bb);
		if(tx != nil && tx->n > 0){
+ put16(ctlr->sched.s+(qid*320+tx->i)*2, 1);
+ coherence();
+ if(tx->i < 64){
+ put16(ctlr->sched.s+(qid*320+tx->i+256)*2, 1);
+ coherence();
+ }
			tx->n--;
			wakeup(tx);
- /* unlock 7k family nics as all commands are done */
- if(ctlr->family == 7000 && tx->n == 0)
+ /* unlock 7k family nics as the command is done */
+ if(ctlr->family == 7000 && qid == 4 && tx->n == 0)
				nicunlock(ctlr);
		}
	}
@@ -4354,14 +4400,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;

@@ -4399,9 +4443,10 @@
		case 0x08b1: /* Wireless AC 7260 */
		case 0x08b2: /* Wireless AC 7260 */
			family = 7000;
- fwname = nil;
+ fwname = "iwm-7260-17";
			break;
		case 0x24f3: /* Wireless AC 8260 */
+ case 0x24f4: /* Wireless AC 8260 */
			family = 8000;
			fwname = "iwm-8000C-34";
			break;


Sat Sep 18 19:38:13 EDT 2021
diff 8f4842d3465e96d264f5c2f7fa2d61db871aae9f 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,27 @@
	SchedTransTblOff = 0x7E0, // +q*2
 };

+/*
+ * uCode capabilities
+ */
 enum {
+ /* flags */
+ UcodeFlgDwBc = 1<<4,
+
+ /* api[0] */
+ UcodeApiSta = 1<<30,
+
+ /* capa[0] */
+ UcodeCapLar = 1<<1,
+
+ /* capa[1] */
+ UcodeCapQuota = 1<<12,
+
+ /* capa[2] */
+ UcodeCapLar2 = 1<<9,
+};
+
+enum {
	FilterPromisc = 1<<0,
	FilterCtl = 1<<1,
	FilterMulticast = 1<<2,
@@ -418,6 +438,7 @@
	uint build;
	char descr[64+1];

+ u32int flags;
	u32int capa[4];
	u32int api[4];

@@ -565,7 +586,6 @@
		uchar type;
		uchar step;
		uchar dash;
- uchar pnum;
		uchar txantmask;
		uchar rxantmask;
	} rfcfg;
@@ -586,7 +606,7 @@
	} eeprom;

	struct {
- u32int version;
+ int read;

		void *buf;
		int len;
@@ -635,8 +655,7 @@
	Type2030 = 12,
	Type2000 = 16,

- Type7260 = 30,
- Type8265 = 35,
+ Type7260 = 20,
 };

 static struct ratetab {
@@ -690,7 +709,6 @@
	[Type6005] "iwn-6005", /* see in iwlattach() below */
	[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);
@@ -728,10 +746,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 +964,7 @@
		for(j=0; j<100; j++){
			if(csr32r(ctlr, Cfg) & EepromLocked)
				return 0;
- delay(10);
+ microdelay(10);
		}
	}
	return "eepromlock: timeout";
@@ -969,7 +989,7 @@
			w = csr32r(ctlr, EepromIo);
			if(w & 1)
				break;
- delay(5);
+ microdelay(5);
		}
		if(i == 10)
			return "eepromread: timeout";
@@ -990,34 +1010,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 +1056,7 @@
	for(i=0; i<2500; i++){
		if(csr32r(ctlr, Gpc) & MacClockReady)
			return 0;
- delay(10);
+ microdelay(10);
	}
	return "clockwait: timeout";
 }
@@ -1046,7 +1067,6 @@
	int capoff;
	char *err;

-
	if(ctlr->family >= 7000){
		/* Reset entire device */
		csr32w(ctlr, Reset, (1<<7));
@@ -1100,7 +1120,6 @@

		prphread(ctlr, OscClk);
		prphread(ctlr, OscClk);
- delay(20);

		prphwrite(ctlr, OscClk, prphread(ctlr, OscClk) | OscClkCtrl);

@@ -1119,7 +1138,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 +1177,7 @@
			for(j = 0; j < 200; j++){
				if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
					break;
- delay(10);
+ microdelay(20);
			}
		}
		nicunlock(ctlr);
@@ -1168,17 +1187,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 +1209,7 @@
			prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
			nicunlock(ctlr);
		}
- delay(5);
+ microdelay(5);
	}

	if(ctlr->family >= 7000){
@@ -1206,12 +1225,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 +1258,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,7 +1327,7 @@
		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 && fwname[ctlr->type] == nil){
			print("iwl: unsupported controller type %d\n",
			ctlr->type);
			return -1;
		}
@@ -1478,6 +1497,11 @@
				s = &i->boot.text;
				s->addr = 0x00000000;
				goto Sect;
+ case 18:
+ if(l < 4)
+ goto Tooshort;
+ i->flags = get32(p);
+ break;
			case 19:
				if(i->main.nsect >= nelem(i->main.sect))
					return "too many main sections";
@@ -1984,7 +2008,7 @@
	*p++ = mcc[0];
	*p++ = 0;
	*p++ = 0; // reserved
- if(1){
+ if(ctlr->fw->capa[2] & UcodeCapLar2){
		p += 4;
		p += 5*4;
	}
@@ -2217,45 +2241,40 @@
	return o;
 }

+static int
+validea(uchar *ea)
+{
+ static uchar reservedea[] = {0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00},
zeros[Eaddrlen];
+
+ if(ea[0] & 1 ||
+ memcmp(ea, reservedea, Eaddrlen) == 0 ||
+ memcmp(ea, zeros, Eaddrlen) == 0)
+ return 0;
+ return 1;
+}
+
 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";
+ if(ctlr->nvm.read)
+ return nil;

- 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(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(readnvmsect(ctlr, ctlr->family >= 8000 ? 12 : 1, buf, 2, 0x01<<1)
!= 2)
+ return "can't read antenna data from nvm";
+ if(buf[1] & 15 & ctlr->rfcfg.txantmask)
+ ctlr->rfcfg.txantmask &= buf[1] & 15;
+ if(buf[1] >> 4 & ctlr->rfcfg.rxantmask)
+ ctlr->rfcfg.rxantmask &= buf[1] >> 4;
+ ctlr->fw->physku &= 0xff00ffffUL;
+ ctlr->fw->physku |= ctlr->rfcfg.txantmask << 16;
+ ctlr->fw->physku |= ctlr->rfcfg.rxantmask << 20;
+
	if(ctlr->family >= 8000){
- if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen){
+ if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen ||
!validea(ea)){
			u32int a0, a1;

			if((err = niclock(ctlr)) != nil)
@@ -2270,12 +2289,23 @@
			ea[3] = a0 >> 0;
			ea[4] = a1 >> 8;
			ea[5] = a1 >> 0;
- }
- } else {
- readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1);
+ }
+ }else{
+ /* reading 6 bytes from 0x15 seems to cause an ADVANCED_SYSASSERT.  */
+ if(readnvmsect(ctlr, 0, buf, 8, 0x14<<1) != 8)
+ return "can't read ea from nvm";
+
+ /* byte order is 16 bit little endian.  */
+ 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);

+ ctlr->nvm.read = 1;
	return nil;
 }

@@ -2366,7 +2396,7 @@
		p += 2; /* sleep_tx_count */
		p++; /* sleep state flags */

- *p++ = (ctlr->fw->api[0] & (1<<30)) != 0 ? type : 0; /* station_type
*/
+ *p++ = ctlr->fw->api[0] & UcodeApiSta ? type : 0; /* station_type */

		p += 2; /* assoc id */

@@ -2375,7 +2405,7 @@
		put32(p, 1<<0);
		p += 4; /* tfd_queue_mask */

- if(1){
+ if(ctlr->fw->api[0] & UcodeApiSta){
			p += 2; /* rx_ba_window */
			p++; /* sp_length */
			p++; /* uapsd_acs */
@@ -2640,7 +2670,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 +2692,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 +2700,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 +2739,9 @@
	uchar c[4*(3*4)], *p;
	int i;

+ if((ctlr->fw->capa[1] & UcodeCapQuota) == 0)
+ return nil;
+
	i = 0;
	p = c;

@@ -2822,13 +2851,13 @@
	return cmd(ctlr, 210, c, 11*4);
 }

-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*
@@ -2848,6 +2877,9 @@
	char *err;

	if(ctlr->calib.done == 0){
+ if(ctlr->family == 7000)
+ if((err = sendbtcoexadv(ctlr)) != nil)
+ return err;
		if((err = readnvmconfig(ctlr)) != nil)
			return err;
	}
@@ -2897,16 +2929,16 @@

		/* 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);
			return err;
		}
- if((err = sendmccupdate(ctlr, "ZZ")) != nil){
- print("can't disable beacon filter: %s\n", err);
- return err;
- }
+ if(ctlr->fw->capa[0] & UcodeCapLar)
+ if((err = sendmccupdate(ctlr, "ZZ")) != nil)
+ return err;
		if((err = disablebeaconfilter(ctlr)) != nil){
			print("can't disable beacon filter: %s\n", err);
			return err;
@@ -3121,7 +3153,7 @@
			f = 4;
		else {
			static char qid2fifo[] = {
- 3, 2, 1, 0, 7, 5, 6,
+ 3, 2, 1, 7, 4, 5, 6,
			};
			f = qid2fifo[i];
		}
@@ -3362,7 +3394,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,7 +3450,8 @@
 static char*
 qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
 {
- int hdrlen;
+ char *err;
+ int hdrlen, val;
	Block *bcmd;
	uchar *d, *c;
	TXQ *q;
@@ -3451,12 +3484,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 +3534,12 @@

	coherence();

+ 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 +3619,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 +3670,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){
@@ -4281,10 +4321,16 @@
		}
		freeblist(bb);
		if(tx != nil && tx->n > 0){
+ put16(ctlr->sched.s+(qid*320+tx->i)*2, 1);
+ coherence();
+ if(tx->i < 64){
+ put16(ctlr->sched.s+(qid*320+tx->i+256)*2, 1);
+ coherence();
+ }
			tx->n--;
			wakeup(tx);
- /* unlock 7k family nics as all commands are done */
- if(ctlr->family == 7000 && tx->n == 0)
+ /* unlock 7k family nics as the command is done */
+ if(ctlr->family == 7000 && qid == 4 && tx->n == 0)
				nicunlock(ctlr);
		}
	}
@@ -4354,14 +4400,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;

@@ -4399,9 +4443,10 @@
		case 0x08b1: /* Wireless AC 7260 */
		case 0x08b2: /* Wireless AC 7260 */
			family = 7000;
- fwname = nil;
+ fwname = "iwm-7260-17";
			break;
		case 0x24f3: /* Wireless AC 8260 */
+ case 0x24f4: /* Wireless AC 8260 */
			family = 8000;
			fwname = "iwm-8000C-34";
			break;


Sat Sep 18 18:36:35 EDT 2021
diff 8f4842d3465e96d264f5c2f7fa2d61db871aae9f 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,27 @@
	SchedTransTblOff = 0x7E0, // +q*2
 };

+/*
+ * uCode capabilities
+ */
 enum {
+ /* flags */
+ UcodeFlgDwBc = 1<<4,
+
+ /* api[0] */
+ UcodeApiSta = 1<<30,
+
+ /* capa[0] */
+ UcodeCapLar = 1<<1,
+
+ /* capa[1] */
+ UcodeCapQuota = 1<<12,
+
+ /* capa[2] */
+ UcodeCapLar2 = 1<<9,
+};
+
+enum {
	FilterPromisc = 1<<0,
	FilterCtl = 1<<1,
	FilterMulticast = 1<<2,
@@ -418,6 +438,7 @@
	uint build;
	char descr[64+1];

+ u32int flags;
	u32int capa[4];
	u32int api[4];

@@ -565,7 +586,6 @@
		uchar type;
		uchar step;
		uchar dash;
- uchar pnum;
		uchar txantmask;
		uchar rxantmask;
	} rfcfg;
@@ -586,7 +606,7 @@
	} eeprom;

	struct {
- u32int version;
+ int read;

		void *buf;
		int len;
@@ -635,8 +655,7 @@
	Type2030 = 12,
	Type2000 = 16,

- Type7260 = 30,
- Type8265 = 35,
+ Type7260 = 20,
 };

 static struct ratetab {
@@ -690,7 +709,6 @@
	[Type6005] "iwn-6005", /* see in iwlattach() below */
	[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);
@@ -728,10 +746,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 +964,7 @@
		for(j=0; j<100; j++){
			if(csr32r(ctlr, Cfg) & EepromLocked)
				return 0;
- delay(10);
+ microdelay(10);
		}
	}
	return "eepromlock: timeout";
@@ -969,7 +989,7 @@
			w = csr32r(ctlr, EepromIo);
			if(w & 1)
				break;
- delay(5);
+ microdelay(5);
		}
		if(i == 10)
			return "eepromread: timeout";
@@ -990,34 +1010,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 +1056,7 @@
	for(i=0; i<2500; i++){
		if(csr32r(ctlr, Gpc) & MacClockReady)
			return 0;
- delay(10);
+ microdelay(10);
	}
	return "clockwait: timeout";
 }
@@ -1046,7 +1067,6 @@
	int capoff;
	char *err;

-
	if(ctlr->family >= 7000){
		/* Reset entire device */
		csr32w(ctlr, Reset, (1<<7));
@@ -1100,7 +1120,6 @@

		prphread(ctlr, OscClk);
		prphread(ctlr, OscClk);
- delay(20);

		prphwrite(ctlr, OscClk, prphread(ctlr, OscClk) | OscClkCtrl);

@@ -1119,7 +1138,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 +1177,7 @@
			for(j = 0; j < 200; j++){
				if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
					break;
- delay(10);
+ microdelay(20);
			}
		}
		nicunlock(ctlr);
@@ -1168,17 +1187,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 +1209,7 @@
			prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
			nicunlock(ctlr);
		}
- delay(5);
+ microdelay(5);
	}

	if(ctlr->family >= 7000){
@@ -1206,12 +1225,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 +1258,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,7 +1327,7 @@
		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 && fwname[ctlr->type] == nil){
			print("iwl: unsupported controller type %d\n",
			ctlr->type);
			return -1;
		}
@@ -1478,6 +1497,11 @@
				s = &i->boot.text;
				s->addr = 0x00000000;
				goto Sect;
+ case 18:
+ if(l < 4)
+ goto Tooshort;
+ i->flags = get32(p);
+ break;
			case 19:
				if(i->main.nsect >= nelem(i->main.sect))
					return "too many main sections";
@@ -1984,7 +2008,7 @@
	*p++ = mcc[0];
	*p++ = 0;
	*p++ = 0; // reserved
- if(1){
+ if(ctlr->fw->capa[2] & UcodeCapLar2){
		p += 4;
		p += 5*4;
	}
@@ -2217,45 +2241,40 @@
	return o;
 }

+static int
+validea(uchar *ea)
+{
+ static uchar reservedea[] = {0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00},
zeros[Eaddrlen];
+
+ if(ea[0] & 1 ||
+ memcmp(ea, reservedea, Eaddrlen) == 0 ||
+ memcmp(ea, zeros, Eaddrlen) == 0)
+ return 0;
+ return 1;
+}
+
 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";
+ if(ctlr->nvm.read)
+ return nil;

- 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(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(readnvmsect(ctlr, ctlr->family >= 8000 ? 12 : 1, buf, 2, 0x01<<1)
!= 2)
+ return "can't read antenna data from nvm";
+ if(buf[1] & 15 & ctlr->rfcfg.txantmask)
+ ctlr->rfcfg.txantmask &= buf[1] & 15;
+ if(buf[1] >> 4 & ctlr->rfcfg.rxantmask)
+ ctlr->rfcfg.rxantmask &= buf[1] >> 4;
+ ctlr->fw->physku &= 0xff00ffffUL;
+ ctlr->fw->physku |= ctlr->rfcfg.txantmask << 16;
+ ctlr->fw->physku |= ctlr->rfcfg.rxantmask << 20;
+
	if(ctlr->family >= 8000){
- if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen){
+ if(readnvmsect(ctlr, 11, ea, Eaddrlen, 0x01<<1) != Eaddrlen ||
!validea(ea)){
			u32int a0, a1;

			if((err = niclock(ctlr)) != nil)
@@ -2270,12 +2289,23 @@
			ea[3] = a0 >> 0;
			ea[4] = a1 >> 8;
			ea[5] = a1 >> 0;
- }
- } else {
- readnvmsect(ctlr, 0, ea, Eaddrlen, 0x15<<1);
+ }
+ }else{
+ /* reading 6 bytes from 0x15 seems to cause an ADVANCED_SYSASSERT.  */
+ if(readnvmsect(ctlr, 0, buf, 8, 0x14<<1) != 8)
+ return "can't read ea from nvm";
+
+ /* byte order is 16 bit little endian.  */
+ 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);

+ ctlr->nvm.read = 1;
	return nil;
 }

@@ -2366,7 +2396,7 @@
		p += 2; /* sleep_tx_count */
		p++; /* sleep state flags */

- *p++ = (ctlr->fw->api[0] & (1<<30)) != 0 ? type : 0; /* station_type
*/
+ *p++ = ctlr->fw->api[0] & UcodeApiSta ? type : 0; /* station_type */

		p += 2; /* assoc id */

@@ -2375,7 +2405,7 @@
		put32(p, 1<<0);
		p += 4; /* tfd_queue_mask */

- if(1){
+ if(ctlr->fw->api[0] & UcodeApiSta){
			p += 2; /* rx_ba_window */
			p++; /* sp_length */
			p++; /* uapsd_acs */
@@ -2640,7 +2670,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 +2692,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 +2700,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 +2739,9 @@
	uchar c[4*(3*4)], *p;
	int i;

+ if((ctlr->fw->capa[1] & UcodeCapQuota) == 0)
+ return nil;
+
	i = 0;
	p = c;

@@ -2822,13 +2851,13 @@
	return cmd(ctlr, 210, c, 11*4);
 }

-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*
@@ -2848,6 +2877,9 @@
	char *err;

	if(ctlr->calib.done == 0){
+ if(ctlr->family == 7000)
+ if((err = sendbtcoexadv(ctlr)) != nil)
+ return err;
		if((err = readnvmconfig(ctlr)) != nil)
			return err;
	}
@@ -2897,16 +2929,16 @@

		/* 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);
			return err;
		}
- if((err = sendmccupdate(ctlr, "ZZ")) != nil){
- print("can't disable beacon filter: %s\n", err);
- return err;
- }
+ if(ctlr->fw->capa[0] & UcodeCapLar)
+ if((err = sendmccupdate(ctlr, "ZZ")) != nil)
+ return err;
		if((err = disablebeaconfilter(ctlr)) != nil){
			print("can't disable beacon filter: %s\n", err);
			return err;
@@ -3121,7 +3153,7 @@
			f = 4;
		else {
			static char qid2fifo[] = {
- 3, 2, 1, 0, 7, 5, 6,
+ 3, 2, 1, 7, 4, 5, 6,
			};
			f = qid2fifo[i];
		}
@@ -3362,7 +3394,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,7 +3450,8 @@
 static char*
 qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
 {
- int hdrlen;
+ char *err;
+ int hdrlen, val;
	Block *bcmd;
	uchar *d, *c;
	TXQ *q;
@@ -3452,10 +3485,10 @@
		return "qcmd: broken";
	}
	/* wake up the nic (just needed for 7k) */
- if(ctlr->family == 7000 && q->n == 0)
- if(niclock(ctlr) != nil){
+ if(ctlr->family == 7000 && qid == 4 && q->n == 0)
+ if((err = niclock(ctlr)) != nil){
			iunlock(ctlr);
- return "qcmd: busy";
+ return err;
		}
	q->n++;
	q->lastcmd = code;
@@ -3507,6 +3540,20 @@

	coherence();

+ /* update scheduler */
+ if(code == 28){
+ val = BLEN(block) + 8;
+ if(ctlr->fw->flags & UcodeFlgDwBc)
+ val = HOWMANY(val, 4);
+ }else
+ val = 0;
+ put16(ctlr->sched.s+(qid*320+q->i)*2, val);
+ coherence();
+ if(q->i < 64){
+ put16(ctlr->sched.s+(qid*320+q->i+256)*2, val);
+ coherence();
+ }
+
	q->i = (q->i+1) % Ntx;
	csr32w(ctlr, HbusTargWptr, (qid<<8) | q->i);

@@ -3586,9 +3633,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 +3684,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){
@@ -4281,10 +4335,16 @@
		}
		freeblist(bb);
		if(tx != nil && tx->n > 0){
+ put16(ctlr->sched.s+(qid*320+tx->i)*2, 1);
+ coherence();
+ if(tx->i < 64){
+ put16(ctlr->sched.s+(qid*320+tx->i+256)*2, 1);
+ coherence();
+ }
			tx->n--;
			wakeup(tx);
- /* unlock 7k family nics as all commands are done */
- if(ctlr->family == 7000 && tx->n == 0)
+ /* unlock 7k family nics as the command is done */
+ if(ctlr->family == 7000 && qid == 4 && tx->n == 0)
				nicunlock(ctlr);
		}
	}
@@ -4354,14 +4414,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;

@@ -4399,9 +4457,10 @@
		case 0x08b1: /* Wireless AC 7260 */
		case 0x08b2: /* Wireless AC 7260 */
			family = 7000;
- fwname = nil;
+ fwname = "iwm-7260-17";
			break;
		case 0x24f3: /* Wireless AC 8260 */
+ case 0x24f4: /* Wireless AC 8260 */
			family = 8000;
			fwname = "iwm-8000C-34";
			break;


Sat Sep 18 11:29:37 EDT 2021
/*
	 * Universal Startup Algorithm.
	 */
	p = KADDR(0x467); /* warm-reset vector */
	*p++ = PADDR(APBOOTSTRAP);
	*p++ = PADDR(APBOOTSTRAP)>>8;
	i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
	/* code assumes i==0 */
	if(i != 0)
		print("mp: bad APBOOTSTRAP\n");
	*p++ = i;
	*p = i>>8;
	coherence();


Sat Sep 18 01:54:52 EDT 2021
: ~ ; d disklabel -Ev sd2
Treating sectors 256-4294852800 as the OpenBSD portion of the disk.
You can use the 'b' command to change this.

Label editor (enter '?' for help at any prompt)
sd2> ?
Available commands:
 ? | h - show help n [part] - set mount point
 A - auto partition all space p [unit] - print partitions
 a [part] - add partition q - quit & save changes
 b - set OpenBSD boundaries R [part] - resize auto allocated partition
 c [part] - change partition size r - display free space
 D - reset label to default s [path] - save label to file
 d [part] - delete partition U - undo all changes
 e - edit drive parameters u - undo last change
 g [d|u] - [d]isk or [u]ser geometry w - write label to disk
 i - modify disklabel UID X - toggle expert mode
 l [unit] - print disk label header x - exit & lose changes
 M - disklabel(8) man page z - delete all partitions
 m [part] - modify partition

Suffixes can be used to indicate units other than sectors:
 'b' (bytes), 'k' (kilobytes), 'm' (megabytes), 'g' (gigabytes) 't' (terabytes)
 'c' (cylinders), '%' (% of total disk), '&' (% of free space).
Values in non-sector units are truncated to the nearest cylinder boundary.
sd2> p
OpenBSD area: 256-4294852800; size: 4294852544; free: 4294852544
# size offset fstype [fsize bsize cpg]
  c: 11721045168 0 unused
sd2> a
partition: [a]
offset: [256]
size: [4294852544] 100%
FS type: [4.2BSD]
sd2*> p
OpenBSD area: 256-4294852800; size: 4294852544; free: 64
# size offset fstype [fsize bsize cpg]
  a: 4294852480 256 4.2BSD 8192 65536 1
  c: 11721045168 0 unused


Sat Sep 18 01:52:09 EDT 2021
: ~ ; d fdisk sd2
Disk: sd2 geometry: 32960/511/255 [4294852800 Sectors]
Offset: 0 Signature: 0xAA55
	    Starting Ending LBA Info:
 #: id C H S - C H S [ start: size ]
-------------------------------------------------------------------------------
 0: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused
 1: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused
 2: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused
*3: A6 0 1 2 - 32959 510 255 [ 256: 4294852544 ] OpenBSD


Sat Sep 18 00:00:56 EDT 2021
#!/bin/rc -e
rfork en
ramfs
cd /usr/git/plan9front/plan9front

prev=`{cat prev}
head=`{git/query HEAD}
for(c in `{git/query $prev^'..'^$head})
	git/export $c | \
		sed 's/^From: .*/From: commits@git.9front.org/' | \
		mail 9front-commits@9front.org
echo $head > prev


Fri Sep 17 17:54:05 EDT 2021
% cd '#ec'; for(i in *){echo $i '=' `{cat $i}}
*acpi =
*bootscreen = 1280x800x32 x8r8g8b8 0xd0000000 67108864
*e820 = 1 0x0000000000000000 0x000000000009e800 2 0x000000000009e800
0x00000000000a0000 2 0x00000000000d2000 0x00000000000d4000 2 0x00000000000dc000
0x0000000000100000 1 0x0000000000100000 0x00000000bb27c000 2 0x00000000bb27c000
0x00000000bb282000 1 0x00000000bb282000 0x00000000bb35f000 2 0x00000000bb35f000
0x00000000bb371000 4 0x00000000bb371000 0x00000000bb3f2000 2 0x00000000bb3f2000
0x00000000bb40f000 1 0x00000000bb40f000 0x00000000bb46f000 2 0x00000000bb46f000
0x00000000bb668000 4 0x00000000bb668000 0x00000000bb6e8000 2 0x00000000bb6e8000
0x00000000bb70f000 1 0x00000000bb70f000 0x00000000bb717000 2 0x00000000bb717000
0x00000000bb71f000 1 0x00000000bb71f000 0x00000000bb76b000 4 0x00000000bb76b000
0x00000000bb777000 3 0x00000000bb777000 0x00000000bb77a000 4 0x00000000bb77a000
0x00000000bb781000 3 0x00000000bb781000 0x00000000bb782000 4 0x00000000bb782000
0x00000000bb78b000 3 0x00000000bb78b000 0x00000000bb78c000 4 0x00000000bb78c000
0x00000000bb79f000 3 0x00000000bb79f000 0x00000000bb7ff000 1 0x00000000bb7ff000
0x00000000bb800000 2 0x00000000bb800000 0x00000000bc000000 2 0x00000000bc000000
0x00000000c0000000 2 0x00000000e0000000 0x00000000f0000000 2 0x00000000feaff000
0x00000000feb00000 2 0x00000000fec00000 0x00000000fec10000 2 0x00000000fed00000
0x00000000fed00400 2 0x00000000fed1c000 0x00000000fed20000 2 0x00000000fed20000
0x00000000fed90000 2 0x00000000fee00000 0x00000000fee01000 2 0x00000000ff000000
0x0000000100000000 1 0x0000000100000000 0x0000000138000000
bootargs = local!/dev/sdE0/fscache -a tcp!*!564
bootfile = 9pc64
ether0 = type=iwl essid=REDACTED
monitor = vesa
mouseport = ps2intellimouse
nora6 =
service = cpu
sysname =
tiltscreen = none
vgasize = 1280x800x32
wpapsk = REDACTED

% cat '#'P/archctl
cpu PentiumIII/Xeon 2661 pge
pge on
coherence mfence
cmpswap cmpswap486
arch _MP_
cache 0x0000000000000000 655360 wb
cache 0x00000000000a0000 131072 uc
cache 0x00000000000c0000 81920 wp
cache 0x00000000000d4000 32768 uc
cache 0x00000000000dc000 147456 wp
cache 0x0000000000100000 3153068032 wb
cache 0x00000000bc000000 1140850688 uc
cache 0x0000000100000000 939524096 wb
cache 0x0000000138000000 63484985344 uc

% cat '#'P/irqalloc
	  1 -1 debugexc
	  2 -1 nmi
	  3 -1 debugpt
	  7 -1 mathemu
	  8 -1 doublefault
	  9 -1 mathover
	 14 -1 faultamd64
	 15 -1 unexpected
	 16 -1 matherror
	 19 -1 simderror
	 50 18 clock
	 51 19 lapicerror
	 63 31 lapicspurious
	 65 11 ether0
	 73 11 ether1
	 81 1 kbd
	 89 11 hda
	 97 11 ehci
	 97 11 ehci
	105 11 sdE (ahci)
	113 11 mmc
	121 12 kbdaux

% cat '#'P/ioalloc
      20 21 i8259.0
      40 43 i8253
      60 60 i8042.data
      61 61 i8253.cntr2c
      64 64 i8042.cs
      70 71 rtc/nvr
      a0 a1 i8259.1
     2b0 2df vga
     3c0 3da vga
     cf8 cfb pcicfg.addr
     cfc cff pcicfg.data
     fff fff dummy
    1800 1807 PCI.0.2.0
    1810 1813 PCI.0.31.2
    1814 1817 PCI.0.31.2
    1818 181f PCI.0.31.2
    1820 183f PCI.0.25.0
    1840 185f PCI.0.31.2
    1860 1867 PCI.0.31.2
    1880 189f PCI.0.31.3

% cat '#'c/config
# pc64 - amd64 pc terminal with local disk
dev
	root
	cons
	swap
	arch
	pnp pci
	env
	pipe
	proc
	mnt
	srv
	shr
	dup
	rtc
	ssl
	tls
	cap
	kprof
	fs

	ether netif
	bridge netif log
	ip arp chandial ip ipv6 ipaux iproute netlog ethermedium nullmedium
	pktmedium inferno

	draw screen vga vgax vgasoft
	mouse mouse
	kbd
	vga pci

	sd
# floppy dma
	aoe
# lpt

	audio dma
# pccard
# i82365 cis
	uart
	usb

	segment
	vmx
	dtracy

link
# devpccard pci
# devi82365
	cputemp pci
# ether2000 ether8390
	ether2114x pci
# ether589 etherelnk3
	ether79c970 pci
# ether8003 ether8390
	ether8139 pci
	ether8169 pci ethermii
# should be obsoleted by igbe
# ether82543gc pci
# ether82557 pci
	ether82563 pci
	ether82598 pci
	etherx550 pci
# ether83815 pci
	etherbcm pci
# etherdp83820 pci ethermii
# etherec2t ether8390
# etherelnk3 pci
# etherga620 pci
	etherigbe pci ethermii
# ethervgbe pci ethermii
# ethervt6102 pci ethermii
# ethervt6105m pci ethermii
	ethersink
# ethersmc devi82365 cis
	etheryuk pci
# etherwavelan wavelan devi82365 cis pci
	etheriwl pci wifi
	etherwpi pci wifi
	etherrt2860 pci wifi
	ethervirtio pci
	ethervirtio10 pci
	ethermedium
# pcmciamodem
	netdevmedium
	loopbackmedium
	usbuhci pci
	usbohci pci
	usbehci pci usbehcipc
	usbxhci pci

# audiosb16 dma
# audioac97 pci audioac97mix
	audiohda pci

misc
	pci pcipc
	archgeneric devkbd i8259 i8253
	archacpi mp apic squidboy ec hpet
	archmp mp apic squidboy
	mtrr

	sdaoe
	sdide pci sdscsi
	sd53c8xx pci sdscsi
# sdmylex pci sdscsi
	sdiahci pci sdscsi led
# sdodin pci sdscsi led
	sdvirtio pci sdscsi
	sdvirtio10 pci sdscsi
	sdmmc pci pmmc
	sdnvme pci
	sdloop
	sdram

	uarti8250
	uartisa
	uartpci pci

	vgasoft =cur swcursor
# vga3dfx +cur
# vgaark2000pv +cur
# vgabt485 =cur
# vgaclgd542x +cur
# vgaclgd546x +cur
# vgact65545 +cur
# vgacyber938x +cur
# vgaet4000 +cur
# vgageode +cur
# vgahiqvideo +cur
# vgai81x +cur
	vgaigfx +cur
# vgamach64xx +cur
# vgamga2164w +cur
# vgamga4xx +cur
# vganeomagic +cur
# vganvidia +cur
	vgaradeon +cur
# vgargb524 =cur
# vgas3 +cur vgasavage
# vgat2r4 +cur
# vgatvp3020 =cur
# vgatvp3026 =cur
	vgavesa
# vgavmware +cur

	dtracysys
	dtracytimer

ip
	tcp
	udp
	rudp
	ipifc
	icmp
	icmp6
	gre
	ipmux
	esp
	il

port
	int cpuserver = 0;

bootdir
	/$objtype/bin/paqfs
	/$objtype/bin/auth/factotum
	bootfs.paq
	boot

% cat '#'c/sysstat
	  0 23094319 22084446 11284494 1670675 0 0 14 98 0
	  1 23558170 19839273 11674066 1720558 0 0 0 98 0

% cat '#'¶/swap
4072517632 memory
4096 pagesize
298281 kernel
15143/672309 user
0/160000 swap
3109/672309 reclaim
12193472/12648448/1206078208 kernel malloc
21689720/39231584/1085470388 kernel draw
3136/65568/16777216 kernel secret

% awk /^Plan 9/{p=1} /^init: starting/{exit} {if(p)print} '#'c/kmesg
Plan 9
125 holes free
0x00026000 0x0009e000 491520
0x00100000 0x00110000 65536
0x008bb000 0x4955c000 1221201920
1221758976 bytes free
pcirouting: Cannot find south bridge PCI.255.31.7
cpu0: 2661MHz GenuineIntel PentiumIII/Xeon (AX 00020652 CX 0298E3FF DX BFEBFBFF)
LAPIC: fee00000 0xffffff00fee00000
ELCR: 0800
cpu0: lapic clock at 133MHz
cpu1: 2661MHz GenuineIntel PentiumIII/Xeon (AX 00020652 CX 0298E3FF DX BFEBFBFF)
#l0: iwl: 54Mbps port 0xF2400000 irq 11 ea 002710c44444
#l1: i82577: 1000Mbps port 0xF2600000 irq 11 ea f0def11619ad
#S/sdE: ahci: sata-II with 4 ports
#A0: hda mem f2620000 irq 11
#A0: waitup timeout for reg=4c, mask=2, set=2
#A0: waitup timeout for reg=5c, mask=2, set=2
#A0: codec #0, vendor 14f15069, rev 00100302
#A0: codec #3, vendor 80862804, rev 00100000
usbehci: 0x8086 0x3b3c: port f2828000 size 1024 irq 11
usbehci: 0x8086 0x3b34: port f2828400 size 1024 irq 11
3800M memory: 1173M kernel data, 2626M user, 3251M swap
bootfs: Sun Aug 15 19:05:02 GMT 2021
fingerprint: 8919bd29786e08d4456e32f7fd8e5d76f2ca2d45
#l0: firmware: iwn-6000, rev 9dd0401, build 25532, size [2] 238d0+14000 + [2]
236e4+14000 + 0
i82577: no phy
sdE1: LBA 0 sectors
  HL-DT-STDVD-ROM DU20N KX01 M0CA97F2329 [newdrive]
sdE0: LLBA 976,773,168 sectors
  ST500LM021-1KJ152 0002LIM1 W6266MQZ [newdrive]
ehci 0xffffff00f2828400: polling
ehci 0xffffff00f2828000: polling

/dev/sdE0: ST500LM021-1KJ152
/dev/sdE0/9fat dos
/dev/sdE0/data
/dev/sdE0/fscache cwfs64x
/dev/sdE0/fsworm
/dev/sdE0/nvram
/dev/sdE0/openbsd
/dev/sdE0/other
/dev/sdE0/plan9
/dev/sdE1: HL-DT-STDVD-ROM DU20N KX01
/dev/sdE2:
/dev/sdE3:
/dev/sdM0: MMC Host Controller
bootargs is (tcp, tls, il, local!device)[local!/dev/sdE0/fscache -a tcp!*!564]
current fs is "main"
12 uids read, 6 groups used
63-bit cwfs as of Sun Aug 15 21:00:11 2021
	last boot Fri Sep 17 15:05:06 2021
essid: REDACTED
key proto=wpapsk essid=REDACTED !password=REDACTED
ipconfig: no success with DHCP
ipconfig now: /net/ether0
4 keys read in AES format
bind: /mnt/term/dev/cons: '/mnt/term/dev' does not exist
bind: /mnt/term/dev: '/mnt/term/dev' does not exist
secstore password:
secstore
#l0: fatal firmware error
lastcmd: 16 (0x10)
error: id 5, pc 28ec,
	branchlink 000028de 000028de, interruptlink 00000000 00001532,
	errordata 00000000 0000022f, srcline 559, tsf ef0040ae, time 5367ff51
#l0: cmd 16: flushq: broken
rxon6000: flushq: broken
#l0: fatal firmware error
lastcmd: 16 (0x10)
error: id 5, pc 28ec,
	branchlink 000028de 000028de, interruptlink 00000000 00001532,
	errordata 00000000 0000022f, srcline 559, tsf 22c09e0c, time 739201f4
#l0: cmd 16: flushq: broken
rxon6000: flushq: broken
nusb/kb: hid: /dev/usb/ep4.1: read: zero read
nusb/kb: fatal: device is detached
#l0: fatal firmware error
lastcmd: 24 (0x18)
error: id 5, pc 1efd8,
	branchlink 0001eee4 0001eee4, interruptlink 00000000 00001532,
	errordata 00000000 00000000, srcline 302, tsf 254092b9, time e9cd47
nusb/kb: hid: /dev/usb/ep9.1: read: zero read
nusb/kb: fatal: device is detached
nusb/audio: no endpoints found
carbon Sep 17 17:49:50 parseoptions: bad option: 0x41: 78 > 13: opt length = 15
carbon Sep 17 18:06:17 parseoptions: bad option: 0x41: 78 > 13: opt length = 15
#l0: fatal firmware error
lastcmd: 16 (0x10)
error: id 5, pc 28ec,
	branchlink 000028de 000028de, interruptlink 00000000 00001532,
	errordata 00000000 0000022f, srcline 559, tsf 7b815718, time fbdec8e8
#l0: cmd 16: flushq: broken
rxon6000: flushq: broken
#l0: fatal firmware error
lastcmd: 16 (0x10)
error: id 5, pc 28ec,
	branchlink 000028de 000028de, interruptlink 00000000 00001532,
	errordata 00000000 0000022f, srcline 559, tsf d241220a, time 147c6df6
#l0: cmd 16: flushq: broken
rxon6000: flushq: broken

% pci -v
0.0.0: brg 06.00.00 8086/0044 0
	Intel Corporation Core Processor DRAM Controller
0.2.0: vid 03.00.00 8086/0046 11 0:f2000004 4194304 2:d000000c 268435456
4:00001801 8
	Intel Corporation Core Processor Integrated Graphics Controller
0.22.0: ser 07.80.00 8086/3b64 11 0:f2827804 16
	Intel Corporation 5 Series/3400 Series Chipset HECI Controller
0.25.0: net 02.00.00 8086/10ea 11 0:f2600000 131072 1:f2625000 4096 2:00001821 32
	Intel Corporation 82577LM Gigabit Network Connection
0.26.0: usb 0c.03.20 8086/3b3c 11 0:f2828000 1024
	Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host
	Controller
0.27.0: aud 04.03.00 8086/3b56 11 0:f2620004 16384
	Intel Corporation 5 Series/3400 Series Chipset High Definition Audio
0.28.0: brg 06.04.00 8086/3b42 11
	Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 1
0.28.1: brg 06.04.00 8086/3b44 11
	Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 2
0.28.3: brg 06.04.00 8086/3b48 11
	Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 4
0.28.4: brg 06.04.00 8086/3b4a 11
	Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 5
0.29.0: usb 0c.03.20 8086/3b34 11 0:f2828400 1024
	Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host
	Controller
0.30.0: brg 06.04.01 8086/2448 255
	Intel Corporation 82801 Mobile PCI Bridge
0.31.0: brg 06.01.00 8086/3b07 0
	Intel Corporation QM57 Chipset LPC Interface Controller
0.31.2: disk 01.06.01 8086/3b2f 11 0:00001861 8 1:00001815 4 2:00001819 8
3:00001811 4 4:00001841 32 5:f2827000 2048
	Intel Corporation 5 Series/3400 Series Chipset 6 port SATA AHCI Controller
0.31.3: smb 0c.05.00 8086/3b30 11 0:f2828804 256 4:00001881 32
	Intel Corporation 5 Series/3400 Series Chipset SMBus Controller
0.31.6: sigl 11.80.00 8086/3b32 11 0:f2626004 4096
	Intel Corporation 5 Series/3400 Series Chipset Thermal Subsystem
3.0.0: net 02.80.00 8086/4239 11 0:f2400004 8192
	Intel Corporation Centrino Advanced-N 6200
13.0.0: base 08.05.00 1180/e822 11 0:f2500000 256
	Ricoh Co Ltd MMC/SD Host Controller
13.0.1: base 08.80.00 1180/e230 11 0:f2500400 256
	Ricoh Co Ltd R5U2xx (R5U230 / R5U231 / R5U241) [Memory Stick Host
	Controller]
13.0.3: --- 0c.00.10 1180/e832 11 0:f2500800 2048
	Ricoh Co Ltd R5C832 PCIe IEEE 1394 Controller
255.0.0: brg 06.00.00 8086/2c62 0
	Intel Corporation Core Processor QuickPath Architecture Generic Non-core
	Registers
255.0.1: brg 06.00.00 8086/2d01 0
	Intel Corporation Core Processor QuickPath Architecture System Address
	Decoder
255.2.0: brg 06.00.00 8086/2d10 0
	Intel Corporation Core Processor QPI Link 0
255.2.1: brg 06.00.00 8086/2d11 0
	Intel Corporation 1st Generation Core i3/5/7 Processor QPI Physical 0
255.2.2: brg 06.00.00 8086/2d12 0
	Intel Corporation 1st Generation Core i3/5/7 Processor Reserved
255.2.3: brg 06.00.00 8086/2d13 0
	Intel Corporation 1st Generation Core i3/5/7 Processor Reserved

% aux/cpuid
vendor GenuineIntel
procmodel 00020652 / 04100800
typefammod 0 06 026 2
features fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
features pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe
features pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm
sse4_1 sse4_2 popcnt
features aes
extmodel 00000000 / 00000000
extfeatures syscall tscp lm
extfeatures ahf64
procname Intel(R) Core(TM) i7 CPU M 620 @ 2.67GHz
physbits 36
virtbits 48

% aux/icanhasmsi
0.2.0
0.22.0
0.25.0
0.27.0
0.28.0
0.28.1
0.28.3
0.28.4
0.31.2
0.31.6
3.0.0
13.0.0
13.0.1
13.0.3

% aux/icanhasvmx -v
vmcsrev 0xf
vmxonsz 1024
vmcsmem 6
extcontrols 1
pin extirq nmiexit virtnmi preempt
proc irqwin tscoffset hltexit invlpgexit mwaitexit rdpmcexit rdtscexit cr3ldexit
proc cr3stexit cr8ldexit cr8stexit tprshadow nmiwin movdrexit ioexit iobitmap mtf
proc msrbitmap monitorexit pauseexit
proc2 virtapic ept gdtexit rdtscp virtx2apic vpid wbinvdexit unrestr
entry loaddebug guest64 entrysmm dualmonitor loadperfglobal loadpat loadefer
exit savedebug host64 saveperfglobal ackextirq !savepat !loadpat saveefer loadefer
exit savepreempt
misc preemptdiv:5 cr3targ:4 maxmsr:0 mseg:0x0
misc longmodeswitch hlt shutdown ipi
cr0fixed pe ne pg
cr4fixed !umip vmxe !fsgsbase !pcide !osxsave !smep !smap !pke
vmcsenum 0x2a
ept xonly pwl4 ucmem wbmem 2MBpage invept invept.single invept.all
vpid invvpid invvpid.addr invvpid.single invvpid.all invvpid.noglob

% aux/pcmcia
pcmcia: opening #y/pcm0attr: unknown device in # filename

% cat '#'u/usb/ctl
ep1.0 enabled control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 0 port 0 rootport 0 addr 0 busy
roothub csp 0x000009 ports 3 ehci
ep2.0 enabled control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 0 port 0 rootport 0 addr 0 busy
roothub csp 0x000009 ports 3 ehci
ep3.0 enabled control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 0 port 1 rootport 1 addr 3 busy
hub csp 0x010009 ports 8 none <nil> ehci
ep11.0 detached control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 7 port 1 rootport 1 addr 11 busy
 csp 0x010106 vid 0x22b8 did 0x2e84 motorola 'moto g(6)' 9a831 ehci
ep11.1 detached bulk rw speed high maxpkt 512 ntds 1 pollival 1 samplesz 0 hz 0
uframes 0 hub 7 port 1 rootport 1 addr 11 busy
ep5.0 enabled control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 3 port 4 rootport 1 addr 5 idle
255 csp 0xffffff vid 0x05c6 did 0x9204 'Qualcomm Incorporated' 'Qualcomm Gobi
2000' e26e3 ehci
ep5.1 enabled bulk rw speed high maxpkt 512 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 3 port 4 rootport 1 addr 5 idle
ep6.0 enabled control rw speed full maxpkt 8 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 3 port 5 rootport 1 addr 6 idle
11 csp 0x00000b vid 0x17ef did 0x1003 Lenovo 'Integrated Smart Card Reader' 35b68
ehci
ep6.1 enabled interrupt r speed full maxpkt 8 ntds 1 pollival 24 samplesz 0 hz 0
uframes 0 hub 3 port 5 rootport 1 addr 6 idle
ep6.2 enabled bulk rw speed full maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 3 port 5 rootport 1 addr 6 idle
ep7.0 enabled control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 0 port 1 rootport 1 addr 7 busy
hub csp 0x010009 ports 6 none <nil> ehci
ep8.0 enabled control rw speed full maxpkt 8 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 7 port 3 rootport 1 addr 8 idle
255 csp 0x0000ff vid 0x147e did 0x2016 UPEK 'Biometric Coprocessor' 91d52 ehci
ep8.1 enabled bulk r speed full maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 7 port 3 rootport 1 addr 8 idle
ep8.2 enabled bulk w speed full maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 7 port 3 rootport 1 addr 8 idle
ep8.3 enabled interrupt r speed full maxpkt 4 ntds 1 pollival 20 samplesz 0 hz 0
uframes 0 hub 7 port 3 rootport 1 addr 8 idle
ep10.0 enabled control rw speed low maxpkt 8 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 3 port 2 rootport 1 addr 10 busy
hid csp 0x020103 vid 0x04f3 did 0x0235 none <nil> c1bad ehci
ep10.1 enabled interrupt r speed low maxpkt 4 ntds 1 pollival 10 samplesz 0 hz 0
uframes 0 hub 3 port 2 rootport 1 addr 10 busy
ep12.0 detached control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 7 port 1 rootport 1 addr 12 busy
224 csp 0x0301e0 vid 0x22b8 did 0x2e25 motorola 'moto g(6)' 22a00 ehci
ep12.1 detached bulk rw speed high maxpkt 512 ntds 1 pollival 1 samplesz 0 hz 0
uframes 0 hub 7 port 1 rootport 1 addr 12 busy
ep13.0 detached control rw speed high maxpkt 64 ntds 1 pollival 0 samplesz 0 hz 0
uframes 0 hub 7 port 1 rootport 1 addr 13 busy
224 csp 0x0301e0 vid 0x22b8 did 0x2e25 motorola 'moto g(6)' 22a00 ehci
ep13.1 detached bulk rw speed high maxpkt 512 ntds 1 pollival 1 samplesz 0 hz 0
uframes 0 hub 7 port 1 rootport 1 addr 13 busy

% cat '#'S/sdctl
sdE ahci ahci port 0xffffff00f2827000: 64a ncq ntf mps ss alp led clo pmb slum
pslum ems xs apts alhd xonly smb elmt iss 2 ncs 31 np 6 ghc 80000002 isr 0 pi 33
0-1, 4-5 ver 10300
sdM mmc 1 units
sdZ ram 4 units

% cat '#'S/sdE0/ctl
inquiry ST500LM021-1KJ152
model ST500LM021-1KJ152
serial W6266MQZ
firm 0002LIM1
wwn 5000c5008a55d516
flag lba llba smart power ata8 sct
udma 6
reg task 50 cmd e017 serr 0 ci 0 is 0 sig 101 sstatus 123
cmd cr fr mpss pod sud st
mode auto sataii
geometry 976773168 512
alignment 4096 0
missirq 0
part data 0 976773168
part plan9 63 195302205
part openbsd 195302205 258212745
part 9fat 63 204864
part nvram 204864 204872
part other 204872 28075920
part fscache 28075920 55946968
part fsworm 55946968 195302202

% cat '#'S/sdE1/ctl
inquiry HL-DT-STDVD-ROM DU20N KX01
model HL-DT-STDVD-ROM DU20N
serial M0CA97F2329
firm KX01
flag lba nop atapi
udma 6
reg task 2451 cmd cc017 serr 0 ci 0 is 0 sig eb140101 sstatus 113
cmd mpsp hpcp cr fr pod sud st
mode auto sataii
geometry 0 0
alignment 0 0
missirq 0

% cat '#'S/sdE2/ctl
inquiry
no disk present [missing]
reg task 7f cmd 246016 serr 0 ci 0 is 0 sig ffffffff sstatus 000
cmd esp hpcp fr mpss pod sud
mode auto sataii
geometry 0 0
alignment 0 0
missirq 0

% cat '#'S/sdE3/ctl
inquiry
no disk present [missing]
reg task 7f cmd 246016 serr 0 ci 0 is 0 sig ffffffff sstatus 000
cmd esp hpcp fr mpss pod sud
mode auto sataii
geometry 0 0
alignment 0 0
missirq 0

% cat '#'S/sdM0/ctl
inquiry MMC Host Controller

% cat '#'l0/ether0/addr
002710c44444
% cat '#'l0/ether0/stats
in: 28965
link: 1
out: 2102
crc errs: 0
overflows: 0
soft overflows: 34
framing errs: 0
buffer errs: 0
output errs: 0
prom: 0
mbps: 1
addr: 002710c44444

% cat '#'l0/ether0/ifstats
REDACTED

% cat '#'l1/ether1/addr
f0def11619ad
% cat '#'l1/ether1/stats
in: 0
link: 0
out: 0
crc errs: 0
overflows: 0
soft overflows: 0
framing errs: 0
buffer errs: 0
output errs: 0
prom: 0
mbps: 1000
addr: f0def11619ad

% cat '#'l1/ether1/ifstats
lintr: 0 1
rintr: 0 1
tintr: 0 0
ixcs: 0 0 0
rdtr: 25
radv: 500
ctrl: 00100240
ctrlext: 01481000
status: 00080600
txcw: 00000000
txdctl: 00040004
pba: 000e0012
speeds: 10:0 100:0 1000:0 ?:0
type: i82577
eeprom: def0 16f1 ad19 0800 ffff 00c1 ffff ffff
	a002 ffff 10c3 2153 17aa 10ea 0000 0000
	0702 0000 0000 a505 0028 1800 0000 0c00
	2a64 0b40 0843 0013 10ea baad 10ea 10eb
	baad baad baad baad 8000 8090 4e00 0000
	0000 0000 0000 0000 0000 0000 0000 ffff
	0100 4000 1333 4007 ffff ffff ffff ffff
	ffff ffff ffff ffff ffff 0100 ffff 4a4f

% cat '#'v/vgactl
type vesa
size 1280x800x32 x8r8g8b8
tilt none
hwgc soft
hwaccel off
hwblank on
addr p 0xd0000000 v 0xffffff00d0000000 size 0x4000000
softscreen on

@{rfork n; aux/realemu; aux/vga -p}
vesa flag Ulinear|Hlinear|Fsnarf
vesa sig VESA 3.0
vesa oem Intel(R)Ironlake Mobile Graphics Chipset Accelerated VGA BIOS 1.0
vesa vendor Intel Corporation
vesa product Intel(R)Ironlake Mobile Graphics Controller
vesa rev Hardware Version 0.0
vesa cap 8-bit-dac
vesa mem 33488896
vesa dsp con 4
vesa dsp act 4
vesa mode 0x160 768x480x8 m8 packed
vesa mode 0x161 768x480x16 r5g6b5 direct
vesa mode 0x162 768x480x32 x8r8g8b8 direct
vesa mode 0x163 960x600x8 m8 packed
vesa mode 0x164 960x600x16 r5g6b5 direct
vesa mode 0x165 960x600x32 x8r8g8b8 direct
vesa mode 0x166 1280x800x8 m8 packed
vesa mode 0x167 1280x800x16 r5g6b5 direct
vesa mode 0x168 1280x800x32 x8r8g8b8 direct
vesa mode 0x105 1024x768x8 m8 packed
vesa mode 0x117 1024x768x16 r5g6b5 direct
vesa mode 0x118 1024x768x32 x8r8g8b8 direct
vesa mode 0x112 640x480x32 x8r8g8b8 direct
vesa mode 0x114 800x600x16 r5g6b5 direct
vesa mode 0x115 800x600x32 x8r8g8b8 direct
vesa mode 0x101 640x480x8 m8 packed
vesa mode 0x103 800x600x8 m8 packed
vesa mode 0x111 640x480x16 r5g6b5 direct
edid mfr LEN
edid serialstr
edid name
edid product 16437
edid serial 0
edid version 1.3
edid mfrdate 2009.0
edid size (cm) 30x19
edid gamma 2.20
edid vert (Hz) 0-0
edid horz (Hz) 0-0
edid pclkmax 0
edid flags digital standby suspend activeoff
edid 1280x800@50Hz
		clock=69.22
		shb=1332 ehb=1396 ht=1595
		vrs=803 vre=806 vt=868
		hsync=- vsync=-
edid 1280x800@60Hz
		clock=69.22
		shb=1332 ehb=1396 ht=1412
		vrs=803 vre=806 vt=817
		hsync=- vsync=-

% xd -x1 '#'r/nvram
REDACTED (What is this on a PC btw?)

% cat '#'A/audiostat
bufsize 1024 buffered 0
codec 0 pin 31 inpin 35
aout 16 c1d
aout 17 c1d
aout 18 611
beep 19 70000c
ain 20 100d1b ← asel 23, asel 24, pin 35, amix 36
ain 21 100d1b ← asel 23, asel 24, pin 35, amix 36
ain 22 100d1b ← asel 23, asel 24, pin 35, amix 36
asel 23 30050d ← pin 26, pin 27, pin 29, pin 30
asel 24 30050d ← pin 26, pin 27, pin 29, pin 30
pin 25 out jack ext right hpout black ← aout 16, aout 17
pin 26 in nothing sep rear micin pink
pin 27 inout jack ext right micin black eapd ← aout 16, aout 17
pin 28 out nothing sep rear hpout green ← aout 16, aout 17
pin 29 inout nothing ext N/A other ? eapd ← aout 16, aout 17
pin 30 in nothing ext N/A other ?
pin 31 out fix int N/A speaker ? ← aout 16, aout 17
pin 32 out nothing ext N/A other ? ← aout 18
aout 33 611
pin 34 out nothing ext N/A other ? ← aout 33
pin 35 in fix int N/A micin ?
amix 36 20050b ← aout 16, aout 17
beep 37 f00000
codec 3 pin 31 inpin 35
aout 2 6611
aout 3 6611
pin 4 out jack int special digiout ? hdmi ← aout 2, aout 3
pin 5 out jack int special digiout ? hdmi ← aout 2, aout 3
pin 6 out jack int special digiout ? hdmi ← aout 2, aout 3
beep 7 f00000
outpath aout 16 → pin 31
outamp aout 16
inpath pin 35 → ain 20
inamp ain 20

% cat '#'A/volume
master 70 70
recgain 0 0
speed 44100
delay 1764

% cat /mnt/apm/ctl
cat: can't open /mnt/apm/ctl: '/mnt/apm/ctl' does not exist



prev | next