]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/etheriwl.c
wifi: quote value of parsed ether options
[plan9front.git] / sys / src / 9 / pc / etheriwl.c
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,
403         Type2030        = 12,
404 };
405
406 static char *fwname[16] = {
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",
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
427 get16(uchar *p){
428         return *((u16int*)p);
429 }
430 static uint
431 get32(uchar *p){
432         return *((u32int*)p);
433 }
434 static void
435 put32(uchar *p, uint v){
436         *((u32int*)p) = v;
437 }
438 static void
439 put16(uchar *p, uint v){
440         *((u16int*)p) = v;
441 };
442
443 static char*
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
458 nicunlock(Ctlr *ctlr)
459 {
460         csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) & ~MacAccessReq);
461 }
462
463 static u32int
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
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
479 memread(Ctlr *ctlr, uint off)
480 {
481         csr32w(ctlr, MemRaddr, off);
482         coherence();
483         return csr32r(ctlr, MemRdata);
484 }
485 static void
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
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
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*
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
550 eepromunlock(Ctlr *ctlr)
551 {
552         csr32w(ctlr, Cfg, csr32r(ctlr, Cfg) & ~EepromLocked);
553 }
554 static char*
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*
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*
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*
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
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*
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
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*
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*
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
1035 gotirq(void *arg)
1036 {
1037         Ctlr *ctlr = arg;
1038         return (ctlr->wait.m & ctlr->wait.w) != 0;
1039 }
1040
1041 static u32int
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
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*
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*
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*
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*
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*
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*
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
1666 txqready(void *arg)
1667 {
1668         TXQ *q = arg;
1669         return q->n < Ntx;
1670 }
1671
1672 static char*
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
1739 txqempty(void *arg)
1740 {
1741         TXQ *q = arg;
1742         return q->n == 0;
1743 }
1744
1745 static char*
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*
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
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
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
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         if(bss != nil){
1849                 ctlr->channel = bss->channel;
1850                 memmove(ctlr->bssid, bss->bssid, Eaddrlen);
1851                 ctlr->aid = bss->aid;
1852                 if(ctlr->aid != 0){
1853                         filter |= FilterBSS;
1854                         filter &= ~FilterBeacon;
1855                         ctlr->bssnodeid = -1;
1856                 } else
1857                         ctlr->bcastnodeid = -1;
1858         } else {
1859                 memmove(ctlr->bssid, edev->bcast, Eaddrlen);
1860                 ctlr->aid = 0;
1861                 ctlr->bcastnodeid = -1;
1862                 ctlr->bssnodeid = -1;
1863         }
1864         flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto;
1865
1866         if(ctlr->aid != 0)
1867                 setled(ctlr, 2, 0, 1);          /* on when associated */
1868         else if(memcmp(ctlr->bssid, edev->bcast, Eaddrlen) != 0)
1869                 setled(ctlr, 2, 10, 10);        /* slow blink when connecting */
1870         else
1871                 setled(ctlr, 2, 5, 5);          /* fast blink when scanning */
1872
1873         if(ctlr->wifi->debug)
1874                 print("#l%d: rxon: bssid %E, aid %x, channel %d, filter %x, flags %x\n",
1875                         edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, filter, flags);
1876
1877         memset(p = c, 0, sizeof(c));
1878         memmove(p, edev->ea, 6); p += 8;        /* myaddr */
1879         memmove(p, ctlr->bssid, 6); p += 8;     /* bssid */
1880         memmove(p, edev->ea, 6); p += 8;        /* wlap */
1881         *p++ = 3;                               /* mode (STA) */
1882         *p++ = 0;                               /* air (?) */
1883         /* rxchain */
1884         put16(p, ((ctlr->rfcfg.rxantmask & 7)<<1) | (2<<10) | (2<<12));
1885         p += 2;
1886         *p++ = 0xff;                            /* ofdm mask (not yet negotiated) */
1887         *p++ = 0x0f;                            /* cck mask (not yet negotiated) */
1888         put16(p, ctlr->aid & 0x3fff);
1889         p += 2;                                 /* aid */
1890         put32(p, flags);
1891         p += 4;
1892         put32(p, filter);
1893         p += 4;
1894         *p++ = ctlr->channel;
1895         p++;                                    /* reserved */
1896         *p++ = 0xff;                            /* ht single mask */
1897         *p++ = 0xff;                            /* ht dual mask */
1898         if(ctlr->type != Type4965){
1899                 *p++ = 0xff;                    /* ht triple mask */
1900                 p++;                            /* reserved */
1901                 put16(p, 0); p += 2;            /* acquisition */
1902                 p += 2;                         /* reserved */
1903         }
1904         if((err = cmd(ctlr, 16, c, p - c)) != nil){
1905                 print("rxon: %s\n", err);
1906                 return;
1907         }
1908
1909         if(ctlr->bcastnodeid == -1){
1910                 ctlr->bcastnodeid = (ctlr->type != Type4965) ? 15 : 31;
1911                 addnode(ctlr, ctlr->bcastnodeid, edev->bcast);
1912         }
1913         if(ctlr->bssnodeid == -1 && bss != nil && ctlr->aid != 0){
1914                 ctlr->bssnodeid = 0;
1915                 addnode(ctlr, ctlr->bssnodeid, bss->bssid);
1916         }
1917 }
1918
1919 static struct ratetab {
1920         uchar   rate;
1921         uchar   plcp;
1922         uchar   flags;
1923 } ratetab[] = {
1924         {   2,  10, RFlagCCK },
1925         {   4,  20, RFlagCCK },
1926         {  11,  55, RFlagCCK },
1927         {  22, 110, RFlagCCK },
1928         {  12, 0xd, 0 },
1929         {  18, 0xf, 0 },
1930         {  24, 0x5, 0 },
1931         {  36, 0x7, 0 },
1932         {  48, 0x9, 0 },
1933         {  72, 0xb, 0 },
1934         {  96, 0x1, 0 },
1935         { 108, 0x3, 0 },
1936         { 120, 0x3, 0 }
1937 };
1938
1939 static uchar iwlrates[] = {
1940         0x80 | 2,
1941         0x80 | 4,
1942         0x80 | 11,
1943         0x80 | 22,
1944         0x80 | 12,
1945         0x80 | 18,
1946         0x80 | 24,
1947         0x80 | 36,
1948         0x80 | 48,
1949         0x80 | 72,
1950         0x80 | 96,
1951         0x80 | 108,
1952         0x80 | 120,
1953
1954         0
1955 };
1956
1957 enum {
1958         TFlagNeedProtection     = 1<<0,
1959         TFlagNeedRTS            = 1<<1,
1960         TFlagNeedCTS            = 1<<2,
1961         TFlagNeedACK            = 1<<3,
1962         TFlagLinkq              = 1<<4,
1963         TFlagImmBa              = 1<<6,
1964         TFlagFullTxOp           = 1<<7,
1965         TFlagBtDis              = 1<<12,
1966         TFlagAutoSeq            = 1<<13,
1967         TFlagMoreFrag           = 1<<14,
1968         TFlagInsertTs           = 1<<16,
1969         TFlagNeedPadding        = 1<<20,
1970 };
1971
1972 static void
1973 transmit(Wifi *wifi, Wnode *wn, Block *b)
1974 {
1975         int flags, nodeid, rate, ant;
1976         uchar c[Tcmdsize], *p;
1977         Ether *edev;
1978         Ctlr *ctlr;
1979         Wifipkt *w;
1980         char *err;
1981
1982         edev = wifi->ether;
1983         ctlr = edev->ctlr;
1984
1985         qlock(ctlr);
1986         if(ctlr->attached == 0 || ctlr->broken){
1987                 qunlock(ctlr);
1988                 freeb(b);
1989                 return;
1990         }
1991
1992         if((wn->channel != ctlr->channel)
1993         || (!ctlr->prom && (wn->aid != ctlr->aid || memcmp(wn->bssid, ctlr->bssid, Eaddrlen) != 0)))
1994                 rxon(edev, wn);
1995
1996         if(b == nil){
1997                 /* association note has no data to transmit */
1998                 qunlock(ctlr);
1999                 return;
2000         }
2001
2002         flags = 0;
2003         nodeid = ctlr->bcastnodeid;
2004         p = wn->minrate;
2005         w = (Wifipkt*)b->rp;
2006         if((w->a1[0] & 1) == 0){
2007                 flags |= TFlagNeedACK;
2008
2009                 if(BLEN(b) > 512-4)
2010                         flags |= TFlagNeedRTS;
2011
2012                 if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
2013                         nodeid = ctlr->bssnodeid;
2014                         p = wn->actrate;
2015                 }
2016
2017                 if(flags & (TFlagNeedRTS|TFlagNeedCTS)){
2018                         if(ctlr->type != Type4965){
2019                                 flags &= ~(TFlagNeedRTS|TFlagNeedCTS);
2020                                 flags |= TFlagNeedProtection;
2021                         } else
2022                                 flags |= TFlagFullTxOp;
2023                 }
2024         }
2025         qunlock(ctlr);
2026
2027         rate = 0;
2028         if(p >= iwlrates && p < &iwlrates[nelem(ratetab)])
2029                 rate = p - iwlrates;
2030
2031         /* select first available antenna */
2032         ant = ctlr->rfcfg.txantmask & 7;
2033         ant |= (ant == 0);
2034         ant = ((ant - 1) & ant) ^ ant;
2035
2036         memset(p = c, 0, sizeof(c));
2037         put16(p, BLEN(b));
2038         p += 2;
2039         p += 2;         /* lnext */
2040         put32(p, flags);
2041         p += 4;
2042         put32(p, 0);
2043         p += 4;         /* scratch */
2044
2045         *p++ = ratetab[rate].plcp;
2046         *p++ = ratetab[rate].flags | (ant<<6);
2047
2048         p += 2;         /* xflags */
2049         *p++ = nodeid;
2050         *p++ = 0;       /* security */
2051         *p++ = 0;       /* linkq */
2052         p++;            /* reserved */
2053         p += 16;        /* key */
2054         p += 2;         /* fnext */
2055         p += 2;         /* reserved */
2056         put32(p, ~0);   /* lifetime */
2057         p += 4;
2058
2059         /* BUG: scratch ptr? not clear what this is for */
2060         put32(p, PCIWADDR(ctlr->kwpage));
2061         p += 5;
2062
2063         *p++ = 60;      /* rts ntries */
2064         *p++ = 15;      /* data ntries */
2065         *p++ = 0;       /* tid */
2066         put16(p, 0);    /* timeout */
2067         p += 2;
2068         p += 2;         /* txop */
2069         if((err = qcmd(ctlr, 0, 28, c, p - c, b)) != nil){
2070                 print("transmit: %s\n", err);
2071                 freeb(b);
2072         }
2073 }
2074
2075 static long
2076 iwlctl(Ether *edev, void *buf, long n)
2077 {
2078         Ctlr *ctlr;
2079
2080         ctlr = edev->ctlr;
2081         if(n >= 5 && memcmp(buf, "reset", 5) == 0){
2082                 ctlr->broken = 1;
2083                 return n;
2084         }
2085         if(ctlr->wifi)
2086                 return wifictl(ctlr->wifi, buf, n);
2087         return 0;
2088 }
2089
2090 static long
2091 iwlifstat(Ether *edev, void *buf, long n, ulong off)
2092 {
2093         Ctlr *ctlr;
2094
2095         ctlr = edev->ctlr;
2096         if(ctlr->wifi)
2097                 return wifistat(ctlr->wifi, buf, n, off);
2098         return 0;
2099 }
2100
2101 static void
2102 setoptions(Ether *edev)
2103 {
2104         Ctlr *ctlr;
2105         int i;
2106
2107         ctlr = edev->ctlr;
2108         for(i = 0; i < edev->nopt; i++)
2109                 wificfg(ctlr->wifi, edev->opt[i]);
2110 }
2111
2112 static void
2113 iwlpromiscuous(void *arg, int on)
2114 {
2115         Ether *edev;
2116         Ctlr *ctlr;
2117
2118         edev = arg;
2119         ctlr = edev->ctlr;
2120         qlock(ctlr);
2121         ctlr->prom = on;
2122         rxon(edev, ctlr->wifi->bss);
2123         qunlock(ctlr);
2124 }
2125
2126 static void
2127 iwlmulticast(void *, uchar*, int)
2128 {
2129 }
2130
2131 static void
2132 iwlrecover(void *arg)
2133 {
2134         Ether *edev;
2135         Ctlr *ctlr;
2136
2137         edev = arg;
2138         ctlr = edev->ctlr;
2139         while(waserror())
2140                 ;
2141         for(;;){
2142                 tsleep(&up->sleep, return0, 0, 4000);
2143
2144                 qlock(ctlr);
2145                 for(;;){
2146                         if(ctlr->broken == 0)
2147                                 break;
2148
2149                         if(ctlr->power)
2150                                 poweroff(ctlr);
2151
2152                         if((csr32r(ctlr, Gpc) & RfKill) == 0)
2153                                 break;
2154
2155                         if(reset(ctlr) != nil)
2156                                 break;
2157                         if(boot(ctlr) != nil)
2158                                 break;
2159
2160                         ctlr->bcastnodeid = -1;
2161                         ctlr->bssnodeid = -1;
2162                         ctlr->aid = 0;
2163                         rxon(edev, ctlr->wifi->bss);
2164                         break;
2165                 }
2166                 qunlock(ctlr);
2167         }
2168 }
2169
2170 static void
2171 iwlattach(Ether *edev)
2172 {
2173         FWImage *fw;
2174         Ctlr *ctlr;
2175         char *err;
2176
2177         ctlr = edev->ctlr;
2178         eqlock(ctlr);
2179         if(waserror()){
2180                 print("#l%d: %s\n", edev->ctlrno, up->errstr);
2181                 if(ctlr->power)
2182                         poweroff(ctlr);
2183                 qunlock(ctlr);
2184                 nexterror();
2185         }
2186         if(ctlr->attached == 0){
2187                 if((csr32r(ctlr, Gpc) & RfKill) == 0)
2188                         error("wifi disabled by switch");
2189
2190                 if(ctlr->wifi == nil){
2191                         ctlr->wifi = wifiattach(edev, transmit);
2192                         /* tested with 2230, it has transmit issues using higher bit rates */
2193                         if(ctlr->type != Type2030)
2194                                 ctlr->wifi->rates = iwlrates;
2195                 }
2196
2197                 if(ctlr->fw == nil){
2198                         fw = readfirmware(fwname[ctlr->type]);
2199                         print("#l%d: firmware: %s, rev %ux, build %ud, size %ux+%ux+%ux+%ux+%ux\n",
2200                                 edev->ctlrno,
2201                                 fwname[ctlr->type],
2202                                 fw->rev, fw->build,
2203                                 fw->main.text.size, fw->main.data.size,
2204                                 fw->init.text.size, fw->init.data.size,
2205                                 fw->boot.text.size);
2206                         ctlr->fw = fw;
2207                 }
2208
2209                 if((err = reset(ctlr)) != nil)
2210                         error(err);
2211                 if((err = boot(ctlr)) != nil)
2212                         error(err);
2213
2214                 ctlr->bcastnodeid = -1;
2215                 ctlr->bssnodeid = -1;
2216                 ctlr->channel = 1;
2217                 ctlr->aid = 0;
2218
2219                 setoptions(edev);
2220
2221                 ctlr->attached = 1;
2222
2223                 kproc("iwlrecover", iwlrecover, edev);
2224         }
2225         qunlock(ctlr);
2226         poperror();
2227 }
2228
2229 static void
2230 receive(Ctlr *ctlr)
2231 {
2232         Block *b, *bb;
2233         uchar *d;
2234         RXQ *rx;
2235         TXQ *tx;
2236         uint hw;
2237
2238         rx = &ctlr->rx;
2239         if(ctlr->broken || rx->s == nil || rx->b == nil)
2240                 return;
2241
2242         bb = nil;
2243         for(hw = get16(rx->s) % Nrx; rx->i != hw; rx->i = (rx->i + 1) % Nrx){
2244                 uchar type, flags, idx, qid;
2245                 u32int len;
2246
2247                 b = rx->b[rx->i];
2248                 if(b == nil)
2249                         continue;
2250
2251                 d = b->rp;
2252                 len = get32(d); d += 4;
2253                 type = *d++;
2254                 flags = *d++;
2255                 USED(flags);
2256                 idx = *d++;
2257                 qid = *d++;
2258
2259                 if(bb != nil){
2260                         freeb(bb);
2261                         bb = nil;
2262                 }
2263                 if((qid & 0x80) == 0 && qid < nelem(ctlr->tx)){
2264                         tx = &ctlr->tx[qid];
2265                         if(tx->n > 0){
2266                                 bb = tx->b[idx];
2267                                 tx->b[idx] = nil;
2268                                 tx->n--;
2269
2270                                 wakeup(tx);
2271                         }
2272                 }
2273
2274                 len &= 0x3fff;
2275                 if(len < 4 || type == 0)
2276                         continue;
2277
2278                 len -= 4;
2279                 switch(type){
2280                 case 1:         /* microcontroller ready */
2281                         setfwinfo(ctlr, d, len);
2282                         break;
2283                 case 24:        /* add node done */
2284                         break;
2285                 case 28:        /* tx done */
2286                         if(ctlr->type == Type4965){
2287                                 if(len <= 20 || d[20] == 1 || d[20] == 2)
2288                                         break;
2289                         } else {
2290                                 if(len <= 32 || d[32] == 1 || d[32] == 2)
2291                                         break;
2292                         }
2293                         wifitxfail(ctlr->wifi, bb);
2294                         break;
2295                 case 102:       /* calibration result (Type5000 only) */
2296                         if(len < 4)
2297                                 break;
2298                         idx = d[0];
2299                         if(idx >= nelem(ctlr->calib.cmd))
2300                                 break;
2301                         if(rbplant(ctlr, rx->i) < 0)
2302                                 break;
2303                         if(ctlr->calib.cmd[idx] != nil)
2304                                 freeb(ctlr->calib.cmd[idx]);
2305                         b->rp = d;
2306                         b->wp = d + len;
2307                         ctlr->calib.cmd[idx] = b;
2308                         continue;
2309                 case 103:       /* calibration done (Type5000 only) */
2310                         ctlr->calib.done = 1;
2311                         break;
2312                 case 130:       /* start scan */
2313                         break;
2314                 case 132:       /* stop scan */
2315                         break;
2316                 case 156:       /* rx statistics */
2317                         break;
2318                 case 157:       /* beacon statistics */
2319                         break;
2320                 case 161:       /* state changed */
2321                         break;
2322                 case 162:       /* beacon missed */
2323                         break;
2324                 case 192:       /* rx phy */
2325                         break;
2326                 case 195:       /* rx done */
2327                         if(d + 2 > b->lim)
2328                                 break;
2329                         d += d[1];
2330                         d += 56;
2331                 case 193:       /* mpdu rx done */
2332                         if(d + 4 > b->lim)
2333                                 break;
2334                         len = get16(d); d += 4;
2335                         if(d + len + 4 > b->lim)
2336                                 break;
2337                         if((get32(d + len) & 3) != 3)
2338                                 break;
2339                         if(ctlr->wifi == nil)
2340                                 break;
2341                         if(rbplant(ctlr, rx->i) < 0)
2342                                 break;
2343                         b->rp = d;
2344                         b->wp = d + len;
2345                         wifiiq(ctlr->wifi, b);
2346                         continue;
2347                 case 197:       /* rx compressed ba */
2348                         break;
2349                 }
2350         }
2351         csr32w(ctlr, FhRxWptr, ((hw+Nrx-1) % Nrx) & ~7);
2352         if(bb != nil)
2353                 freeb(bb);
2354 }
2355
2356 static void
2357 iwlinterrupt(Ureg*, void *arg)
2358 {
2359         u32int isr, fhisr;
2360         Ether *edev;
2361         Ctlr *ctlr;
2362
2363         edev = arg;
2364         ctlr = edev->ctlr;
2365         ilock(ctlr);
2366         csr32w(ctlr, Imr, 0);
2367         isr = csr32r(ctlr, Isr);
2368         fhisr = csr32r(ctlr, FhIsr);
2369         if(isr == 0xffffffff || (isr & 0xfffffff0) == 0xa5a5a5a0){
2370                 iunlock(ctlr);
2371                 return;
2372         }
2373         if(isr == 0 && fhisr == 0)
2374                 goto done;
2375         csr32w(ctlr, Isr, isr);
2376         csr32w(ctlr, FhIsr, fhisr);
2377         if((isr & (Iswrx | Ifhrx | Irxperiodic)) || (fhisr & Ifhrx))
2378                 receive(ctlr);
2379         if(isr & Ierr){
2380                 ctlr->broken = 1;
2381                 print("#l%d: fatal firmware error\n", edev->ctlrno);
2382                 dumpctlr(ctlr);
2383         }
2384         ctlr->wait.m |= isr;
2385         if(ctlr->wait.m & ctlr->wait.w)
2386                 wakeup(&ctlr->wait);
2387 done:
2388         csr32w(ctlr, Imr, ctlr->ie);
2389         iunlock(ctlr);
2390 }
2391
2392 static void
2393 iwlshutdown(Ether *edev)
2394 {
2395         Ctlr *ctlr;
2396
2397         ctlr = edev->ctlr;
2398         if(ctlr->power)
2399                 poweroff(ctlr);
2400         ctlr->broken = 0;
2401 }
2402
2403 static Ctlr *iwlhead, *iwltail;
2404
2405 static void
2406 iwlpci(void)
2407 {
2408         Pcidev *pdev;
2409         
2410         pdev = nil;
2411         while(pdev = pcimatch(pdev, 0, 0)) {
2412                 Ctlr *ctlr;
2413                 void *mem;
2414                 
2415                 if(pdev->ccrb != 2 || pdev->ccru != 0x80)
2416                         continue;
2417                 if(pdev->vid != 0x8086)
2418                         continue;
2419
2420                 switch(pdev->did){
2421                 default:
2422                         continue;
2423                 case 0x0084:    /* WiFi Link 1000 */
2424                 case 0x4229:    /* WiFi Link 4965 */
2425                 case 0x4230:    /* WiFi Link 4965 */
2426                 case 0x4232:    /* Wifi Link 5100 */
2427                 case 0x4236:    /* WiFi Link 5300 AGN */
2428                 case 0x4237:    /* Wifi Link 5100 AGN */
2429                 case 0x423d:    /* Wifi Link 5150 */
2430                 case 0x0085:    /* Centrino Advanced-N 6205 */
2431                 case 0x422b:    /* Centrino Ultimate-N 6300 variant 1 */
2432                 case 0x4238:    /* Centrino Ultimate-N 6300 variant 2 */
2433                 case 0x08ae:    /* Centrino Wireless-N 100 */
2434                 case 0x0083:    /* Centrino Wireless-N 1000 */
2435                 case 0x0887:    /* Centrino Wireless-N 2230 */
2436                 case 0x0888:    /* Centrino Wireless-N 2230 */
2437                         break;
2438                 }
2439
2440                 /* Clear device-specific "PCI retry timeout" register (41h). */
2441                 if(pcicfgr8(pdev, 0x41) != 0)
2442                         pcicfgw8(pdev, 0x41, 0);
2443
2444                 /* Clear interrupt disable bit. Hardware bug workaround. */
2445                 if(pdev->pcr & 0x400){
2446                         pdev->pcr &= ~0x400;
2447                         pcicfgw16(pdev, PciPCR, pdev->pcr);
2448                 }
2449
2450                 pcisetbme(pdev);
2451                 pcisetpms(pdev, 0);
2452
2453                 ctlr = malloc(sizeof(Ctlr));
2454                 if(ctlr == nil) {
2455                         print("iwl: unable to alloc Ctlr\n");
2456                         continue;
2457                 }
2458                 ctlr->port = pdev->mem[0].bar & ~0x0F;
2459                 mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
2460                 if(mem == nil) {
2461                         print("iwl: can't map %8.8luX\n", pdev->mem[0].bar);
2462                         free(ctlr);
2463                         continue;
2464                 }
2465                 ctlr->nic = mem;
2466                 ctlr->pdev = pdev;
2467                 ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0xF;
2468
2469                 if(fwname[ctlr->type] == nil){
2470                         print("iwl: unsupported controller type %d\n", ctlr->type);
2471                         vunmap(mem, pdev->mem[0].size);
2472                         free(ctlr);
2473                         continue;
2474                 }
2475
2476                 if(iwlhead != nil)
2477                         iwltail->link = ctlr;
2478                 else
2479                         iwlhead = ctlr;
2480                 iwltail = ctlr;
2481         }
2482 }
2483
2484 static int
2485 iwlpnp(Ether* edev)
2486 {
2487         Ctlr *ctlr;
2488         
2489         if(iwlhead == nil)
2490                 iwlpci();
2491 again:
2492         for(ctlr = iwlhead; ctlr != nil; ctlr = ctlr->link){
2493                 if(ctlr->active)
2494                         continue;
2495                 if(edev->port == 0 || edev->port == ctlr->port){
2496                         ctlr->active = 1;
2497                         break;
2498                 }
2499         }
2500
2501         if(ctlr == nil)
2502                 return -1;
2503
2504         edev->ctlr = ctlr;
2505         edev->port = ctlr->port;
2506         edev->irq = ctlr->pdev->intl;
2507         edev->tbdf = ctlr->pdev->tbdf;
2508         edev->arg = edev;
2509         edev->interrupt = iwlinterrupt;
2510         edev->attach = iwlattach;
2511         edev->ifstat = iwlifstat;
2512         edev->ctl = iwlctl;
2513         edev->shutdown = iwlshutdown;
2514         edev->promiscuous = iwlpromiscuous;
2515         edev->multicast = iwlmulticast;
2516         edev->mbps = 54;
2517
2518         if(iwlinit(edev) < 0){
2519                 edev->ctlr = nil;
2520                 goto again;
2521         }
2522         
2523         return 0;
2524 }
2525
2526 void
2527 etheriwllink(void)
2528 {
2529         addethercard("iwl", iwlpnp);
2530 }