xref: /plan9-contrib/sys/src/9/pc/etheriwl.c (revision 43f728cba48694b0a42c538a38fdf975a0ae5433)
1 /*
2  * Intel WiFi Link driver.
3  *
4  * Written without any documentation but Damien Bergaminis
5  * OpenBSD iwn(4) driver sources. Requires intel firmware
6  * to be present in /lib/firmware/iwn-* on attach.
7  */
8 
9 #include "u.h"
10 #include "../port/lib.h"
11 #include "mem.h"
12 #include "dat.h"
13 #include "fns.h"
14 #include "io.h"
15 #include "../port/error.h"
16 #include "../port/netif.h"
17 
18 #include "etherif.h"
19 #include "wifi.h"
20 
21 enum {
22 	Ntxlog		= 8,
23 	Ntx		= 1<<Ntxlog,
24 	Nrxlog		= 8,
25 	Nrx		= 1<<Nrxlog,
26 
27 	Rstatsize	= 16,
28 	Rbufsize	= 4*1024,
29 	Rdscsize	= 8,
30 
31 	Tbufsize	= 4*1024,
32 	Tdscsize	= 128,
33 	Tcmdsize	= 140,
34 };
35 
36 /* registers */
37 enum {
38 	Cfg		= 0x000,	/* config register */
39 		MacSi		= 1<<8,
40 		RadioSi		= 1<<9,
41 		EepromLocked	= 1<<21,
42 		NicReady	= 1<<22,
43 		HapwakeL1A	= 1<<23,
44 		PrepareDone	= 1<<25,
45 		Prepare		= 1<<27,
46 
47 	Isr		= 0x008,	/* interrupt status */
48 	Imr		= 0x00c,	/* interrupt mask */
49 		Ialive		= 1<<0,
50 		Iwakeup		= 1<<1,
51 		Iswrx		= 1<<3,
52 		Ictreached	= 1<<6,
53 		Irftoggled	= 1<<7,
54 		Iswerr		= 1<<25,
55 		Isched		= 1<<26,
56 		Ifhtx		= 1<<27,
57 		Irxperiodic	= 1<<28,
58 		Ihwerr		= 1<<29,
59 		Ifhrx		= 1<<31,
60 
61 		Ierr		= Iswerr | Ihwerr,
62 		Idefmask	= Ierr | Ifhtx | Ifhrx | Ialive | Iwakeup | Iswrx | Ictreached | Irftoggled,
63 
64 	FhIsr		= 0x010,	/* second interrupt status */
65 
66 	Reset		= 0x020,
67 
68 	Rev		= 0x028,	/* hardware revision */
69 
70 	EepromIo	= 0x02c,	/* EEPROM i/o register */
71 	EepromGp	= 0x030,
72 
73 	OtpromGp	= 0x034,
74 		DevSelOtp	= 1<<16,
75 		RelativeAccess	= 1<<17,
76 		EccCorrStts	= 1<<20,
77 		EccUncorrStts	= 1<<21,
78 
79 	Gpc		= 0x024,	/* gp cntrl */
80 		MacAccessEna	= 1<<0,
81 		MacClockReady	= 1<<0,
82 		InitDone	= 1<<2,
83 		MacAccessReq	= 1<<3,
84 		NicSleep	= 1<<4,
85 		RfKill		= 1<<27,
86 
87 	Gio		= 0x03c,
88 		EnaL0S		= 1<<1,
89 
90 	GpDrv	= 0x050,
91 		GpDrvCalV6	= 1<<2,
92 		GpDrv1X2	= 1<<3,
93 		GpDrvRadioIqInvert	= 1<<7,
94 
95 	Led		= 0x094,
96 		LedBsmCtrl	= 1<<5,
97 		LedOn		= 0x38,
98 		LedOff		= 0x78,
99 
100 	UcodeGp1Clr	= 0x05c,
101 		UcodeGp1RfKill		= 1<<1,
102 		UcodeGp1CmdBlocked	= 1<<2,
103 		UcodeGp1CtempStopRf	= 1<<3,
104 
105 	ShadowRegCtrl	= 0x0a8,
106 
107 	Giochicken	= 0x100,
108 		L1AnoL0Srx	= 1<<23,
109 		DisL0Stimer	= 1<<29,
110 
111 	AnaPll		= 0x20c,
112 
113 	Dbghpetmem	= 0x240,
114 	Dbglinkpwrmgmt	= 0x250,
115 
116 	MemRaddr	= 0x40c,
117 	MemWaddr	= 0x410,
118 	MemWdata	= 0x418,
119 	MemRdata	= 0x41c,
120 
121 	PrphWaddr	= 0x444,
122 	PrphRaddr	= 0x448,
123 	PrphWdata	= 0x44c,
124 	PrphRdata	= 0x450,
125 
126 	HbusTargWptr	= 0x460,
127 };
128 
129 /*
130  * Flow-Handler registers.
131  */
132 enum {
133 	FhTfbdCtrl0	= 0x1900,	// +q*8
134 	FhTfbdCtrl1	= 0x1904,	// +q*8
135 
136 	FhKwAddr	= 0x197c,
137 
138 	FhSramAddr	= 0x19a4,	// +q*4
139 	FhCbbcQueue	= 0x19d0,	// +q*4
140 	FhStatusWptr	= 0x1bc0,
141 	FhRxBase	= 0x1bc4,
142 	FhRxWptr	= 0x1bc8,
143 	FhRxConfig	= 0x1c00,
144 		FhRxConfigEna		= 1<<31,
145 		FhRxConfigRbSize8K	= 1<<16,
146 		FhRxConfigSingleFrame	= 1<<15,
147 		FhRxConfigIrqDstHost	= 1<<12,
148 		FhRxConfigIgnRxfEmpty	= 1<<2,
149 
150 		FhRxConfigNrbdShift	= 20,
151 		FhRxConfigRbTimeoutShift= 4,
152 
153 	FhRxStatus	= 0x1c44,
154 
155 	FhTxConfig	= 0x1d00,	// +q*32
156 		FhTxConfigDmaCreditEna	= 1<<3,
157 		FhTxConfigDmaEna	= 1<<31,
158 		FhTxConfigCirqHostEndTfd= 1<<20,
159 
160 	FhTxBufStatus	= 0x1d08,	// +q*32
161 		FhTxBufStatusTbNumShift	= 20,
162 		FhTxBufStatusTbIdxShift = 12,
163 		FhTxBufStatusTfbdValid	= 3,
164 
165 	FhTxChicken	= 0x1e98,
166 	FhTxStatus	= 0x1eb0,
167 };
168 
169 /*
170  * NIC internal memory offsets.
171  */
172 enum {
173 	ApmgClkCtrl	= 0x3000,
174 	ApmgClkEna	= 0x3004,
175 	ApmgClkDis	= 0x3008,
176 		DmaClkRqt	= 1<<9,
177 		BsmClkRqt	= 1<<11,
178 
179 	ApmgPs		= 0x300c,
180 		EarlyPwroffDis	= 1<<22,
181 		PwrSrcVMain	= 0<<24,
182 		PwrSrcVAux	= 2<<24,
183 		PwrSrcMask	= 3<<24,
184 		ResetReq	= 1<<26,
185 
186 	ApmgDigitalSvr	= 0x3058,
187 	ApmgAnalogSvr	= 0x306c,
188 	ApmgPciStt	= 0x3010,
189 	BsmWrCtrl	= 0x3400,
190 	BsmWrMemSrc	= 0x3404,
191 	BsmWrMemDst	= 0x3408,
192 	BsmWrDwCount	= 0x340c,
193 	BsmDramTextAddr	= 0x3490,
194 	BsmDramTextSize	= 0x3494,
195 	BsmDramDataAddr	= 0x3498,
196 	BsmDramDataSize	= 0x349c,
197 	BsmSramBase	= 0x3800,
198 };
199 
200 /*
201  * TX scheduler registers.
202  */
203 enum {
204 	SchedBase		= 0xa02c00,
205 	SchedSramAddr		= SchedBase,
206 
207 	SchedDramAddr4965	= SchedBase+0x010,
208 	SchedTxFact4965		= SchedBase+0x01c,
209 	SchedQueueRdptr4965	= SchedBase+0x064,	// +q*4
210 	SchedQChainSel4965	= SchedBase+0x0d0,
211 	SchedIntrMask4965	= SchedBase+0x0e4,
212 	SchedQueueStatus4965	= SchedBase+0x104,	// +q*4
213 
214 	SchedDramAddr5000	= SchedBase+0x008,
215 	SchedTxFact5000		= SchedBase+0x010,
216 	SchedQueueRdptr5000	= SchedBase+0x068,	// +q*4
217 	SchedQChainSel5000	= SchedBase+0x0e8,
218 	SchedIntrMask5000	= SchedBase+0x108,
219 	SchedQueueStatus5000	= SchedBase+0x10c,	// +q*4
220 	SchedAggrSel5000	= SchedBase+0x248,
221 };
222 
223 enum {
224 	SchedCtxOff4965		= 0x380,
225 	SchedCtxLen4965		= 416,
226 
227 	SchedCtxOff5000		= 0x600,
228 	SchedCtxLen5000		= 512,
229 };
230 
231 enum {
232 	FilterPromisc		= 1<<0,
233 	FilterCtl		= 1<<1,
234 	FilterMulticast		= 1<<2,
235 	FilterNoDecrypt		= 1<<3,
236 	FilterBSS		= 1<<5,
237 	FilterBeacon		= 1<<6,
238 };
239 
240 enum {
241 	RFlag24Ghz		= 1<<0,
242 	RFlagCCK		= 1<<1,
243 	RFlagAuto		= 1<<2,
244 	RFlagShSlot		= 1<<4,
245 	RFlagShPreamble		= 1<<5,
246 	RFlagNoDiversity	= 1<<7,
247 	RFlagAntennaA		= 1<<8,
248 	RFlagAntennaB		= 1<<9,
249 	RFlagTSF		= 1<<15,
250 	RFlagCTSToSelf		= 1<<30,
251 };
252 
253 typedef struct FWInfo FWInfo;
254 typedef struct FWImage FWImage;
255 typedef struct FWSect FWSect;
256 
257 typedef struct TXQ TXQ;
258 typedef struct RXQ RXQ;
259 
260 typedef struct Ctlr Ctlr;
261 
262 struct FWSect
263 {
264 	uchar	*data;
265 	uint	size;
266 };
267 
268 struct FWImage
269 {
270 	struct {
271 		FWSect	text;
272 		FWSect	data;
273 	} init, main, boot;
274 
275 	uint	rev;
276 	uint	build;
277 	char	descr[64+1];
278 	uchar	data[];
279 };
280 
281 struct FWInfo
282 {
283 	uchar	major;
284 	uchar	minjor;
285 	uchar	type;
286 	uchar	subtype;
287 
288 	u32int	logptr;
289 	u32int	errptr;
290 	u32int	tstamp;
291 	u32int	valid;
292 };
293 
294 struct TXQ
295 {
296 	uint	n;
297 	uint	i;
298 	Block	**b;
299 	uchar	*d;
300 	uchar	*c;
301 
302 	uint	lastcmd;
303 
304 	Rendez;
305 	QLock;
306 };
307 
308 struct RXQ
309 {
310 	uint	i;
311 	Block	**b;
312 	u32int	*p;
313 	uchar	*s;
314 };
315 
316 struct Ctlr {
317 	Lock;
318 	QLock;
319 
320 	Ctlr *link;
321 	Pcidev *pdev;
322 	Wifi *wifi;
323 
324 	int type;
325 	int port;
326 	int power;
327 	int active;
328 	int broken;
329 	int attached;
330 
331 	u32int ie;
332 
333 	u32int *nic;
334 	uchar *kwpage;
335 
336 	/* assigned node ids in hardware node table or -1 if unassigned */
337 	int bcastnodeid;
338 	int bssnodeid;
339 
340 	/* current receiver settings */
341 	uchar bssid[Eaddrlen];
342 	int channel;
343 	int prom;
344 	int aid;
345 
346 	RXQ rx;
347 	TXQ tx[20];
348 
349 	struct {
350 		Rendez;
351 		u32int	m;
352 		u32int	w;
353 	} wait;
354 
355 	struct {
356 		uchar	type;
357 		uchar	step;
358 		uchar	dash;
359 		uchar	txantmask;
360 		uchar	rxantmask;
361 	} rfcfg;
362 
363 	struct {
364 		int	otp;
365 		uint	off;
366 
367 		uchar	version;
368 		uchar	type;
369 		u16int	volt;
370 		u16int	temp;
371 		u16int	rawtemp;
372 
373 		char	regdom[4+1];
374 
375 		u32int	crystal;
376 	} eeprom;
377 
378 	struct {
379 		Block	*cmd[21];
380 		int	done;
381 	} calib;
382 
383 	struct {
384 		u32int	base;
385 		uchar	*s;
386 	} sched;
387 
388 	FWInfo fwinfo;
389 	FWImage *fw;
390 };
391 
392 /* controller types */
393 enum {
394 	Type4965	= 0,
395 	Type5300	= 2,
396 	Type5350	= 3,
397 	Type5150	= 4,
398 	Type5100	= 5,
399 	Type1000	= 6,
400 	Type6000	= 7,
401 	Type6050	= 8,
402 	Type6005	= 11,	/* also Centrino Advanced-N 6030, 6235 */
403 	Type2030	= 12,
404 };
405 
406 static char *fwname[32] = {
407 	[Type4965] "iwn-4965",
408 	[Type5300] "iwn-5000",
409 	[Type5350] "iwn-5000",
410 	[Type5150] "iwn-5150",
411 	[Type5100] "iwn-5000",
412 	[Type1000] "iwn-1000",
413 	[Type6000] "iwn-6000",
414 	[Type6050] "iwn-6050",
415 	[Type6005] "iwn-6005", /* see in iwlattach() below */
416 	[Type2030] "iwn-2030",
417 };
418 
419 static char *qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block);
420 static char *flushq(Ctlr *ctlr, uint qid);
421 static char *cmd(Ctlr *ctlr, uint code, uchar *data, int size);
422 
423 #define csr32r(c, r)	(*((c)->nic+((r)/4)))
424 #define csr32w(c, r, v)	(*((c)->nic+((r)/4)) = (v))
425 
426 static uint
get16(uchar * p)427 get16(uchar *p){
428 	return *((u16int*)p);
429 }
430 static uint
get32(uchar * p)431 get32(uchar *p){
432 	return *((u32int*)p);
433 }
434 static void
put32(uchar * p,uint v)435 put32(uchar *p, uint v){
436 	*((u32int*)p) = v;
437 }
438 static void
put16(uchar * p,uint v)439 put16(uchar *p, uint v){
440 	*((u16int*)p) = v;
441 };
442 
443 static char*
niclock(Ctlr * ctlr)444 niclock(Ctlr *ctlr)
445 {
446 	int i;
447 
448 	csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) | MacAccessReq);
449 	for(i=0; i<1000; i++){
450 		if((csr32r(ctlr, Gpc) & (NicSleep | MacAccessEna)) == MacAccessEna)
451 			return 0;
452 		delay(10);
453 	}
454 	return "niclock: timeout";
455 }
456 
457 static void
nicunlock(Ctlr * ctlr)458 nicunlock(Ctlr *ctlr)
459 {
460 	csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) & ~MacAccessReq);
461 }
462 
463 static u32int
prphread(Ctlr * ctlr,uint off)464 prphread(Ctlr *ctlr, uint off)
465 {
466 	csr32w(ctlr, PrphRaddr, ((sizeof(u32int)-1)<<24) | off);
467 	coherence();
468 	return csr32r(ctlr, PrphRdata);
469 }
470 static void
prphwrite(Ctlr * ctlr,uint off,u32int data)471 prphwrite(Ctlr *ctlr, uint off, u32int data)
472 {
473 	csr32w(ctlr, PrphWaddr, ((sizeof(u32int)-1)<<24) | off);
474 	coherence();
475 	csr32w(ctlr, PrphWdata, data);
476 }
477 
478 static u32int
memread(Ctlr * ctlr,uint off)479 memread(Ctlr *ctlr, uint off)
480 {
481 	csr32w(ctlr, MemRaddr, off);
482 	coherence();
483 	return csr32r(ctlr, MemRdata);
484 }
485 static void
memwrite(Ctlr * ctlr,uint off,u32int data)486 memwrite(Ctlr *ctlr, uint off, u32int data)
487 {
488 	csr32w(ctlr, MemWaddr, off);
489 	coherence();
490 	csr32w(ctlr, MemWdata, data);
491 }
492 
493 static void
setfwinfo(Ctlr * ctlr,uchar * d,int len)494 setfwinfo(Ctlr *ctlr, uchar *d, int len)
495 {
496 	FWInfo *i;
497 
498 	if(len < 32)
499 		return;
500 	i = &ctlr->fwinfo;
501 	i->minjor = *d++;
502 	i->major = *d++;
503 	d += 2+8;
504 	i->type = *d++;
505 	i->subtype = *d++;
506 	d += 2;
507 	i->logptr = get32(d); d += 4;
508 	i->errptr = get32(d); d += 4;
509 	i->tstamp = get32(d); d += 4;
510 	i->valid = get32(d);
511 };
512 
513 static void
dumpctlr(Ctlr * ctlr)514 dumpctlr(Ctlr *ctlr)
515 {
516 	u32int dump[13];
517 	int i;
518 
519 	print("lastcmd: %ud (0x%ux)\n", ctlr->tx[4].lastcmd,  ctlr->tx[4].lastcmd);
520 	if(ctlr->fwinfo.errptr == 0){
521 		print("no error pointer\n");
522 		return;
523 	}
524 	for(i=0; i<nelem(dump); i++)
525 		dump[i] = memread(ctlr, ctlr->fwinfo.errptr + i*4);
526 	print(	"error:\tid %ux, pc %ux,\n"
527 		"\tbranchlink %.8ux %.8ux, interruptlink %.8ux %.8ux,\n"
528 		"\terrordata %.8ux %.8ux, srcline %ud, tsf %ux, time %ux\n",
529 		dump[1], dump[2],
530 		dump[4], dump[3], dump[6], dump[5],
531 		dump[7], dump[8], dump[9], dump[10], dump[11]);
532 }
533 
534 static char*
eepromlock(Ctlr * ctlr)535 eepromlock(Ctlr *ctlr)
536 {
537 	int i, j;
538 
539 	for(i=0; i<100; i++){
540 		csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | EepromLocked);
541 		for(j=0; j<100; j++){
542 			if(csr32r(ctlr, Cfg) & EepromLocked)
543 				return 0;
544 			delay(10);
545 		}
546 	}
547 	return "eepromlock: timeout";
548 }
549 static void
eepromunlock(Ctlr * ctlr)550 eepromunlock(Ctlr *ctlr)
551 {
552 	csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) & ~EepromLocked);
553 }
554 static char*
eepromread(Ctlr * ctlr,void * data,int count,uint off)555 eepromread(Ctlr *ctlr, void *data, int count, uint off)
556 {
557 	uchar *out = data;
558 	u32int w, s;
559 	int i;
560 
561 	w = 0;
562 	off += ctlr->eeprom.off;
563 	for(; count > 0; count -= 2, off++){
564 		csr32w(ctlr, EepromIo, off << 2);
565 		for(i=0; i<10; i++){
566 			w = csr32r(ctlr, EepromIo);
567 			if(w & 1)
568 				break;
569 			delay(5);
570 		}
571 		if(i == 10)
572 			return "eepromread: timeout";
573 		if(ctlr->eeprom.otp){
574 			s = csr32r(ctlr, OtpromGp);
575 			if(s & EccUncorrStts)
576 				return "eepromread: otprom ecc error";
577 			if(s & EccCorrStts)
578 				csr32w(ctlr, OtpromGp, s);
579 		}
580 		*out++ = w >> 16;
581 		if(count > 1)
582 			*out++ = w >> 24;
583 	}
584 	return 0;
585 }
586 
587 static char*
handover(Ctlr * ctlr)588 handover(Ctlr *ctlr)
589 {
590 	int i;
591 
592 	csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | NicReady);
593 	for(i=0; i<5; i++){
594 		if(csr32r(ctlr, Cfg) & NicReady)
595 			return 0;
596 		delay(10);
597 	}
598 	csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | Prepare);
599 	for(i=0; i<15000; i++){
600 		if((csr32r(ctlr, Cfg) & PrepareDone) == 0)
601 			break;
602 		delay(10);
603 	}
604 	if(i >= 15000)
605 		return "handover: timeout";
606 	csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | NicReady);
607 	for(i=0; i<5; i++){
608 		if(csr32r(ctlr, Cfg) & NicReady)
609 			return 0;
610 		delay(10);
611 	}
612 	return "handover: timeout";
613 }
614 
615 static char*
clockwait(Ctlr * ctlr)616 clockwait(Ctlr *ctlr)
617 {
618 	int i;
619 
620 	/* Set "initialization complete" bit. */
621 	csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) | InitDone);
622 	for(i=0; i<2500; i++){
623 		if(csr32r(ctlr, Gpc) & MacClockReady)
624 			return 0;
625 		delay(10);
626 	}
627 	return "clockwait: timeout";
628 }
629 
630 static char*
poweron(Ctlr * ctlr)631 poweron(Ctlr *ctlr)
632 {
633 	int capoff;
634 	char *err;
635 
636 	/* Disable L0s exit timer (NMI bug workaround). */
637 	csr32w(ctlr, Giochicken, csr32r(ctlr, Giochicken) | DisL0Stimer);
638 
639 	/* Don't wait for ICH L0s (ICH bug workaround). */
640 	csr32w(ctlr, Giochicken, csr32r(ctlr, Giochicken) | L1AnoL0Srx);
641 
642 	/* Set FH wait threshold to max (HW bug under stress workaround). */
643 	csr32w(ctlr, Dbghpetmem, csr32r(ctlr, Dbghpetmem) | 0xffff0000);
644 
645 	/* Enable HAP INTA to move adapter from L1a to L0s. */
646 	csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | HapwakeL1A);
647 
648 	capoff = pcicap(ctlr->pdev, PciCapPCIe);
649 	if(capoff != -1){
650 		/* Workaround for HW instability in PCIe L0->L0s->L1 transition. */
651 		if(pcicfgr16(ctlr->pdev, capoff + 0x10) & 0x2)	/* LCSR -> L1 Entry enabled. */
652 			csr32w(ctlr, Gio, csr32r(ctlr, Gio) | EnaL0S);
653 		else
654 			csr32w(ctlr, Gio, csr32r(ctlr, Gio) & ~EnaL0S);
655 	}
656 
657 	if(ctlr->type != Type4965 && ctlr->type <= Type1000)
658 		csr32w(ctlr, AnaPll, csr32r(ctlr, AnaPll) | 0x00880300);
659 
660 	/* Wait for clock stabilization before accessing prph. */
661 	if((err = clockwait(ctlr)) != nil)
662 		return err;
663 
664 	if((err = niclock(ctlr)) != nil)
665 		return err;
666 
667 	/* Enable DMA and BSM (Bootstrap State Machine). */
668 	if(ctlr->type == Type4965)
669 		prphwrite(ctlr, ApmgClkEna, DmaClkRqt | BsmClkRqt);
670 	else
671 		prphwrite(ctlr, ApmgClkEna, DmaClkRqt);
672 	delay(20);
673 
674 	/* Disable L1-Active. */
675 	prphwrite(ctlr, ApmgPciStt, prphread(ctlr, ApmgPciStt) | (1<<11));
676 
677 	nicunlock(ctlr);
678 
679 	ctlr->power = 1;
680 
681 	return 0;
682 }
683 
684 static void
poweroff(Ctlr * ctlr)685 poweroff(Ctlr *ctlr)
686 {
687 	int i, j;
688 
689 	csr32w(ctlr, Reset, 1);
690 
691 	/* Disable interrupts */
692 	ctlr->ie = 0;
693 	csr32w(ctlr, Imr, 0);
694 	csr32w(ctlr, Isr, ~0);
695 	csr32w(ctlr, FhIsr, ~0);
696 
697 	/* Stop scheduler */
698 	if(ctlr->type != Type4965)
699 		prphwrite(ctlr, SchedTxFact5000, 0);
700 	else
701 		prphwrite(ctlr, SchedTxFact4965, 0);
702 
703 	/* Stop TX ring */
704 	if(niclock(ctlr) == nil){
705 		for(i = (ctlr->type != Type4965) ? 7 : 6; i >= 0; i--){
706 			csr32w(ctlr, FhTxConfig + i*32, 0);
707 			for(j = 0; j < 200; j++){
708 				if(csr32r(ctlr, FhTxStatus) & (0x10000<<i))
709 					break;
710 				delay(10);
711 			}
712 		}
713 		nicunlock(ctlr);
714 	}
715 
716 	/* Stop RX ring */
717 	if(niclock(ctlr) == nil){
718 		csr32w(ctlr, FhRxConfig, 0);
719 		for(j = 0; j < 200; j++){
720 			if(csr32r(ctlr, FhRxStatus) & 0x1000000)
721 				break;
722 			delay(10);
723 		}
724 		nicunlock(ctlr);
725 	}
726 
727 	/* Disable DMA */
728 	if(niclock(ctlr) == nil){
729 		prphwrite(ctlr, ApmgClkDis, DmaClkRqt);
730 		nicunlock(ctlr);
731 	}
732 	delay(5);
733 
734 	/* Stop busmaster DMA activity. */
735 	csr32w(ctlr, Reset, csr32r(ctlr, Reset) | (1<<9));
736 	for(j = 0; j < 100; j++){
737 		if(csr32r(ctlr, Reset) & (1<<8))
738 			break;
739 		delay(10);
740 	}
741 
742 	/* Reset the entire device. */
743 	csr32w(ctlr, Reset, csr32r(ctlr, Reset) | (1<<7));
744 	delay(10);
745 
746 	/* Clear "initialization complete" bit. */
747 	csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) & ~InitDone);
748 
749 	ctlr->power = 0;
750 }
751 
752 static char*
rominit(Ctlr * ctlr)753 rominit(Ctlr *ctlr)
754 {
755 	uint prev, last;
756 	uchar buf[2];
757 	char *err;
758 	int i;
759 
760 	ctlr->eeprom.otp = 0;
761 	ctlr->eeprom.off = 0;
762 	if(ctlr->type < Type1000 || (csr32r(ctlr, OtpromGp) & DevSelOtp) == 0)
763 		return nil;
764 
765 	/* Wait for clock stabilization before accessing prph. */
766 	if((err = clockwait(ctlr)) != nil)
767 		return err;
768 
769 	if((err = niclock(ctlr)) != nil)
770 		return err;
771 	prphwrite(ctlr, ApmgPs, prphread(ctlr, ApmgPs) | ResetReq);
772 	delay(5);
773 	prphwrite(ctlr, ApmgPs, prphread(ctlr, ApmgPs) & ~ResetReq);
774 	nicunlock(ctlr);
775 
776 	/* Set auto clock gate disable bit for HW with OTP shadow RAM. */
777 	if(ctlr->type != Type1000)
778 		csr32w(ctlr, Dbglinkpwrmgmt, csr32r(ctlr, Dbglinkpwrmgmt) | (1<<31));
779 
780 	csr32w(ctlr, EepromGp, csr32r(ctlr, EepromGp) & ~0x00000180);
781 
782 	/* Clear ECC status. */
783 	csr32w(ctlr, OtpromGp, csr32r(ctlr, OtpromGp) | (EccCorrStts | EccUncorrStts));
784 
785 	ctlr->eeprom.otp = 1;
786 	if(ctlr->type != Type1000)
787 		return nil;
788 
789 	/* Switch to absolute addressing mode. */
790 	csr32w(ctlr, OtpromGp, csr32r(ctlr, OtpromGp) & ~RelativeAccess);
791 
792 	/*
793 	 * Find the block before last block (contains the EEPROM image)
794 	 * for HW without OTP shadow RAM.
795 	 */
796 	prev = last = 0;
797 	for(i=0; i<3; i++){
798 		if((err = eepromread(ctlr, buf, 2, last)) != nil)
799 			return err;
800 		if(get16(buf) == 0)
801 			break;
802 		prev = last;
803 		last = get16(buf);
804 	}
805 	if(i == 0 || i >= 3)
806 		return "rominit: missing eeprom image";
807 
808 	ctlr->eeprom.off = prev+1;
809 	return nil;
810 }
811 
812 static int
iwlinit(Ether * edev)813 iwlinit(Ether *edev)
814 {
815 	Ctlr *ctlr;
816 	char *err;
817 	uchar b[4];
818 	uint u, caloff, regoff;
819 
820 	ctlr = edev->ctlr;
821 	if((err = handover(ctlr)) != nil)
822 		goto Err;
823 	if((err = poweron(ctlr)) != nil)
824 		goto Err;
825 	if((csr32r(ctlr, EepromGp) & 0x7) == 0){
826 		err = "bad rom signature";
827 		goto Err;
828 	}
829 	if((err = eepromlock(ctlr)) != nil)
830 		goto Err;
831 	if((err = rominit(ctlr)) != nil)
832 		goto Err2;
833 	if((err = eepromread(ctlr, edev->ea, sizeof(edev->ea), 0x15)) != nil){
834 		eepromunlock(ctlr);
835 		goto Err;
836 	}
837 	if((err = eepromread(ctlr, b, 2, 0x048)) != nil){
838 	Err2:
839 		eepromunlock(ctlr);
840 		goto Err;
841 	}
842 	u = get16(b);
843 	ctlr->rfcfg.type = u & 3;	u >>= 2;
844 	ctlr->rfcfg.step = u & 3;	u >>= 2;
845 	ctlr->rfcfg.dash = u & 3;	u >>= 4;
846 	ctlr->rfcfg.txantmask = u & 15;	u >>= 4;
847 	ctlr->rfcfg.rxantmask = u & 15;
848 	if((err = eepromread(ctlr, b, 2, 0x66)) != nil)
849 		goto Err2;
850 	regoff = get16(b);
851 	if((err = eepromread(ctlr, b, 4, regoff+1)) != nil)
852 		goto Err2;
853 	strncpy(ctlr->eeprom.regdom, (char*)b, 4);
854 	ctlr->eeprom.regdom[4] = 0;
855 	if((err = eepromread(ctlr, b, 2, 0x67)) != nil)
856 		goto Err2;
857 	caloff = get16(b);
858 	if((err = eepromread(ctlr, b, 4, caloff)) != nil)
859 		goto Err2;
860 	ctlr->eeprom.version = b[0];
861 	ctlr->eeprom.type = b[1];
862 	ctlr->eeprom.volt = get16(b+2);
863 
864 	ctlr->eeprom.temp = 0;
865 	ctlr->eeprom.rawtemp = 0;
866 	if(ctlr->type == Type2030){
867 		if((err = eepromread(ctlr, b, 2, caloff + 0x12a)) != nil)
868 			goto Err2;
869 		ctlr->eeprom.temp = get16(b);
870 		if((err = eepromread(ctlr, b, 2, caloff + 0x12b)) != nil)
871 			goto Err2;
872 		ctlr->eeprom.rawtemp = get16(b);
873 	}
874 
875 	if(ctlr->type != Type4965 && ctlr->type != Type5150){
876 		if((err = eepromread(ctlr, b, 4, caloff + 0x128)) != nil)
877 			goto Err2;
878 		ctlr->eeprom.crystal = get32(b);
879 	}
880 	eepromunlock(ctlr);
881 
882 	switch(ctlr->type){
883 	case Type4965:
884 		ctlr->rfcfg.txantmask = 3;
885 		ctlr->rfcfg.rxantmask = 7;
886 		break;
887 	case Type5100:
888 		ctlr->rfcfg.txantmask = 2;
889 		ctlr->rfcfg.rxantmask = 3;
890 		break;
891 	case Type6000:
892 		if(ctlr->pdev->did == 0x422c || ctlr->pdev->did == 0x4230){
893 			ctlr->rfcfg.txantmask = 6;
894 			ctlr->rfcfg.rxantmask = 6;
895 		}
896 		break;
897 	}
898 	poweroff(ctlr);
899 	return 0;
900 Err:
901 	print("iwlinit: %s\n", err);
902 	poweroff(ctlr);
903 	return -1;
904 }
905 
906 static char*
crackfw(FWImage * i,uchar * data,uint size,int alt)907 crackfw(FWImage *i, uchar *data, uint size, int alt)
908 {
909 	uchar *p, *e;
910 	FWSect *s;
911 
912 	memset(i, 0, sizeof(*i));
913 	if(size < 4){
914 Tooshort:
915 		return "firmware image too short";
916 	}
917 	p = data;
918 	e = p + size;
919 	i->rev = get32(p); p += 4;
920 	if(i->rev == 0){
921 		uvlong altmask;
922 
923 		if(size < (4+64+4+4+8))
924 			goto Tooshort;
925 		if(memcmp(p, "IWL\n", 4) != 0)
926 			return "bad firmware signature";
927 		p += 4;
928 		strncpy(i->descr, (char*)p, 64);
929 		i->descr[64] = 0;
930 		p += 64;
931 		i->rev = get32(p); p += 4;
932 		i->build = get32(p); p += 4;
933 		altmask = get32(p); p += 4;
934 		altmask |= (uvlong)get32(p) << 32; p += 4;
935 		while(alt > 0 && (altmask & (1ULL<<alt)) == 0)
936 			alt--;
937 		while(p < e){
938 			FWSect dummy;
939 
940 			if((p + 2+2+4) > e)
941 				goto Tooshort;
942 			switch(get16(p)){
943 			case 1:	s = &i->main.text; break;
944 			case 2: s = &i->main.data; break;
945 			case 3: s = &i->init.text; break;
946 			case 4: s = &i->init.data; break;
947 			case 5: s = &i->boot.text; break;
948 			default:s = &dummy;
949 			}
950 			p += 2;
951 			if(get16(p) != 0 && get16(p) != alt)
952 				s = &dummy;
953 			p += 2;
954 			s->size = get32(p); p += 4;
955 			s->data = p;
956 			if((p + s->size) > e)
957 				goto Tooshort;
958 			p += (s->size + 3) & ~3;
959 		}
960 	} else {
961 		if(((i->rev>>8) & 0xFF) < 2)
962 			return "need firmware api >= 2";
963 		if(((i->rev>>8) & 0xFF) >= 3){
964 			i->build = get32(p); p += 4;
965 		}
966 		if((p + 5*4) > e)
967 			goto Tooshort;
968 		i->main.text.size = get32(p); p += 4;
969 		i->main.data.size = get32(p); p += 4;
970 		i->init.text.size = get32(p); p += 4;
971 		i->init.data.size = get32(p); p += 4;
972 		i->boot.text.size = get32(p); p += 4;
973 		i->main.text.data = p; p += i->main.text.size;
974 		i->main.data.data = p; p += i->main.data.size;
975 		i->init.text.data = p; p += i->init.text.size;
976 		i->init.data.data = p; p += i->init.data.size;
977 		i->boot.text.data = p; p += i->boot.text.size;
978 		if(p > e)
979 			goto Tooshort;
980 	}
981 	return 0;
982 }
983 
984 static FWImage*
readfirmware(char * name)985 readfirmware(char *name)
986 {
987 	uchar dirbuf[sizeof(Dir)+100], *data;
988 	char buf[128], *err;
989 	FWImage *fw;
990 	int n, r;
991 	Chan *c;
992 	Dir d;
993 
994 	if(!iseve())
995 		error(Eperm);
996 	if(!waserror()){
997 		snprint(buf, sizeof buf, "/boot/%s", name);
998 		c = namec(buf, Aopen, OREAD, 0);
999 		poperror();
1000 	} else {
1001 		snprint(buf, sizeof buf, "/lib/firmware/%s", name);
1002 		c = namec(buf, Aopen, OREAD, 0);
1003 	}
1004 	if(waserror()){
1005 		cclose(c);
1006 		nexterror();
1007 	}
1008 	n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf);
1009 	if(n <= 0)
1010 		error("can't stat firmware");
1011 	convM2D(dirbuf, n, &d, nil);
1012 	fw = smalloc(sizeof(*fw) + 16 + d.length);
1013 	data = (uchar*)(fw+1);
1014 	if(waserror()){
1015 		free(fw);
1016 		nexterror();
1017 	}
1018 	r = 0;
1019 	while(r < d.length){
1020 		n = devtab[c->type]->read(c, data+r, d.length-r, (vlong)r);
1021 		if(n <= 0)
1022 			break;
1023 		r += n;
1024 	}
1025 	if((err = crackfw(fw, data, r, 1)) != nil)
1026 		error(err);
1027 	poperror();
1028 	poperror();
1029 	cclose(c);
1030 	return fw;
1031 }
1032 
1033 
1034 static int
gotirq(void * arg)1035 gotirq(void *arg)
1036 {
1037 	Ctlr *ctlr = arg;
1038 	return (ctlr->wait.m & ctlr->wait.w) != 0;
1039 }
1040 
1041 static u32int
irqwait(Ctlr * ctlr,u32int mask,int timeout)1042 irqwait(Ctlr *ctlr, u32int mask, int timeout)
1043 {
1044 	u32int r;
1045 
1046 	ilock(ctlr);
1047 	r = ctlr->wait.m & mask;
1048 	if(r == 0){
1049 		ctlr->wait.w = mask;
1050 		iunlock(ctlr);
1051 		if(!waserror()){
1052 			tsleep(&ctlr->wait, gotirq, ctlr, timeout);
1053 			poperror();
1054 		}
1055 		ilock(ctlr);
1056 		ctlr->wait.w = 0;
1057 		r = ctlr->wait.m & mask;
1058 	}
1059 	ctlr->wait.m &= ~r;
1060 	iunlock(ctlr);
1061 	return r;
1062 }
1063 
1064 static int
rbplant(Ctlr * ctlr,int i)1065 rbplant(Ctlr *ctlr, int i)
1066 {
1067 	Block *b;
1068 
1069 	b = iallocb(Rbufsize + 256);
1070 	if(b == nil)
1071 		return -1;
1072 	b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, 256);
1073 	memset(b->rp, 0, Rdscsize);
1074 	ctlr->rx.b[i] = b;
1075 	ctlr->rx.p[i] = PCIWADDR(b->rp) >> 8;
1076 	return 0;
1077 }
1078 
1079 static char*
initring(Ctlr * ctlr)1080 initring(Ctlr *ctlr)
1081 {
1082 	RXQ *rx;
1083 	TXQ *tx;
1084 	int i, q;
1085 
1086 	rx = &ctlr->rx;
1087 	if(rx->b == nil)
1088 		rx->b = malloc(sizeof(Block*) * Nrx);
1089 	if(rx->p == nil)
1090 		rx->p = mallocalign(sizeof(u32int) * Nrx, 256, 0, 0);
1091 	if(rx->s == nil)
1092 		rx->s = mallocalign(Rstatsize, 16, 0, 0);
1093 	if(rx->b == nil || rx->p == nil || rx->s == nil)
1094 		return "no memory for rx ring";
1095 	memset(ctlr->rx.s, 0, Rstatsize);
1096 	for(i=0; i<Nrx; i++){
1097 		rx->p[i] = 0;
1098 		if(rx->b[i] != nil){
1099 			freeb(rx->b[i]);
1100 			rx->b[i] = nil;
1101 		}
1102 		if(rbplant(ctlr, i) < 0)
1103 			return "no memory for rx descriptors";
1104 	}
1105 	rx->i = 0;
1106 
1107 	if(ctlr->sched.s == nil)
1108 		ctlr->sched.s = mallocalign(512 * nelem(ctlr->tx) * 2, 1024, 0, 0);
1109 	if(ctlr->sched.s == nil)
1110 		return "no memory for sched buffer";
1111 	memset(ctlr->sched.s, 0, 512 * nelem(ctlr->tx));
1112 
1113 	for(q=0; q<nelem(ctlr->tx); q++){
1114 		tx = &ctlr->tx[q];
1115 		if(tx->b == nil)
1116 			tx->b = malloc(sizeof(Block*) * Ntx);
1117 		if(tx->d == nil)
1118 			tx->d = mallocalign(Tdscsize * Ntx, 256, 0, 0);
1119 		if(tx->c == nil)
1120 			tx->c = mallocalign(Tcmdsize * Ntx, 4, 0, 0);
1121 		if(tx->b == nil || tx->d == nil || tx->c == nil)
1122 			return "no memory for tx ring";
1123 		memset(tx->d, 0, Tdscsize * Ntx);
1124 		memset(tx->c, 0, Tcmdsize * Ntx);
1125 		for(i=0; i<Ntx; i++){
1126 			if(tx->b[i] != nil){
1127 				freeb(tx->b[i]);
1128 				tx->b[i] = nil;
1129 			}
1130 		}
1131 		tx->i = 0;
1132 		tx->n = 0;
1133 		tx->lastcmd = 0;
1134 	}
1135 
1136 	if(ctlr->kwpage == nil)
1137 		ctlr->kwpage = mallocalign(4096, 4096, 0, 0);
1138 	if(ctlr->kwpage == nil)
1139 		return "no memory for kwpage";
1140 	memset(ctlr->kwpage, 0, 4096);
1141 
1142 	return nil;
1143 }
1144 
1145 static char*
reset(Ctlr * ctlr)1146 reset(Ctlr *ctlr)
1147 {
1148 	char *err;
1149 	int i, q;
1150 
1151 	if(ctlr->power)
1152 		poweroff(ctlr);
1153 	if((err = initring(ctlr)) != nil)
1154 		return err;
1155 	if((err = poweron(ctlr)) != nil)
1156 		return err;
1157 
1158 	if((err = niclock(ctlr)) != nil)
1159 		return err;
1160 	prphwrite(ctlr, ApmgPs, (prphread(ctlr, ApmgPs) & ~PwrSrcMask) | PwrSrcVMain);
1161 	nicunlock(ctlr);
1162 
1163 	csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) | RadioSi | MacSi);
1164 
1165 	if((err = niclock(ctlr)) != nil)
1166 		return err;
1167 	if(ctlr->type != Type4965)
1168 		prphwrite(ctlr, ApmgPs, prphread(ctlr, ApmgPs) | EarlyPwroffDis);
1169 	if(ctlr->type == Type1000){
1170 		/*
1171 		 * Select first Switching Voltage Regulator (1.32V) to
1172 		 * solve a stability issue related to noisy DC2DC line
1173 		 * in the silicon of 1000 Series.
1174 		 */
1175 		prphwrite(ctlr, ApmgDigitalSvr,
1176 			(prphread(ctlr, ApmgDigitalSvr) & ~(0xf<<5)) | (3<<5));
1177 	}
1178 	nicunlock(ctlr);
1179 
1180 	if((err = niclock(ctlr)) != nil)
1181 		return err;
1182 	if((ctlr->type == Type6005 || ctlr->type == Type6050) && ctlr->eeprom.version == 6)
1183 		csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvCalV6);
1184 	if(ctlr->type == Type6005)
1185 		csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrv1X2);
1186 	if(ctlr->type == Type2030)
1187 		csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvRadioIqInvert);
1188 	nicunlock(ctlr);
1189 
1190 	if((err = niclock(ctlr)) != nil)
1191 		return err;
1192 	csr32w(ctlr, FhRxConfig, 0);
1193 	csr32w(ctlr, FhRxWptr, 0);
1194 	csr32w(ctlr, FhRxBase, PCIWADDR(ctlr->rx.p) >> 8);
1195 	csr32w(ctlr, FhStatusWptr, PCIWADDR(ctlr->rx.s) >> 4);
1196 	csr32w(ctlr, FhRxConfig,
1197 		FhRxConfigEna |
1198 		FhRxConfigIgnRxfEmpty |
1199 		FhRxConfigIrqDstHost |
1200 		FhRxConfigSingleFrame |
1201 		(Nrxlog << FhRxConfigNrbdShift));
1202 	csr32w(ctlr, FhRxWptr, (Nrx-1) & ~7);
1203 	nicunlock(ctlr);
1204 
1205 	if((err = niclock(ctlr)) != nil)
1206 		return err;
1207 	if(ctlr->type != Type4965)
1208 		prphwrite(ctlr, SchedTxFact5000, 0);
1209 	else
1210 		prphwrite(ctlr, SchedTxFact4965, 0);
1211 	csr32w(ctlr, FhKwAddr, PCIWADDR(ctlr->kwpage) >> 4);
1212 	for(q = (ctlr->type != Type4965) ? 19 : 15; q >= 0; q--)
1213 		csr32w(ctlr, FhCbbcQueue + q*4, PCIWADDR(ctlr->tx[q].d) >> 8);
1214 	nicunlock(ctlr);
1215 
1216 	for(i = (ctlr->type != Type4965) ? 7 : 6; i >= 0; i--)
1217 		csr32w(ctlr, FhTxConfig + i*32, FhTxConfigDmaEna | FhTxConfigDmaCreditEna);
1218 
1219 	csr32w(ctlr, UcodeGp1Clr, UcodeGp1RfKill);
1220 	csr32w(ctlr, UcodeGp1Clr, UcodeGp1CmdBlocked);
1221 
1222 	ctlr->broken = 0;
1223 	ctlr->wait.m = 0;
1224 	ctlr->wait.w = 0;
1225 
1226 	ctlr->ie = Idefmask;
1227 	csr32w(ctlr, Imr, ctlr->ie);
1228 	csr32w(ctlr, Isr, ~0);
1229 
1230 	if(ctlr->type >= Type6000)
1231 		csr32w(ctlr, ShadowRegCtrl, csr32r(ctlr, ShadowRegCtrl) | 0x800fffff);
1232 
1233 	return nil;
1234 }
1235 
1236 static char*
sendbtcoexadv(Ctlr * ctlr)1237 sendbtcoexadv(Ctlr *ctlr)
1238 {
1239 	static u32int btcoex3wire[12] = {
1240 		0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
1241 		0xcc00ff28,	0x0000aaaa, 0xcc00aaaa, 0x0000aaaa,
1242 		0xc0004000, 0x00004000, 0xf0005000, 0xf0005000,
1243 	};
1244 
1245 	uchar c[Tcmdsize], *p;
1246 	char *err;
1247 	int i;
1248 
1249 	/* set BT config */
1250 	memset(c, 0, sizeof(c));
1251 	p = c;
1252 
1253 	if(ctlr->type == Type2030){
1254 		*p++ = 145; /* flags */
1255 		p++; /* lead time */
1256 		*p++ = 5; /* max kill */
1257 		*p++ = 1; /* bt3 t7 timer */
1258 		put32(p, 0xffff0000); /* kill ack */
1259 		p += 4;
1260 		put32(p, 0xffff0000); /* kill cts */
1261 		p += 4;
1262 		*p++ = 2; /* sample time */
1263 		*p++ = 0xc; /* bt3 t2 timer */
1264 		p += 2; /* bt4 reaction */
1265 		for (i = 0; i < nelem(btcoex3wire); i++){
1266 			put32(p, btcoex3wire[i]);
1267 			p += 4;
1268 		}
1269 		p += 2; /* bt4 decision */
1270 		put16(p, 0xff); /* valid */
1271 		p += 2;
1272 		put32(p, 0xf0); /* prio boost */
1273 		p += 4;
1274 		p++; /* reserved */
1275 		p++; /* tx prio boost */
1276 		p += 2; /* rx prio boost */
1277 	}
1278 	if((err = cmd(ctlr, 155, c, p-c)) != nil)
1279 		return err;
1280 
1281 	/* set BT priority */
1282 	memset(c, 0, sizeof(c));
1283 	p = c;
1284 
1285 	*p++ = 0x6; /* init1 */
1286 	*p++ = 0x7; /* init2 */
1287 	*p++ = 0x2; /* periodic low1 */
1288 	*p++ = 0x3; /* periodic low2 */
1289 	*p++ = 0x4; /* periodic high1 */
1290 	*p++ = 0x5; /* periodic high2 */
1291 	*p++ = 0x6; /* dtim */
1292 	*p++ = 0x8; /* scan52 */
1293 	*p++ = 0xa; /* scan24 */
1294 	p += 7; /* reserved */
1295 	if((err = cmd(ctlr, 204, c, p-c)) != nil)
1296 		return err;
1297 
1298 	/* force BT state machine change */
1299 	memset(c, 0, sizeof(c));
1300 	p = c;
1301 
1302 	*p++ = 1; /* open */
1303 	*p++ = 1; /* type */
1304 	p += 2; /* reserved */
1305 	if((err = cmd(ctlr, 205, c, p-c)) != nil)
1306 		return err;
1307 
1308 	c[0] = 0; /* open */
1309 	return cmd(ctlr, 205, c, p-c);
1310 }
1311 
1312 static char*
postboot(Ctlr * ctlr)1313 postboot(Ctlr *ctlr)
1314 {
1315 	uint ctxoff, ctxlen, dramaddr;
1316 	char *err;
1317 	int i, q;
1318 
1319 	if((err = niclock(ctlr)) != nil)
1320 		return err;
1321 
1322 	if(ctlr->type != Type4965){
1323 		dramaddr = SchedDramAddr5000;
1324 		ctxoff = SchedCtxOff5000;
1325 		ctxlen = SchedCtxLen5000;
1326 	} else {
1327 		dramaddr = SchedDramAddr4965;
1328 		ctxoff = SchedCtxOff4965;
1329 		ctxlen = SchedCtxLen4965;
1330 	}
1331 
1332 	ctlr->sched.base = prphread(ctlr, SchedSramAddr);
1333 	for(i=0; i < ctxlen; i += 4)
1334 		memwrite(ctlr, ctlr->sched.base + ctxoff + i, 0);
1335 
1336 	prphwrite(ctlr, dramaddr, PCIWADDR(ctlr->sched.s)>>10);
1337 
1338 	csr32w(ctlr, FhTxChicken, csr32r(ctlr, FhTxChicken) | 2);
1339 
1340 	if(ctlr->type != Type4965){
1341 		/* Enable chain mode for all queues, except command queue 4. */
1342 		prphwrite(ctlr, SchedQChainSel5000, 0xfffef);
1343 		prphwrite(ctlr, SchedAggrSel5000, 0);
1344 
1345 		for(q=0; q<20; q++){
1346 			prphwrite(ctlr, SchedQueueRdptr5000 + q*4, 0);
1347 			csr32w(ctlr, HbusTargWptr, q << 8);
1348 
1349 			memwrite(ctlr, ctlr->sched.base + ctxoff + q*8, 0);
1350 			/* Set scheduler window size and frame limit. */
1351 			memwrite(ctlr, ctlr->sched.base + ctxoff + q*8 + 4, 64<<16 | 64);
1352 		}
1353 		/* Enable interrupts for all our 20 queues. */
1354 		prphwrite(ctlr, SchedIntrMask5000, 0xfffff);
1355 
1356 		/* Identify TX FIFO rings (0-7). */
1357 		prphwrite(ctlr, SchedTxFact5000, 0xff);
1358 	} else {
1359 		/* Disable chain mode for all our 16 queues. */
1360 		prphwrite(ctlr, SchedQChainSel4965, 0);
1361 
1362 		for(q=0; q<16; q++) {
1363 			prphwrite(ctlr, SchedQueueRdptr4965 + q*4, 0);
1364 			csr32w(ctlr, HbusTargWptr, q << 8);
1365 
1366 			/* Set scheduler window size. */
1367 			memwrite(ctlr, ctlr->sched.base + ctxoff + q*8, 64);
1368 			/* Set scheduler window size and frame limit. */
1369 			memwrite(ctlr, ctlr->sched.base + ctxoff + q*8 + 4, 64<<16);
1370 		}
1371 		/* Enable interrupts for all our 16 queues. */
1372 		prphwrite(ctlr, SchedIntrMask4965, 0xffff);
1373 
1374 		/* Identify TX FIFO rings (0-7). */
1375 		prphwrite(ctlr, SchedTxFact4965, 0xff);
1376 	}
1377 
1378 	/* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
1379 	for(q=0; q<7; q++){
1380 		if(ctlr->type != Type4965){
1381 			static uchar qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
1382 			prphwrite(ctlr, SchedQueueStatus5000 + q*4, 0x00ff0018 | qid2fifo[q]);
1383 		} else {
1384 			static uchar qid2fifo[] = { 3, 2, 1, 0, 4, 5, 6 };
1385 			prphwrite(ctlr, SchedQueueStatus4965 + q*4, 0x0007fc01 | qid2fifo[q]<<1);
1386 		}
1387 	}
1388 	nicunlock(ctlr);
1389 
1390 	if(ctlr->type != Type4965){
1391 		uchar c[Tcmdsize];
1392 
1393 		/* disable wimax coexistance */
1394 		memset(c, 0, sizeof(c));
1395 		if((err = cmd(ctlr, 90, c, 4+4*16)) != nil)
1396 			return err;
1397 
1398 		if(ctlr->type != Type5150){
1399 			/* calibrate crystal */
1400 			memset(c, 0, sizeof(c));
1401 			c[0] = 15;	/* code */
1402 			c[1] = 0;	/* group */
1403 			c[2] = 1;	/* ngroup */
1404 			c[3] = 1;	/* isvalid */
1405 			c[4] = ctlr->eeprom.crystal;
1406 			c[5] = ctlr->eeprom.crystal>>16;
1407 			/* for some reason 8086:4238 needs a second try */
1408 			if(cmd(ctlr, 176, c, 8) != nil && (err = cmd(ctlr, 176, c, 8)) != nil)
1409 				return err;
1410 		}
1411 
1412 		if(ctlr->calib.done == 0){
1413 			/* query calibration (init firmware) */
1414 			memset(c, 0, sizeof(c));
1415 			put32(c + 0*(5*4) + 0, 0xffffffff);
1416 			put32(c + 0*(5*4) + 4, 0xffffffff);
1417 			put32(c + 0*(5*4) + 8, 0xffffffff);
1418 			put32(c + 2*(5*4) + 0, 0xffffffff);
1419 			if((err = cmd(ctlr, 101, c, (((2*(5*4))+4)*2)+4)) != nil)
1420 				return err;
1421 
1422 			/* wait to collect calibration records */
1423 			if(irqwait(ctlr, Ierr, 2000))
1424 				return "calibration failed";
1425 
1426 			if(ctlr->calib.done == 0){
1427 				print("iwl: no calibration results\n");
1428 				ctlr->calib.done = 1;
1429 			}
1430 		} else {
1431 			static uchar cmds[] = {8, 9, 11, 17, 16};
1432 
1433 			/* send calibration records (runtime firmware) */
1434 			for(q=0; q<nelem(cmds); q++){
1435 				Block *b;
1436 
1437 				i = cmds[q];
1438 				if(i == 8 && ctlr->type != Type5150 && ctlr->type != Type2030)
1439 					continue;
1440 				if(i == 17 && (ctlr->type >= Type6000 || ctlr->type == Type5150) &&
1441 					ctlr->type != Type2030)
1442 					continue;
1443 
1444 				if((b = ctlr->calib.cmd[i]) == nil)
1445 					continue;
1446 				b = copyblock(b, BLEN(b));
1447 				if((err = qcmd(ctlr, 4, 176, nil, 0, b)) != nil){
1448 					freeb(b);
1449 					return err;
1450 				}
1451 				if((err = flushq(ctlr, 4)) != nil)
1452 					return err;
1453 			}
1454 
1455 			/* temperature sensor offset */
1456 			switch (ctlr->type){
1457 			case Type6005:
1458 				memset(c, 0, sizeof(c));
1459 				c[0] = 18;
1460 				c[1] = 0;
1461 				c[2] = 1;
1462 				c[3] = 1;
1463 				put16(c + 4, 2700);
1464 				if((err = cmd(ctlr, 176, c, 4+2+2)) != nil)
1465 					return err;
1466 				break;
1467 
1468 			case Type2030:
1469 				memset(c, 0, sizeof(c));
1470 				c[0] = 18;
1471 				c[1] = 0;
1472 				c[2] = 1;
1473 				c[3] = 1;
1474 				if(ctlr->eeprom.rawtemp != 0){
1475 					put16(c + 4, ctlr->eeprom.temp);
1476 					put16(c + 6, ctlr->eeprom.rawtemp);
1477 				} else{
1478 					put16(c + 4, 2700);
1479 					put16(c + 6, 2700);
1480 				}
1481 				put16(c + 8, ctlr->eeprom.volt);
1482 				if((err = cmd(ctlr, 176, c, 4+2+2+2+2)) != nil)
1483 					return err;
1484 				break;
1485 			}
1486 
1487 			if(ctlr->type == Type6005 || ctlr->type == Type6050){
1488 				/* runtime DC calibration */
1489 				memset(c, 0, sizeof(c));
1490 				put32(c + 0*(5*4) + 0, 0xffffffff);
1491 				put32(c + 0*(5*4) + 4, 1<<1);
1492 				if((err = cmd(ctlr, 101, c, (((2*(5*4))+4)*2)+4)) != nil)
1493 					return err;
1494 			}
1495 
1496 			/* set tx antenna config */
1497 			put32(c, ctlr->rfcfg.txantmask & 7);
1498 			if((err = cmd(ctlr, 152, c, 4)) != nil)
1499 				return err;
1500 
1501 			if(ctlr->type == Type2030){
1502 				if((err = sendbtcoexadv(ctlr)) != nil)
1503 					return err;
1504 			}
1505 		}
1506 	}
1507 
1508 	return nil;
1509 }
1510 
1511 static char*
loadfirmware1(Ctlr * ctlr,u32int dst,uchar * data,int size)1512 loadfirmware1(Ctlr *ctlr, u32int dst, uchar *data, int size)
1513 {
1514 	uchar *dma;
1515 	char *err;
1516 
1517 	dma = mallocalign(size, 16, 0, 0);
1518 	if(dma == nil)
1519 		return "no memory for dma";
1520 	memmove(dma, data, size);
1521 	coherence();
1522 	if((err = niclock(ctlr)) != 0){
1523 		free(dma);
1524 		return err;
1525 	}
1526 	csr32w(ctlr, FhTxConfig + 9*32, 0);
1527 	csr32w(ctlr, FhSramAddr + 9*4, dst);
1528 	csr32w(ctlr, FhTfbdCtrl0 + 9*8, PCIWADDR(dma));
1529 	csr32w(ctlr, FhTfbdCtrl1 + 9*8, size);
1530 	csr32w(ctlr, FhTxBufStatus + 9*32,
1531 		(1<<FhTxBufStatusTbNumShift) |
1532 		(1<<FhTxBufStatusTbIdxShift) |
1533 		FhTxBufStatusTfbdValid);
1534 	csr32w(ctlr, FhTxConfig + 9*32, FhTxConfigDmaEna | FhTxConfigCirqHostEndTfd);
1535 	nicunlock(ctlr);
1536 	if(irqwait(ctlr, Ifhtx|Ierr, 5000) != Ifhtx){
1537 		free(dma);
1538 		return "dma error / timeout";
1539 	}
1540 	free(dma);
1541 	return 0;
1542 }
1543 
1544 static char*
boot(Ctlr * ctlr)1545 boot(Ctlr *ctlr)
1546 {
1547 	int i, n, size;
1548 	uchar *p, *dma;
1549 	FWImage *fw;
1550 	char *err;
1551 
1552 	fw = ctlr->fw;
1553 
1554 	if(fw->boot.text.size == 0){
1555 		if(ctlr->calib.done == 0){
1556 			if((err = loadfirmware1(ctlr, 0x00000000, fw->init.text.data, fw->init.text.size)) != nil)
1557 				return err;
1558 			if((err = loadfirmware1(ctlr, 0x00800000, fw->init.data.data, fw->init.data.size)) != nil)
1559 				return err;
1560 			csr32w(ctlr, Reset, 0);
1561 			if(irqwait(ctlr, Ierr|Ialive, 5000) != Ialive)
1562 				return "init firmware boot failed";
1563 			if((err = postboot(ctlr)) != nil)
1564 				return err;
1565 			if((err = reset(ctlr)) != nil)
1566 				return err;
1567 		}
1568 		if((err = loadfirmware1(ctlr, 0x00000000, fw->main.text.data, fw->main.text.size)) != nil)
1569 			return err;
1570 		if((err = loadfirmware1(ctlr, 0x00800000, fw->main.data.data, fw->main.data.size)) != nil)
1571 			return err;
1572 		csr32w(ctlr, Reset, 0);
1573 		if(irqwait(ctlr, Ierr|Ialive, 5000) != Ialive)
1574 			return "main firmware boot failed";
1575 		return postboot(ctlr);
1576 	}
1577 
1578 	size = ROUND(fw->init.data.size, 16) + ROUND(fw->init.text.size, 16);
1579 	dma = mallocalign(size, 16, 0, 0);
1580 	if(dma == nil)
1581 		return "no memory for dma";
1582 
1583 	if((err = niclock(ctlr)) != nil){
1584 		free(dma);
1585 		return err;
1586 	}
1587 
1588 	p = dma;
1589 	memmove(p, fw->init.data.data, fw->init.data.size);
1590 	coherence();
1591 	prphwrite(ctlr, BsmDramDataAddr, PCIWADDR(p) >> 4);
1592 	prphwrite(ctlr, BsmDramDataSize, fw->init.data.size);
1593 	p += ROUND(fw->init.data.size, 16);
1594 	memmove(p, fw->init.text.data, fw->init.text.size);
1595 	coherence();
1596 	prphwrite(ctlr, BsmDramTextAddr, PCIWADDR(p) >> 4);
1597 	prphwrite(ctlr, BsmDramTextSize, fw->init.text.size);
1598 
1599 	nicunlock(ctlr);
1600 	if((err = niclock(ctlr)) != nil){
1601 		free(dma);
1602 		return err;
1603 	}
1604 
1605 	p = fw->boot.text.data;
1606 	n = fw->boot.text.size/4;
1607 	for(i=0; i<n; i++, p += 4)
1608 		prphwrite(ctlr, BsmSramBase+i*4, get32(p));
1609 
1610 	prphwrite(ctlr, BsmWrMemSrc, 0);
1611 	prphwrite(ctlr, BsmWrMemDst, 0);
1612 	prphwrite(ctlr, BsmWrDwCount, n);
1613 
1614 	prphwrite(ctlr, BsmWrCtrl, 1<<31);
1615 
1616 	for(i=0; i<1000; i++){
1617 		if((prphread(ctlr, BsmWrCtrl) & (1<<31)) == 0)
1618 			break;
1619 		delay(10);
1620 	}
1621 	if(i == 1000){
1622 		nicunlock(ctlr);
1623 		free(dma);
1624 		return "bootcode timeout";
1625 	}
1626 
1627 	prphwrite(ctlr, BsmWrCtrl, 1<<30);
1628 	nicunlock(ctlr);
1629 
1630 	csr32w(ctlr, Reset, 0);
1631 	if(irqwait(ctlr, Ierr|Ialive, 5000) != Ialive){
1632 		free(dma);
1633 		return "init firmware boot failed";
1634 	}
1635 	free(dma);
1636 
1637 	size = ROUND(fw->main.data.size, 16) + ROUND(fw->main.text.size, 16);
1638 	dma = mallocalign(size, 16, 0, 0);
1639 	if(dma == nil)
1640 		return "no memory for dma";
1641 	if((err = niclock(ctlr)) != nil){
1642 		free(dma);
1643 		return err;
1644 	}
1645 	p = dma;
1646 	memmove(p, fw->main.data.data, fw->main.data.size);
1647 	coherence();
1648 	prphwrite(ctlr, BsmDramDataAddr, PCIWADDR(p) >> 4);
1649 	prphwrite(ctlr, BsmDramDataSize, fw->main.data.size);
1650 	p += ROUND(fw->main.data.size, 16);
1651 	memmove(p, fw->main.text.data, fw->main.text.size);
1652 	coherence();
1653 	prphwrite(ctlr, BsmDramTextAddr, PCIWADDR(p) >> 4);
1654 	prphwrite(ctlr, BsmDramTextSize, fw->main.text.size | (1<<31));
1655 	nicunlock(ctlr);
1656 
1657 	if(irqwait(ctlr, Ierr|Ialive, 5000) != Ialive){
1658 		free(dma);
1659 		return "main firmware boot failed";
1660 	}
1661 	free(dma);
1662 	return postboot(ctlr);
1663 }
1664 
1665 static int
txqready(void * arg)1666 txqready(void *arg)
1667 {
1668 	TXQ *q = arg;
1669 	return q->n < Ntx;
1670 }
1671 
1672 static char*
qcmd(Ctlr * ctlr,uint qid,uint code,uchar * data,int size,Block * block)1673 qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
1674 {
1675 	uchar *d, *c;
1676 	TXQ *q;
1677 
1678 	assert(qid < nelem(ctlr->tx));
1679 	assert(size <= Tcmdsize-4);
1680 
1681 	ilock(ctlr);
1682 	q = &ctlr->tx[qid];
1683 	while(q->n >= Ntx && !ctlr->broken){
1684 		iunlock(ctlr);
1685 		qlock(q);
1686 		if(!waserror()){
1687 			tsleep(q, txqready, q, 10);
1688 			poperror();
1689 		}
1690 		qunlock(q);
1691 		ilock(ctlr);
1692 	}
1693 	if(ctlr->broken){
1694 		iunlock(ctlr);
1695 		return "qcmd: broken";
1696 	}
1697 	q->n++;
1698 
1699 	q->lastcmd = code;
1700 	q->b[q->i] = block;
1701 	c = q->c + q->i * Tcmdsize;
1702 	d = q->d + q->i * Tdscsize;
1703 
1704 	/* build command */
1705 	c[0] = code;
1706 	c[1] = 0;	/* flags */
1707 	c[2] = q->i;
1708 	c[3] = qid;
1709 
1710 	if(size > 0)
1711 		memmove(c+4, data, size);
1712 
1713 	size += 4;
1714 
1715 	/* build descriptor */
1716 	*d++ = 0;
1717 	*d++ = 0;
1718 	*d++ = 0;
1719 	*d++ = 1 + (block != nil); /* nsegs */
1720 	put32(d, PCIWADDR(c));	d += 4;
1721 	put16(d, size << 4); d += 2;
1722 	if(block != nil){
1723 		size = BLEN(block);
1724 		put32(d, PCIWADDR(block->rp)); d += 4;
1725 		put16(d, size << 4);
1726 	}
1727 
1728 	coherence();
1729 
1730 	q->i = (q->i+1) % Ntx;
1731 	csr32w(ctlr, HbusTargWptr, (qid<<8) | q->i);
1732 
1733 	iunlock(ctlr);
1734 
1735 	return nil;
1736 }
1737 
1738 static int
txqempty(void * arg)1739 txqempty(void *arg)
1740 {
1741 	TXQ *q = arg;
1742 	return q->n == 0;
1743 }
1744 
1745 static char*
flushq(Ctlr * ctlr,uint qid)1746 flushq(Ctlr *ctlr, uint qid)
1747 {
1748 	TXQ *q;
1749 	int i;
1750 
1751 	q = &ctlr->tx[qid];
1752 	qlock(q);
1753 	for(i = 0; i < 200 && !ctlr->broken; i++){
1754 		if(txqempty(q)){
1755 			qunlock(q);
1756 			return nil;
1757 		}
1758 		if(!waserror()){
1759 			tsleep(q, txqempty, q, 10);
1760 			poperror();
1761 		}
1762 	}
1763 	qunlock(q);
1764 	if(ctlr->broken)
1765 		return "flushq: broken";
1766 	return "flushq: timeout";
1767 }
1768 
1769 static char*
cmd(Ctlr * ctlr,uint code,uchar * data,int size)1770 cmd(Ctlr *ctlr, uint code, uchar *data, int size)
1771 {
1772 	char *err;
1773 
1774 	if(0) print("cmd %ud\n", code);
1775 	if((err = qcmd(ctlr, 4, code, data, size, nil)) != nil)
1776 		return err;
1777 	return flushq(ctlr, 4);
1778 }
1779 
1780 static void
setled(Ctlr * ctlr,int which,int on,int off)1781 setled(Ctlr *ctlr, int which, int on, int off)
1782 {
1783 	uchar c[8];
1784 
1785 	csr32w(ctlr, Led, csr32r(ctlr, Led) & ~LedBsmCtrl);
1786 
1787 	memset(c, 0, sizeof(c));
1788 	put32(c, 10000);
1789 	c[4] = which;
1790 	c[5] = on;
1791 	c[6] = off;
1792 	cmd(ctlr, 72, c, sizeof(c));
1793 }
1794 
1795 static void
addnode(Ctlr * ctlr,uchar id,uchar * addr)1796 addnode(Ctlr *ctlr, uchar id, uchar *addr)
1797 {
1798 	uchar c[Tcmdsize], *p;
1799 
1800 	memset(p = c, 0, sizeof(c));
1801 	*p++ = 0;	/* control (1 = update) */
1802 	p += 3;		/* reserved */
1803 	memmove(p, addr, 6);
1804 	p += 6;
1805 	p += 2;		/* reserved */
1806 	*p++ = id;	/* node id */
1807 	p++;		/* flags */
1808 	p += 2;		/* reserved */
1809 	p += 2;		/* kflags */
1810 	p++;		/* tcs2 */
1811 	p++;		/* reserved */
1812 	p += 5*2;	/* ttak */
1813 	p++;		/* kid */
1814 	p++;		/* reserved */
1815 	p += 16;	/* key */
1816 	if(ctlr->type != Type4965){
1817 		p += 8;		/* tcs */
1818 		p += 8;		/* rxmic */
1819 		p += 8;		/* txmic */
1820 	}
1821 	p += 4;		/* htflags */
1822 	p += 4;		/* mask */
1823 	p += 2;		/* disable tid */
1824 	p += 2;		/* reserved */
1825 	p++;		/* add ba tid */
1826 	p++;		/* del ba tid */
1827 	p += 2;		/* add ba ssn */
1828 	p += 4;		/* reserved */
1829 	cmd(ctlr, 24, c, p - c);
1830 }
1831 
1832 static void
rxon(Ether * edev,Wnode * bss)1833 rxon(Ether *edev, Wnode *bss)
1834 {
1835 	uchar c[Tcmdsize], *p;
1836 	int filter, flags;
1837 	Ctlr *ctlr;
1838 	char *err;
1839 
1840 	ctlr = edev->ctlr;
1841 	filter = FilterNoDecrypt | FilterMulticast | FilterBeacon;
1842 	if(ctlr->prom){
1843 		filter |= FilterPromisc;
1844 		if(bss != nil)
1845 			ctlr->channel = bss->channel;
1846 		bss = nil;
1847 	}
1848 	flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto;
1849 	if(bss != nil){
1850 		if(bss->cap & (1<<5))
1851 			flags |= RFlagShPreamble;
1852 		if(bss->cap & (1<<10))
1853 			flags |= RFlagShSlot;
1854 		ctlr->channel = bss->channel;
1855 		memmove(ctlr->bssid, bss->bssid, Eaddrlen);
1856 		ctlr->aid = bss->aid;
1857 		if(ctlr->aid != 0){
1858 			filter |= FilterBSS;
1859 			filter &= ~FilterBeacon;
1860 			ctlr->bssnodeid = -1;
1861 		} else
1862 			ctlr->bcastnodeid = -1;
1863 	} else {
1864 		memmove(ctlr->bssid, edev->bcast, Eaddrlen);
1865 		ctlr->aid = 0;
1866 		ctlr->bcastnodeid = -1;
1867 		ctlr->bssnodeid = -1;
1868 	}
1869 
1870 	if(ctlr->aid != 0)
1871 		setled(ctlr, 2, 0, 1);		/* on when associated */
1872 	else if(memcmp(ctlr->bssid, edev->bcast, Eaddrlen) != 0)
1873 		setled(ctlr, 2, 10, 10);	/* slow blink when connecting */
1874 	else
1875 		setled(ctlr, 2, 5, 5);		/* fast blink when scanning */
1876 
1877 	if(ctlr->wifi->debug)
1878 		print("#l%d: rxon: bssid %E, aid %x, channel %d, filter %x, flags %x\n",
1879 			edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, filter, flags);
1880 
1881 	memset(p = c, 0, sizeof(c));
1882 	memmove(p, edev->ea, 6); p += 8;	/* myaddr */
1883 	memmove(p, ctlr->bssid, 6); p += 8;	/* bssid */
1884 	memmove(p, edev->ea, 6); p += 8;	/* wlap */
1885 	*p++ = 3;				/* mode (STA) */
1886 	*p++ = 0;				/* air (?) */
1887 	/* rxchain */
1888 	put16(p, ((ctlr->rfcfg.rxantmask & 7)<<1) | (2<<10) | (2<<12));
1889 	p += 2;
1890 	*p++ = 0xff;				/* ofdm mask (not yet negotiated) */
1891 	*p++ = 0x0f;				/* cck mask (not yet negotiated) */
1892 	put16(p, ctlr->aid & 0x3fff);
1893 	p += 2;					/* aid */
1894 	put32(p, flags);
1895 	p += 4;
1896 	put32(p, filter);
1897 	p += 4;
1898 	*p++ = ctlr->channel;
1899 	p++;					/* reserved */
1900 	*p++ = 0xff;				/* ht single mask */
1901 	*p++ = 0xff;				/* ht dual mask */
1902 	if(ctlr->type != Type4965){
1903 		*p++ = 0xff;			/* ht triple mask */
1904 		p++;				/* reserved */
1905 		put16(p, 0); p += 2;		/* acquisition */
1906 		p += 2;				/* reserved */
1907 	}
1908 	if((err = cmd(ctlr, 16, c, p - c)) != nil){
1909 		print("rxon: %s\n", err);
1910 		return;
1911 	}
1912 
1913 	if(ctlr->bcastnodeid == -1){
1914 		ctlr->bcastnodeid = (ctlr->type != Type4965) ? 15 : 31;
1915 		addnode(ctlr, ctlr->bcastnodeid, edev->bcast);
1916 	}
1917 	if(ctlr->bssnodeid == -1 && bss != nil && ctlr->aid != 0){
1918 		ctlr->bssnodeid = 0;
1919 		addnode(ctlr, ctlr->bssnodeid, bss->bssid);
1920 	}
1921 }
1922 
1923 static struct ratetab {
1924 	uchar	rate;
1925 	uchar	plcp;
1926 	uchar	flags;
1927 } ratetab[] = {
1928 	{   2,  10, RFlagCCK },
1929 	{   4,  20, RFlagCCK },
1930 	{  11,  55, RFlagCCK },
1931 	{  22, 110, RFlagCCK },
1932 	{  12, 0xd, 0 },
1933 	{  18, 0xf, 0 },
1934 	{  24, 0x5, 0 },
1935 	{  36, 0x7, 0 },
1936 	{  48, 0x9, 0 },
1937 	{  72, 0xb, 0 },
1938 	{  96, 0x1, 0 },
1939 	{ 108, 0x3, 0 },
1940 	{ 120, 0x3, 0 }
1941 };
1942 
1943 static uchar iwlrates[] = {
1944 	0x80 | 2,
1945 	0x80 | 4,
1946 	0x80 | 11,
1947 	0x80 | 22,
1948 	0x80 | 12,
1949 	0x80 | 18,
1950 	0x80 | 24,
1951 	0x80 | 36,
1952 	0x80 | 48,
1953 	0x80 | 72,
1954 	0x80 | 96,
1955 	0x80 | 108,
1956 	0x80 | 120,
1957 
1958 	0
1959 };
1960 
1961 enum {
1962 	TFlagNeedProtection	= 1<<0,
1963 	TFlagNeedRTS		= 1<<1,
1964 	TFlagNeedCTS		= 1<<2,
1965 	TFlagNeedACK		= 1<<3,
1966 	TFlagLinkq		= 1<<4,
1967 	TFlagImmBa		= 1<<6,
1968 	TFlagFullTxOp		= 1<<7,
1969 	TFlagBtDis		= 1<<12,
1970 	TFlagAutoSeq		= 1<<13,
1971 	TFlagMoreFrag		= 1<<14,
1972 	TFlagInsertTs		= 1<<16,
1973 	TFlagNeedPadding	= 1<<20,
1974 };
1975 
1976 static void
transmit(Wifi * wifi,Wnode * wn,Block * b)1977 transmit(Wifi *wifi, Wnode *wn, Block *b)
1978 {
1979 	int flags, nodeid, rate, ant;
1980 	uchar c[Tcmdsize], *p;
1981 	Ether *edev;
1982 	Ctlr *ctlr;
1983 	Wifipkt *w;
1984 	char *err;
1985 
1986 	edev = wifi->ether;
1987 	ctlr = edev->ctlr;
1988 
1989 	qlock(ctlr);
1990 	if(ctlr->attached == 0 || ctlr->broken){
1991 		qunlock(ctlr);
1992 		freeb(b);
1993 		return;
1994 	}
1995 
1996 	if((wn->channel != ctlr->channel)
1997 	|| (!ctlr->prom && (wn->aid != ctlr->aid || memcmp(wn->bssid, ctlr->bssid, Eaddrlen) != 0)))
1998 		rxon(edev, wn);
1999 
2000 	if(b == nil){
2001 		/* association note has no data to transmit */
2002 		qunlock(ctlr);
2003 		return;
2004 	}
2005 
2006 	flags = 0;
2007 	nodeid = ctlr->bcastnodeid;
2008 	p = wn->minrate;
2009 	w = (Wifipkt*)b->rp;
2010 	if((w->a1[0] & 1) == 0){
2011 		flags |= TFlagNeedACK;
2012 
2013 		if(BLEN(b) > 512-4)
2014 			flags |= TFlagNeedRTS;
2015 
2016 		if((w->fc[0] & 0x0c) == 0x08 &&	ctlr->bssnodeid != -1){
2017 			nodeid = ctlr->bssnodeid;
2018 			p = wn->actrate;
2019 		}
2020 
2021 		if(flags & (TFlagNeedRTS|TFlagNeedCTS)){
2022 			if(ctlr->type != Type4965){
2023 				flags &= ~(TFlagNeedRTS|TFlagNeedCTS);
2024 				flags |= TFlagNeedProtection;
2025 			} else
2026 				flags |= TFlagFullTxOp;
2027 		}
2028 	}
2029 	qunlock(ctlr);
2030 
2031 	rate = 0;
2032 	if(p >= iwlrates && p < &iwlrates[nelem(ratetab)])
2033 		rate = p - iwlrates;
2034 
2035 	/* select first available antenna */
2036 	ant = ctlr->rfcfg.txantmask & 7;
2037 	ant |= (ant == 0);
2038 	ant = ((ant - 1) & ant) ^ ant;
2039 
2040 	memset(p = c, 0, sizeof(c));
2041 	put16(p, BLEN(b));
2042 	p += 2;
2043 	p += 2;		/* lnext */
2044 	put32(p, flags);
2045 	p += 4;
2046 	put32(p, 0);
2047 	p += 4;		/* scratch */
2048 
2049 	*p++ = ratetab[rate].plcp;
2050 	*p++ = ratetab[rate].flags | (ant<<6);
2051 
2052 	p += 2;		/* xflags */
2053 	*p++ = nodeid;
2054 	*p++ = 0;	/* security */
2055 	*p++ = 0;	/* linkq */
2056 	p++;		/* reserved */
2057 	p += 16;	/* key */
2058 	p += 2;		/* fnext */
2059 	p += 2;		/* reserved */
2060 	put32(p, ~0);	/* lifetime */
2061 	p += 4;
2062 
2063 	/* BUG: scratch ptr? not clear what this is for */
2064 	put32(p, PCIWADDR(ctlr->kwpage));
2065 	p += 5;
2066 
2067 	*p++ = 60;	/* rts ntries */
2068 	*p++ = 15;	/* data ntries */
2069 	*p++ = 0;	/* tid */
2070 	put16(p, 0);	/* timeout */
2071 	p += 2;
2072 	p += 2;		/* txop */
2073 	if((err = qcmd(ctlr, 0, 28, c, p - c, b)) != nil){
2074 		print("transmit: %s\n", err);
2075 		freeb(b);
2076 	}
2077 }
2078 
2079 static long
iwlctl(Ether * edev,void * buf,long n)2080 iwlctl(Ether *edev, void *buf, long n)
2081 {
2082 	Ctlr *ctlr;
2083 
2084 	ctlr = edev->ctlr;
2085 	if(n >= 5 && memcmp(buf, "reset", 5) == 0){
2086 		ctlr->broken = 1;
2087 		return n;
2088 	}
2089 	if(ctlr->wifi)
2090 		return wifictl(ctlr->wifi, buf, n);
2091 	return 0;
2092 }
2093 
2094 static long
iwlifstat(Ether * edev,void * buf,long n,ulong off)2095 iwlifstat(Ether *edev, void *buf, long n, ulong off)
2096 {
2097 	Ctlr *ctlr;
2098 
2099 	ctlr = edev->ctlr;
2100 	if(ctlr->wifi)
2101 		return wifistat(ctlr->wifi, buf, n, off);
2102 	return 0;
2103 }
2104 
2105 static void
setoptions(Ether * edev)2106 setoptions(Ether *edev)
2107 {
2108 	Ctlr *ctlr;
2109 	int i;
2110 
2111 	ctlr = edev->ctlr;
2112 	for(i = 0; i < edev->nopt; i++)
2113 		wificfg(ctlr->wifi, edev->opt[i]);
2114 }
2115 
2116 static void
iwlpromiscuous(void * arg,int on)2117 iwlpromiscuous(void *arg, int on)
2118 {
2119 	Ether *edev;
2120 	Ctlr *ctlr;
2121 
2122 	edev = arg;
2123 	ctlr = edev->ctlr;
2124 	qlock(ctlr);
2125 	ctlr->prom = on;
2126 	rxon(edev, ctlr->wifi->bss);
2127 	qunlock(ctlr);
2128 }
2129 
2130 static void
iwlmulticast(void *,uchar *,int)2131 iwlmulticast(void *, uchar*, int)
2132 {
2133 }
2134 
2135 static void
iwlrecover(void * arg)2136 iwlrecover(void *arg)
2137 {
2138 	Ether *edev;
2139 	Ctlr *ctlr;
2140 
2141 	edev = arg;
2142 	ctlr = edev->ctlr;
2143 	while(waserror())
2144 		;
2145 	for(;;){
2146 		tsleep(&up->sleep, return0, 0, 4000);
2147 
2148 		qlock(ctlr);
2149 		for(;;){
2150 			if(ctlr->broken == 0)
2151 				break;
2152 
2153 			if(ctlr->power)
2154 				poweroff(ctlr);
2155 
2156 			if((csr32r(ctlr, Gpc) & RfKill) == 0)
2157 				break;
2158 
2159 			if(reset(ctlr) != nil)
2160 				break;
2161 			if(boot(ctlr) != nil)
2162 				break;
2163 
2164 			ctlr->bcastnodeid = -1;
2165 			ctlr->bssnodeid = -1;
2166 			ctlr->aid = 0;
2167 			rxon(edev, ctlr->wifi->bss);
2168 			break;
2169 		}
2170 		qunlock(ctlr);
2171 	}
2172 }
2173 
2174 static void
iwlattach(Ether * edev)2175 iwlattach(Ether *edev)
2176 {
2177 	FWImage *fw;
2178 	Ctlr *ctlr;
2179 	char *err;
2180 
2181 	ctlr = edev->ctlr;
2182 	qlock(ctlr);
2183 	if(waserror()){
2184 		print("#l%d: %s\n", edev->ctlrno, up->errstr);
2185 		if(ctlr->power)
2186 			poweroff(ctlr);
2187 		qunlock(ctlr);
2188 		nexterror();
2189 	}
2190 	if(ctlr->attached == 0){
2191 		if((csr32r(ctlr, Gpc) & RfKill) == 0)
2192 			error("wifi disabled by switch");
2193 
2194 		if(ctlr->wifi == nil){
2195 			ctlr->wifi = wifiattach(edev, transmit);
2196 			/* tested with 2230, it has transmit issues using higher bit rates */
2197 			if(ctlr->type != Type2030)
2198 				ctlr->wifi->rates = iwlrates;
2199 		}
2200 
2201 		if(ctlr->fw == nil){
2202 			char *fn = fwname[ctlr->type];
2203 			if(ctlr->type == Type6005){
2204 				switch(ctlr->pdev->did){
2205 				case 0x0082:	/* Centrino Advanced-N 6205 */
2206 				case 0x0085:	/* Centrino Advanced-N 6205 */
2207 					break;
2208 				default:	/* Centrino Advanced-N 6030, 6235 */
2209 					fn = "iwn-6030";
2210 				}
2211 			}
2212 			fw = readfirmware(fn);
2213 			print("#l%d: firmware: %s, rev %ux, build %ud, size %ux+%ux+%ux+%ux+%ux\n",
2214 				edev->ctlrno, fn,
2215 				fw->rev, fw->build,
2216 				fw->main.text.size, fw->main.data.size,
2217 				fw->init.text.size, fw->init.data.size,
2218 				fw->boot.text.size);
2219 			ctlr->fw = fw;
2220 		}
2221 
2222 		if((err = reset(ctlr)) != nil)
2223 			error(err);
2224 		if((err = boot(ctlr)) != nil)
2225 			error(err);
2226 
2227 		ctlr->bcastnodeid = -1;
2228 		ctlr->bssnodeid = -1;
2229 		ctlr->channel = 1;
2230 		ctlr->aid = 0;
2231 
2232 		setoptions(edev);
2233 
2234 		ctlr->attached = 1;
2235 
2236 		kproc("iwlrecover", iwlrecover, edev);
2237 	}
2238 	qunlock(ctlr);
2239 	poperror();
2240 }
2241 
2242 static void
receive(Ctlr * ctlr)2243 receive(Ctlr *ctlr)
2244 {
2245 	Block *b, *bb;
2246 	uchar *d;
2247 	RXQ *rx;
2248 	TXQ *tx;
2249 	uint hw;
2250 
2251 	rx = &ctlr->rx;
2252 	if(ctlr->broken || rx->s == nil || rx->b == nil)
2253 		return;
2254 
2255 	bb = nil;
2256 	for(hw = get16(rx->s) % Nrx; rx->i != hw; rx->i = (rx->i + 1) % Nrx){
2257 		uchar type, flags, idx, qid;
2258 		u32int len;
2259 
2260 		b = rx->b[rx->i];
2261 		if(b == nil)
2262 			continue;
2263 
2264 		d = b->rp;
2265 		len = get32(d); d += 4;
2266 		type = *d++;
2267 		flags = *d++;
2268 		USED(flags);
2269 		idx = *d++;
2270 		qid = *d++;
2271 
2272 		if(bb != nil){
2273 			freeb(bb);
2274 			bb = nil;
2275 		}
2276 		if((qid & 0x80) == 0 && qid < nelem(ctlr->tx)){
2277 			tx = &ctlr->tx[qid];
2278 			if(tx->n > 0){
2279 				bb = tx->b[idx];
2280 				tx->b[idx] = nil;
2281 				tx->n--;
2282 
2283 				wakeup(tx);
2284 			}
2285 		}
2286 
2287 		len &= 0x3fff;
2288 		if(len < 4 || type == 0)
2289 			continue;
2290 
2291 		len -= 4;
2292 		switch(type){
2293 		case 1:		/* microcontroller ready */
2294 			setfwinfo(ctlr, d, len);
2295 			break;
2296 		case 24:	/* add node done */
2297 			break;
2298 		case 28:	/* tx done */
2299 			if(ctlr->type == Type4965){
2300 				if(len <= 20 || d[20] == 1 || d[20] == 2)
2301 					break;
2302 			} else {
2303 				if(len <= 32 || d[32] == 1 || d[32] == 2)
2304 					break;
2305 			}
2306 			wifitxfail(ctlr->wifi, bb);
2307 			break;
2308 		case 102:	/* calibration result (Type5000 only) */
2309 			if(len < 4)
2310 				break;
2311 			idx = d[0];
2312 			if(idx >= nelem(ctlr->calib.cmd))
2313 				break;
2314 			if(rbplant(ctlr, rx->i) < 0)
2315 				break;
2316 			if(ctlr->calib.cmd[idx] != nil)
2317 				freeb(ctlr->calib.cmd[idx]);
2318 			b->rp = d;
2319 			b->wp = d + len;
2320 			ctlr->calib.cmd[idx] = b;
2321 			continue;
2322 		case 103:	/* calibration done (Type5000 only) */
2323 			ctlr->calib.done = 1;
2324 			break;
2325 		case 130:	/* start scan */
2326 			break;
2327 		case 132:	/* stop scan */
2328 			break;
2329 		case 156:	/* rx statistics */
2330 			break;
2331 		case 157:	/* beacon statistics */
2332 			break;
2333 		case 161:	/* state changed */
2334 			break;
2335 		case 162:	/* beacon missed */
2336 			break;
2337 		case 192:	/* rx phy */
2338 			break;
2339 		case 195:	/* rx done */
2340 			if(d + 2 > b->lim)
2341 				break;
2342 			d += d[1];
2343 			d += 56;
2344 		case 193:	/* mpdu rx done */
2345 			if(d + 4 > b->lim)
2346 				break;
2347 			len = get16(d); d += 4;
2348 			if(d + len + 4 > b->lim)
2349 				break;
2350 			if((get32(d + len) & 3) != 3)
2351 				break;
2352 			if(ctlr->wifi == nil)
2353 				break;
2354 			if(rbplant(ctlr, rx->i) < 0)
2355 				break;
2356 			b->rp = d;
2357 			b->wp = d + len;
2358 			wifiiq(ctlr->wifi, b);
2359 			continue;
2360 		case 197:	/* rx compressed ba */
2361 			break;
2362 		}
2363 	}
2364 	csr32w(ctlr, FhRxWptr, ((hw+Nrx-1) % Nrx) & ~7);
2365 	if(bb != nil)
2366 		freeb(bb);
2367 }
2368 
2369 static void
iwlinterrupt(Ureg *,void * arg)2370 iwlinterrupt(Ureg*, void *arg)
2371 {
2372 	u32int isr, fhisr;
2373 	Ether *edev;
2374 	Ctlr *ctlr;
2375 
2376 	edev = arg;
2377 	ctlr = edev->ctlr;
2378 	ilock(ctlr);
2379 	csr32w(ctlr, Imr, 0);
2380 	isr = csr32r(ctlr, Isr);
2381 	fhisr = csr32r(ctlr, FhIsr);
2382 	if(isr == 0xffffffff || (isr & 0xfffffff0) == 0xa5a5a5a0){
2383 		iunlock(ctlr);
2384 		return;
2385 	}
2386 	if(isr == 0 && fhisr == 0)
2387 		goto done;
2388 	csr32w(ctlr, Isr, isr);
2389 	csr32w(ctlr, FhIsr, fhisr);
2390 	if((isr & (Iswrx | Ifhrx | Irxperiodic)) || (fhisr & Ifhrx))
2391 		receive(ctlr);
2392 	if(isr & Ierr){
2393 		ctlr->broken = 1;
2394 		print("#l%d: fatal firmware error\n", edev->ctlrno);
2395 		dumpctlr(ctlr);
2396 	}
2397 	ctlr->wait.m |= isr;
2398 	if(ctlr->wait.m & ctlr->wait.w)
2399 		wakeup(&ctlr->wait);
2400 done:
2401 	csr32w(ctlr, Imr, ctlr->ie);
2402 	iunlock(ctlr);
2403 }
2404 
2405 static void
iwlshutdown(Ether * edev)2406 iwlshutdown(Ether *edev)
2407 {
2408 	Ctlr *ctlr;
2409 
2410 	ctlr = edev->ctlr;
2411 	if(ctlr->power)
2412 		poweroff(ctlr);
2413 	ctlr->broken = 0;
2414 }
2415 
2416 static Ctlr *iwlhead, *iwltail;
2417 
2418 static void
iwlpci(void)2419 iwlpci(void)
2420 {
2421 	Pcidev *pdev;
2422 
2423 	pdev = nil;
2424 	while(pdev = pcimatch(pdev, 0, 0)) {
2425 		Ctlr *ctlr;
2426 		void *mem;
2427 
2428 		if(pdev->ccrb != 2 || pdev->ccru != 0x80)
2429 			continue;
2430 		if(pdev->vid != 0x8086)
2431 			continue;
2432 
2433 		switch(pdev->did){
2434 		default:
2435 			continue;
2436 		case 0x0084:	/* WiFi Link 1000 */
2437 		case 0x4229:	/* WiFi Link 4965 */
2438 		case 0x4230:	/* WiFi Link 4965 */
2439 		case 0x4232:	/* Wifi Link 5100 */
2440 		case 0x4236:	/* WiFi Link 5300 AGN */
2441 		case 0x4237:	/* Wifi Link 5100 AGN */
2442 		case 0x423d:	/* Wifi Link 5150 */
2443 		case 0x423b:	/* PRO/Wireless 5350 AGN */
2444 		case 0x0082:	/* Centrino Advanced-N 6205 */
2445 		case 0x0085:	/* Centrino Advanced-N 6205 */
2446 		case 0x422b:	/* Centrino Ultimate-N 6300 variant 1 */
2447 		case 0x4238:	/* Centrino Ultimate-N 6300 variant 2 */
2448 		case 0x08ae:	/* Centrino Wireless-N 100 */
2449 		case 0x0083:	/* Centrino Wireless-N 1000 */
2450 		case 0x0887:	/* Centrino Wireless-N 2230 */
2451 		case 0x0888:	/* Centrino Wireless-N 2230 */
2452 		case 0x0090:	/* Centrino Advanced-N 6030 */
2453 		case 0x0091:	/* Centrino Advanced-N 6030 */
2454 		case 0x088e:	/* Centrino Advanced-N 6235 */
2455 		case 0x088f:	/* Centrino Advanced-N 6235 */
2456 			break;
2457 		}
2458 
2459 		/* Clear device-specific "PCI retry timeout" register (41h). */
2460 		if(pcicfgr8(pdev, 0x41) != 0)
2461 			pcicfgw8(pdev, 0x41, 0);
2462 
2463 		/* Clear interrupt disable bit. Hardware bug workaround. */
2464 		if(pdev->pcr & 0x400){
2465 			pdev->pcr &= ~0x400;
2466 			pcicfgw16(pdev, PciPCR, pdev->pcr);
2467 		}
2468 
2469 		pcisetbme(pdev);
2470 		pcisetpms(pdev, 0);
2471 
2472 		ctlr = malloc(sizeof(Ctlr));
2473 		if(ctlr == nil) {
2474 			print("iwl: unable to alloc Ctlr\n");
2475 			continue;
2476 		}
2477 		ctlr->port = pdev->mem[0].bar & ~0x0F;
2478 		mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
2479 		if(mem == nil) {
2480 			print("iwl: can't map %8.8luX\n", pdev->mem[0].bar);
2481 			free(ctlr);
2482 			continue;
2483 		}
2484 		ctlr->nic = mem;
2485 		ctlr->pdev = pdev;
2486 		ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0x1F;
2487 
2488 		if(fwname[ctlr->type] == nil){
2489 			print("iwl: unsupported controller type %d\n", ctlr->type);
2490 			vunmap(mem, pdev->mem[0].size);
2491 			free(ctlr);
2492 			continue;
2493 		}
2494 
2495 		if(iwlhead != nil)
2496 			iwltail->link = ctlr;
2497 		else
2498 			iwlhead = ctlr;
2499 		iwltail = ctlr;
2500 	}
2501 }
2502 
2503 static int
iwlpnp(Ether * edev)2504 iwlpnp(Ether* edev)
2505 {
2506 	Ctlr *ctlr;
2507 
2508 	if(iwlhead == nil)
2509 		iwlpci();
2510 again:
2511 	for(ctlr = iwlhead; ctlr != nil; ctlr = ctlr->link){
2512 		if(ctlr->active)
2513 			continue;
2514 		if(edev->port == 0 || edev->port == ctlr->port){
2515 			ctlr->active = 1;
2516 			break;
2517 		}
2518 	}
2519 
2520 	if(ctlr == nil)
2521 		return -1;
2522 
2523 	edev->ctlr = ctlr;
2524 	edev->port = ctlr->port;
2525 	edev->irq = ctlr->pdev->intl;
2526 	edev->tbdf = ctlr->pdev->tbdf;
2527 	edev->arg = edev;
2528 	edev->interrupt = iwlinterrupt;
2529 	edev->attach = iwlattach;
2530 	edev->ifstat = iwlifstat;
2531 	edev->ctl = iwlctl;
2532 	edev->shutdown = iwlshutdown;
2533 	edev->promiscuous = iwlpromiscuous;
2534 	edev->multicast = iwlmulticast;
2535 	edev->mbps = 54;
2536 
2537 	if(iwlinit(edev) < 0){
2538 		edev->ctlr = nil;
2539 		goto again;
2540 	}
2541 
2542 	return 0;
2543 }
2544 
2545 void
etheriwllink(void)2546 etheriwllink(void)
2547 {
2548 	addethercard("iwl", iwlpnp);
2549 }
2550