]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/etherrt2860.c
usbehci: catch interrupt in tsleep
[plan9front.git] / sys / src / 9 / pc / etherrt2860.c
1 /* 
2  * Ralink RT2860 driver
3  *
4  * Written without any documentation but Damien Bergaminis
5  * OpenBSD ral(4) driver sources. Requires ralink firmware
6  * to be present in /lib/firmware/ral-rt2860 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 #include "../port/etherif.h"
18 #include "../port/wifi.h"
19
20 /* for consistency */
21 typedef signed char s8int;
22
23 enum {
24         /* PCI registers */
25         PciCfg = 0x0000,
26                 PciCfgUsb = (1 << 17),
27                 PciCfgPci = (1 << 16),
28         PciEectrl = 0x0004,
29                 EectrlC = (1 << 0),
30                 EectrlS = (1 << 1),
31                 EectrlD = (1 << 2),
32                 EectrlShiftD = 2,
33                 EectrlQ = (1 << 3),
34                 EectrlShiftQ = 3,
35         PciMcuctrl = 0x0008,
36         PciSysctrl = 0x000c,
37         PcieJtag = 0x0010,
38
39         Rt3090AuxCtrl = 0x010c,
40
41         Rt3070Opt14 = 0x0114,
42 };
43
44 enum {
45         /* SCH/DMA registers */
46         IntStatus = 0x0200,
47                 /* flags for registers IntStatus/IntMask */
48                 TxCoherent = (1 << 17),
49                 RxCoherent = (1 << 16),
50                 MacInt4 = (1 << 15),
51                 MacInt3 = (1 << 14),
52                 MacInt2 = (1 << 13),
53                 MacInt1 = (1 << 12),
54                 MacInt0 = (1 << 11),
55                 TxRxCoherent = (1 << 10),
56                 McuCmdInt = (1 << 9),
57                 TxDoneInt5 = (1 << 8),
58                 TxDoneInt4 = (1 << 7),
59                 TxDoneInt3 = (1 << 6),
60                 TxDoneInt2 = (1 << 5),
61                 TxDoneInt1 = (1 << 4),
62                 TxDoneInt0 = (1 << 3),
63                 RxDoneInt = (1 << 2),
64                 TxDlyInt = (1 << 1),
65                 RxDlyInt = (1 << 0),
66         IntMask = 0x0204,
67         WpdmaGloCfg = 0x0208,
68                 HdrSegLenShift = 8,
69                 BigEndian = (1 << 7),
70                 TxWbDdone = (1 << 6),
71                 WpdmaBtSizeShift = 4,
72                 WpdmaBtSize16 = 0,
73                 WpdmaBtSize32 = 1,
74                 WpdmaBtSize64 = 2,
75                 WpdmaBtSize128 = 3,
76                 RxDmaBusy = (1 << 3),
77                 RxDmaEn = (1 << 2),
78                 TxDmaBusy = (1 << 1),
79                 TxDmaEn = (1 << 0),
80         WpdmaRstIdx = 0x020c,
81         DelayIntCfg = 0x0210,
82                 TxdlyIntEn = (1 << 31),
83                 TxmaxPintShift = 24,
84                 TxmaxPtimeShift = 16,
85                 RxdlyIntEn = (1 << 15),
86                 RxmaxPintShift = 8,
87                 RxmaxPtimeShift = 0,
88         WmmAifsnCfg = 0x0214,
89         WmmCwminCfg = 0x0218,
90         WmmCwmaxCfg = 0x021c,
91         WmmTxop0Cfg = 0x0220,
92         WmmTxop1Cfg = 0x0224,
93         GpioCtrl = 0x0228,
94                 GpioDShift = 8,
95                 GpioOShift = 0,
96         McuCmdReg = 0x022c,
97 #define TxBasePtr(qid) (0x0230 + (qid) * 16)
98 #define TxMaxCnt(qid) (0x0234 + (qid) * 16)
99 #define TxCtxIdx(qid) (0x0238 + (qid) * 16)
100 #define TxDtxIdx(qid) (0x023c + (qid) * 16)
101         RxBasePtr = 0x0290,
102         RxMaxCnt = 0x0294,
103         RxCalcIdx = 0x0298,
104         FsDrxIdx = 0x029c,
105         UsbDmaCfg = 0x02a0 /* RT2870 only */,
106                 UsbTxBusy = (1 << 31),
107                 UsbRxBusy = (1 << 30),
108                 UsbEpoutVldShift = 24,
109                 UsbTxEn = (1 << 23),
110                 UsbRxEn = (1 << 22),
111                 UsbRxAggEn = (1 << 21),
112                 UsbTxopHalt = (1 << 20),
113                 UsbTxClear = (1 << 19),
114                 UsbPhyWdEn = (1 << 16),
115                 UsbPhyManRst = (1 << 15),
116 #define UsbRxAggLmt(x) ((x) << 8) /* in unit of 1KB */
117 #define UsbRxAggTo(x) ((x) & 0xff) /* in unit of 33ns */
118         UsCycCnt = 0x02a4,
119                 TestEn = (1 << 24),
120                 TestSelShift = 16,
121                 BtModeEn = (1 << 8),
122                 UsCycCntShift = 0,
123 };
124
125 enum {
126         /* PBF registers */
127         SysCtrl = 0x0400,
128                 HstPmSel = (1 << 16),
129                 CapMode = (1 << 14),
130                 PmeOen = (1 << 13),
131                 Clkselect = (1 << 12),
132                 PbfClkEn = (1 << 11),
133                 MacClkEn = (1 << 10),
134                 DmaClkEn = (1 << 9),
135                 McuReady = (1 << 7),
136                 AsyReset = (1 << 4),
137                 PbfReset = (1 << 3),
138                 MacReset = (1 << 2),
139                 DmaReset = (1 << 1),
140                 McuReset = (1 << 0),
141         HostCmd = 0x0404,
142                 McuCmdSleep = 0x30,
143                 McuCmdWakeup = 0x31,
144                 McuCmdLeds = 0x50,
145                         LedRadio = (1 << 13),
146                         LedLink2ghz = (1 << 14),
147                         LedLink5ghz = (1 << 15),
148                 McuCmdLedRssi = 0x51,
149                 McuCmdLed1 = 0x52,
150                 McuCmdLed2 = 0x53,
151                 McuCmdLed3 = 0x54,
152                 McuCmdRfreset = 0x72,
153                 McuCmdAntsel = 0x73,
154                 McuCmdBbp = 0x80,
155                 McuCmdPslevel = 0x83,
156         PbfCfg = 0x0408,
157                 Tx1qNumShift = 21,
158                 Tx2qNumShift = 16,
159                 Null0Mode = (1 << 15),
160                 Null1Mode = (1 << 14),
161                 RxDropMode = (1 << 13),
162                 Tx0qManual = (1 << 12),
163                 Tx1qManual = (1 << 11),
164                 Tx2qManual = (1 << 10),
165                 Rx0qManual = (1 << 9),
166                 HccaEn = (1 << 8),
167                 Tx0qEn = (1 << 4),
168                 Tx1qEn = (1 << 3),
169                 Tx2qEn = (1 << 2),
170                 Rx0qEn = (1 << 1),
171         MaxPcnt = 0x040c,
172         BufCtrl = 0x0410,
173 #define WriteTxq(qid) (1 << (11 - (qid)))
174                 Null0Kick = (1 << 7),
175                 Null1Kick = (1 << 6),
176                 BufReset = (1 << 5),
177 #define ReadTxq(qid) = (1 << (3 - (qid))
178                 ReadRx0q = (1 << 0),
179         McuIntSta = 0x0414,
180                 /* flags for registers McuIntSta/McuIntEna */
181                 McuMacInt8 = (1 << 24),
182                 McuMacInt7 = (1 << 23),
183                 McuMacInt6 = (1 << 22),
184                 McuMacInt4 = (1 << 20),
185                 McuMacInt3 = (1 << 19),
186                 McuMacInt2 = (1 << 18),
187                 McuMacInt1 = (1 << 17),
188                 McuMacInt0 = (1 << 16),
189                 Dtx0Int = (1 << 11),
190                 Dtx1Int = (1 << 10),
191                 Dtx2Int = (1 << 9),
192                 Drx0Int = (1 << 8),
193                 HcmdInt = (1 << 7),
194                 N0txInt = (1 << 6),
195                 N1txInt = (1 << 5),
196                 BcntxInt = (1 << 4),
197                 Mtx0Int = (1 << 3),
198                 Mtx1Int = (1 << 2),
199                 Mtx2Int = (1 << 1),
200                 Mrx0Int = (1 << 0),
201         McuIntEna = 0x0418,
202 #define TxqIo(qid) (0x041c + (qid) * 4)
203         Rx0qIo = 0x0424,
204         BcnOffset0 = 0x042c,
205         BcnOffset1 = 0x0430,
206         TxrxqSta = 0x0434,
207         TxrxqPcnt = 0x0438,
208                 Rx0qPcntMask = 0xff000000,
209                 Tx2qPcntMask = 0x00ff0000,
210                 Tx1qPcntMask = 0x0000ff00,
211                 Tx0qPcntMask = 0x000000ff,
212         PbfDbg = 0x043c,
213         CapCtrl = 0x0440,
214                 CapAdcFeq = (1 << 31),
215                 CapStart = (1 << 30),
216                 ManTrig = (1 << 29),
217                 TrigOffsetShift = 16,
218                 StartAddrShift = 0,
219 };
220
221 enum {
222         /* RT3070 registers */
223         Rt3070RfCsrCfg = 0x0500,
224                 Rt3070RfKick = (1 << 17),
225                 Rt3070RfWrite = (1 << 16),
226         Rt3070EfuseCtrl = 0x0580,
227                 Rt3070SelEfuse = (1 << 31),
228                 Rt3070EfsromKick = (1 << 30),
229                 Rt3070EfsromAinMask = 0x03ff0000,
230                 Rt3070EfsromAinShift = 16,
231                 Rt3070EfsromModeMask = 0x000000c0,
232                 Rt3070EfuseAoutMask = 0x0000003f,
233         Rt3070EfuseData0 = 0x0590,
234         Rt3070EfuseData1 = 0x0594,
235         Rt3070EfuseData2 = 0x0598,
236         Rt3070EfuseData3 = 0x059c,
237         Rt3090OscCtrl = 0x05a4,
238         Rt3070LdoCfg0 = 0x05d4,
239         Rt3070GpioSwitch = 0x05dc,
240 };
241
242 enum {
243         /* MAC registers */
244         AsicVerId = 0x1000,
245         MacSysCtrl = 0x1004,
246                 RxTsEn = (1 << 7),
247                 WlanHaltEn = (1 << 6),
248                 PbfLoopEn = (1 << 5),
249                 ContTxTest = (1 << 4),
250                 MacRxEn = (1 << 3),
251                 MacTxEn = (1 << 2),
252                 BbpHrst = (1 << 1),
253                 MacSrst = (1 << 0),
254         MacAddrDw0 = 0x1008,
255         MacAddrDw1 = 0x100c,
256         MacBssidDw0 = 0x1010,
257         MacBssidDw1 = 0x1014,
258                 MultiBcnNumShift = 18,
259                 MultiBssidModeShift = 16,
260         MaxLenCfg = 0x1018,
261                 MinMpduLenShift = 16,
262                 MaxPsduLenShift = 12,
263                 MaxPsduLen8k = 0,
264                 MaxPsduLen16k = 1,
265                 MaxPsduLen32k = 2,
266                 MaxPsduLen64k = 3,
267                 MaxMpduLenShift = 0,
268         BbpCsrCfg = 0x101c,
269                 BbpRwParallel = (1 << 19),
270                 BbpParDur1125 = (1 << 18),
271                 BbpCsrKick = (1 << 17),
272                 BbpCsrRead = (1 << 16),
273                 BbpAddrShift = 8,
274                 BbpDataShift = 0,
275         RfCsrCfg0 = 0x1020,
276                 RfRegCtrl = (1 << 31),
277                 RfLeSel1 = (1 << 30),
278                 RfLeStby = (1 << 29),
279                 RfRegWidthShift = 24,
280                 RfReg0Shift = 0,
281         RfCsrCfg1 = 0x1024,
282                 RfDur5 = (1 << 24),
283                 RfReg1Shift = 0,
284         RfCsrCfg2 = 0x1028,
285         LedCfg = 0x102c,
286                 LedPol = (1 << 30),
287                 YLedModeShift = 28,
288                 GLedModeShift = 26,
289                 RLedModeShift = 24,
290                 LedModeOff = 0,
291                 LedModeBlinkTx = 1,
292                 LedModeSlowBlink = 2,
293                 LedModeOn = 3,
294                 SlowBlkTimeShift = 16,
295                 LedOffTimeShift = 8,
296                 LedOnTimeShift = 0,
297 };
298
299 enum {
300         /* undocumented registers */
301         Debug = 0x10f4,
302 };
303
304 enum {
305         /* MAC Timing control registers */
306         XifsTimeCfg = 0x1100,
307                 BbRxendEn = (1 << 29),
308                 EifsTimeShift = 20,
309                 OfdmXifsTimeShift = 16,
310                 OfdmSifsTimeShift = 8,
311                 CckSifsTimeShift = 0,
312         BkoffSlotCfg = 0x1104,
313                 CcDelayTimeShift = 8,
314                 SlotTime = 0,
315         NavTimeCfg = 0x1108,
316                 NavUpd = (1 << 31),
317                 NavUpdValShift = 16,
318                 NavClrEn = (1 << 15),
319                 NavTimerShift = 0,
320         ChTimeCfg = 0x110c,
321                 EifsAsChBusy = (1 << 4),
322                 NavAsChBusy = (1 << 3),
323                 RxAsChBusy = (1 << 2),
324                 TxAsChBusy = (1 << 1),
325                 ChStaTimerEn = (1 << 0),
326         PbfLifeTimer = 0x1110,
327         BcnTimeCfg = 0x1114,
328                 TsfInsCompShift = 24,
329                 BcnTxEn = (1 << 20),
330                 TbttTimerEn = (1 << 19),
331                 TsfSyncModeShift = 17,
332                 TsfSyncModeDis = 0,
333                 TsfSyncModeSta = 1,
334                 TsfSyncModeIbss = 2,
335                 TsfSyncModeHostap = 3,
336                 TsfTimerEn = (1 << 16),
337                 BcnIntvalShift = 0,
338         TbttSyncCfg = 0x1118,
339                 BcnCwminShift = 20,
340                 BcnAifsnShift = 16,
341                 BcnExpWinShift = 8,
342                 TbttAdjustShift = 0,
343         TsfTimerDw0 = 0x111c,
344         TsfTimerDw1 = 0x1120,
345         TbttTimer = 0x1124,
346         IntTimerCfg = 0x1128,
347                 GpTimerShift = 16,
348                 PreTbttTimerShift = 0,
349         IntTimerEn = 0x112c,
350                 GpTimerEn = (1 << 1),
351                 PreTbttIntEn = (1 << 0),
352         ChIdleTime = 0x1130,
353 };
354
355 enum {
356         /* MAC Power Save configuration registers */
357         MacStatusReg = 0x1200,
358                 RxStatusBusy = (1 << 1),
359                 TxStatusBusy = (1 << 0),
360         PwrPinCfg = 0x1204,
361                 IoAddaPd = (1 << 3),
362                 IoPllPd = (1 << 2),
363                 IoRaPe = (1 << 1),
364                 IoRfPe = (1 << 0),
365         AutoWakeupCfg = 0x1208,
366                 AutoWakeupEn = (1 << 15),
367                 SleepTbttNumShift = 8,
368                 WakeupLeadTimeShift = 0,
369 };
370
371 enum {
372         /* MAC TX configuration registers */
373 #define EdcaAcCfg(aci) (0x1300 + (aci) * 4)
374         EdcaTidAcMap = 0x1310,
375 #define TxPwrCfg(ridx) (0x1314 + (ridx) * 4)
376         TxPinCfg = 0x1328,
377                 Rt3593LnaPeG2Pol = (1 << 31),
378                 Rt3593LnaPeA2Pol = (1 << 30),
379                 Rt3593LnaPeG2En = (1 << 29),
380                 Rt3593LnaPeA2En = (1 << 28),
381                 Rt3593LnaPe2En = (Rt3593LnaPeA2En | Rt3593LnaPeG2En),
382                 Rt3593PaPeG2Pol = (1 << 27),
383                 Rt3593PaPeA2Pol = (1 << 26),
384                 Rt3593PaPeG2En = (1 << 25),
385                 Rt3593PaPeA2En = (1 << 24),
386                 TrswPol = (1 << 19),
387                 TrswEn = (1 << 18),
388                 RftrPol = (1 << 17),
389                 RftrEn = (1 << 16),
390                 LnaPeG1Pol = (1 << 15),
391                 LnaPeA1Pol = (1 << 14),
392                 LnaPeG0Pol = (1 << 13),
393                 LnaPeA0Pol = (1 << 12),
394                 LnaPeG1En = (1 << 11),
395                 LnaPeA1En = (1 << 10),
396                 LnaPe1En = (LnaPeA1En | LnaPeG1En),
397                 LnaPeG0En = (1 << 9),
398                 LnaPeA0En = (1 << 8),
399                 LnaPe0En = (LnaPeA0En | LnaPeG0En),
400                 PaPeG1Pol = (1 << 7),
401                 PaPeA1Pol = (1 << 6),
402                 PaPeG0Pol = (1 << 5),
403                 PaPeA0Pol = (1 << 4),
404                 PaPeG1En = (1 << 3),
405                 PaPeA1En = (1 << 2),
406                 PaPeG0En = (1 << 1),
407                 PaPeA0En = (1 << 0),
408         TxBandCfg = 0x132c,
409                 Tx5gBandSelN = (1 << 2),
410                 Tx5gBandSelP = (1 << 1),
411                 TxBandSel = (1 << 0),
412         TxSwCfg0 = 0x1330,
413                 DlyRftrEnShift = 24,
414                 DlyTrswEnShift = 16,
415                 DlyPapeEnShift = 8,
416                 DlyTxpeEnShift = 0,
417         TxSwCfg1 = 0x1334,
418                 DlyRftrDisShift = 16,
419                 DlyTrswDisShift = 8,
420                 DlyPapeDisShift = 0,
421         TxSwCfg2 = 0x1338,
422                 DlyLnaEnShift = 24,
423                 DlyLnaDisShift = 16,
424                 DlyDacEnShift = 8,
425                 DlyDacDisShift = 0,
426         TxopThresCfg = 0x133c,
427                 TxopRemThresShift = 24,
428                 CfEndThresShift = 16,
429                 RdgInThres = 8,
430                 RdgOutThres = 0,
431         TxopCtrlCfg = 0x1340,
432                 ExtCwMinShift = 16,
433                 ExtCcaDlyShift = 8,
434                 ExtCcaEn = (1 << 7),
435                 LsigTxopEn = (1 << 6),
436                 TxopTrunEnMimops = (1 << 4),
437                 TxopTrunEnTxop = (1 << 3),
438                 TxopTrunEnRate = (1 << 2),
439                 TxopTrunEnAc = (1 << 1),
440                 TxopTrunEnTimeout = (1 << 0),
441         TxRtsCfg = 0x1344,
442                 RtsFbkEn = (1 << 24),
443                 RtsThresShift = 8,
444                 RtsRtyLimitShift = 0,
445         TxTimeoutCfg = 0x1348,
446                 TxopTimeoutShift = 16,
447                 RxAckTimeoutShift = 8,
448                 MpduLifeTimeShift = 4,
449         TxRtyCfg = 0x134c,
450                 TxAutofbEn = (1 << 30),
451                 AggRtyModeTimer = (1 << 29),
452                 NagRtyModeTimer = (1 << 28),
453                 LongRtyThresShift = 16,
454                 LongRtyLimitShift = 8,
455                 ShortRtyLimitShift = 0,
456         TxLinkCfg = 0x1350,
457                 RemoteMfsShift = 24,
458                 RemoteMfbShift = 16,
459                 TxCfackEn = (1 << 12),
460                 TxRdgEn = (1 << 11),
461                 TxMrqEn = (1 << 10),
462                 RemoteUmfsEn = (1 << 9),
463                 TxMfbEn = (1 << 8),
464                 RemoteMfbLtShift = 0,
465         HtFbkCfg0 = 0x1354,
466         HtFbkCfg1 = 0x1358,
467         LgFbkCfg0 = 0x135c,
468         LgFbkCfg1 = 0x1360,
469         CckProtCfg = 0x1364,
470                 /* possible flags for registers *ProtCfg */
471                 RtsthEn = (1 << 26),
472                 TxopAllowGf40 = (1 << 25),
473                 TxopAllowGf20 = (1 << 24),
474                 TxopAllowMm40 = (1 << 23),
475                 TxopAllowMm20 = (1 << 22),
476                 TxopAllowOfdm = (1 << 21),
477                 TxopAllowCck = (1 << 20),
478                 TxopAllowAll = (0x3f << 20),
479                 ProtNavShort = (1 << 18),
480                 ProtNavLong = (2 << 18),
481                 ProtCtrlRtsCts = (1 << 16),
482                 ProtCtrlCts = (2 << 16),
483         OfdmProtCfg = 0x1368,
484         Mm20ProtCfg = 0x136c,
485         Mm40ProtCfg = 0x1370,
486         Gf20ProtCfg = 0x1374,
487         Gf40ProtCfg = 0x1378,
488         ExpCtsTime = 0x137c,
489                 /* possible flags for registers EXP_{CTS,ACK}_TIME */
490                 ExpOfdmTimeShift = 16,
491                 ExpCckTimeShift = 0,
492         ExpAckTime = 0x1380,
493 };
494
495 enum {
496         /* MAC RX configuration registers */
497         RxFiltrCfg = 0x1400,
498                 DropCtrlRsv = (1 << 16),
499                 DropBar = (1 << 15),
500                 DropBa = (1 << 14),
501                 DropPspoll = (1 << 13),
502                 DropRts = (1 << 12),
503                 DropCts = (1 << 11),
504                 DropAck = (1 << 10),
505                 DropCfend = (1 << 9),
506                 DropCfack = (1 << 8),
507                 DropDupl = (1 << 7),
508                 DropBc = (1 << 6),
509                 DropMc = (1 << 5),
510                 DropVerErr = (1 << 4),
511                 DropNotMybss = (1 << 3),
512                 DropUcNome = (1 << 2),
513                 DropPhyErr = (1 << 1),
514                 DropCrcErr = (1 << 0),
515         AutoRspCfg = 0x1404,
516                 CtrlPwrBit = (1 << 7),
517                 BacAckPolicy = (1 << 6),
518                 CckShortEn = (1 << 4),
519                 Cts40mRefEn = (1 << 3),
520                 Cts40mModeEn = (1 << 2),
521                 BacAckpolicyEn = (1 << 1),
522                 AutoRspEn = (1 << 0),
523         LegacyBasicRate = 0x1408,
524         HtBasicRate = 0x140c,
525         HtCtrlCfg = 0x1410,
526         SifsCostCfg = 0x1414,
527                 OfdmSifsCostShift = 8,
528                 CckSifsCostShift = 0,
529         RxParserCfg = 0x1418,
530 };
531
532 enum {
533         /* MAC Security configuration registers */
534         TxSecCnt0 = 0x1500,
535         RxSecCnt0 = 0x1504,
536         CcmpFcMute = 0x1508,
537 };
538
539 enum {
540         /* MAC HCCA/PSMP configuration registers */
541         TxopHldrAddr0 = 0x1600,
542         TxopHldrAddr1 = 0x1604,
543         TxopHldrEt = 0x1608,
544                 TxopEtm1En = (1 << 25),
545                 TxopEtm0En = (1 << 24),
546                 TxopEtmThresShift = 16,
547                 TxopEtoEn = (1 << 8),
548                 TxopEtoThresShift = 1,
549                 PerRxRstEn = (1 << 0),
550         QosCfpollRaDw0 = 0x160c,
551         QosCfpollA1Dw1 = 0x1610,
552         QosCfpollQc = 0x1614,
553 };
554
555 enum {
556         /* MAC Statistics Counters */
557         RxStaCnt0 = 0x1700,
558         RxStaCnt1 = 0x1704,
559         RxStaCnt2 = 0x1708,
560         TxStaCnt0 = 0x170c,
561         TxStaCnt1 = 0x1710,
562         TxStaCnt2 = 0x1714,
563         TxStatFifo = 0x1718,
564                 TxqMcsShift = 16,
565                 TxqWcidShift = 8,
566                 TxqAckreq = (1 << 7),
567                 TxqAgg = (1 << 6),
568                 TxqOk = (1 << 5),
569                 TxqPidShift = 1,
570                 TxqVld = (1 << 0),
571 };
572
573 /* RX WCID search table */
574 #define WcidEntry(wcid) (0x1800 + (wcid) * 8)
575
576 enum {
577         FwBase = 0x2000,
578         Rt2870FwBase = 0x3000,
579 };
580
581 /* Pair-wise key table */
582 #define Pkey(wcid) (0x4000 + (wcid) * 32)
583
584 /* IV/EIV table */
585 #define Iveiv(wcid) (0x6000 + (wcid) * 8)
586
587 /* WCID attribute table */
588 #define WcidAttr(wcid) (0x6800 + (wcid) * 4)
589
590 /* possible flags for register WCID_ATTR */
591 enum {
592         ModeNosec = 0,
593         ModeWep40 = 1,
594         ModeWep104 = 2,
595         ModeTkip = 3,
596         ModeAesCcmp = 4,
597         ModeCkip40 = 5,
598         ModeCkip104 = 6,
599         ModeCkip128 = 7,
600         RxPkeyEn = (1 << 0),
601 };
602
603 /* Shared Key Table */
604 #define Skey(vap, kidx) (0x6c00 + (vap) * 128 + (kidx) * 32)
605
606 /* Shared Key Mode */
607 enum {
608         SkeyMode07 = 0x7000,
609         SkeyMode815 = 0x7004,
610         SkeyMode1623 = 0x7008,
611         SkeyMode2431 = 0x700c,
612 };
613
614 enum {
615         /* Shared Memory between MCU and host */
616         H2mMailbox = 0x7010,
617                 H2mBusy = (1 << 24),
618                 TokenNoIntr = 0xff,
619         H2mMailboxCid = 0x7014,
620         H2mMailboxStatus = 0x701c,
621         H2mBbpagent = 0x7028,
622 #define BcnBase(vap) (0x7800 + (vap) * 512)
623 };
624
625 /* 
626  *      RT2860 TX descriptor
627  *      --------------------
628  *      u32int  sdp0            Segment Data Pointer 0
629  *      u16int  sdl1            Segment Data Length 1
630  *      u16int  sdl0            Segment Data Length 0
631  *      u32int  sdp1            Segment Data Pointer 1
632  *      u8int   reserved[3]
633  *      u8int   flags
634  */
635
636 enum {
637         /* sdl1 flags */
638         TxBurst = (1 << 15),
639         TxLs1 = (1 << 14) /* SDP1 is the last segment */,
640         /* sdl0 flags */
641         TxDdone = (1 << 15),
642         TxLs0 = (1 << 14) /* SDP0 is the last segment */,
643         /* flags */
644         TxQselShift = 1,
645         TxQselMgmt = (0 << 1),
646         TxQselHcca = (1 << 1),
647         TxQselEdca = (2 << 1),
648         TxWiv = (1 << 0),
649 };
650
651 /* 
652  *      TX Wireless Information
653  *      -----------------------
654  *      u8int   flags
655  *      u8int   txop
656  *      u16int  phy
657  *      u8int   xflags
658  *      u8int   wcid    Wireless Client ID
659  *      u16int  len
660  *      u32int  iv
661  *      u32int  eiv
662  */
663
664 enum {
665         /* flags */
666         TxMpduDsityShift = 5,
667         TxAmpdu = (1 << 4),
668         TxTs = (1 << 3),
669         TxCfack = (1 << 2),
670         TxMmps = (1 << 1),
671         TxFrag = (1 << 0),
672         /* txop */
673         TxTxopHt = 0,
674         TxTxopPifs = 1,
675         TxTxopSifs = 2,
676         TxTxopBackoff = 3,
677         /* phy */
678         PhyMode = 0xc000,
679         PhyCck = (0 << 14),
680         PhyOfdm = (1 << 14),
681         PhyHt = (2 << 14),
682         PhyHtGf = (3 << 14),
683         PhySgi = (1 << 8),
684         PhyBw40 = (1 << 7),
685         PhyMcs = 0x7f,
686         PhyShpre = (1 << 3),
687         /* xflags */
688         TxBawinsizeShift = 2,
689         TxNseq = (1 << 1),
690         TxAck = (1 << 0),
691         /* len */
692         TxPidShift = 12,
693 };
694
695 /* 
696  *      RT2860 RX descriptor
697  *      --------------------
698  *      u32int  sdp0
699  *      u16int  sdl1    unused
700  *      u16int  sdl0
701  *      u32int  sdp1    unused
702  *      u32int  flags
703  */
704
705 enum {
706         /* sdl flags */
707         RxDdone = (1 << 15),
708         RxLs0 = (1 << 14),
709         /* flags */
710         RxDec = (1 << 16),
711         RxAmpdu = (1 << 15),
712         RxL2pad = (1 << 14),
713         RxRssi = (1 << 13),
714         RxHtc = (1 << 12),
715         RxAmsdu = (1 << 11),
716         RxMicerr = (1 << 10),
717         RxIcverr = (1 << 9),
718         RxCrcerr = (1 << 8),
719         RxMybss = (1 << 7),
720         RxBc = (1 << 6),
721         RxMc = (1 << 5),
722         RxUc2me = (1 << 4),
723         RxFrag = (1 << 3),
724         RxNull = (1 << 2),
725         RxData = (1 << 1),
726         RxBa = (1 << 0),
727 };
728
729 /* 
730  *      RX Wireless Information
731  *      -----------------------
732  *      u8int   wcid
733  *      u8int   keyidx
734  *      u16int  len
735  *      u16int  seq
736  *      u16int  phy
737  *      u8int   rssi[3]
738  *      u8int   reserved1
739  *      u8int   snr[2]
740  *      u16int  reserved2
741  */
742
743 enum {
744         /* keyidx flags */
745         RxUdfShift = 5,
746         RxBssIdxShift = 2,
747         /* len flags */
748         RxTidShift = 12,
749 };
750
751 enum {
752         WIFIHDRSIZE = 2+2+3*6+2,
753         Rdscsize = 16,
754         Tdscsize = 16,
755         Rbufsize = 4096,
756         Tbufsize = 4096,
757         Rxwisize = 16,
758         Txwisize = 16,
759         /* first DMA segment contains TXWI + 802.11 header + 32-bit padding */
760         TxwiDmaSz = Txwisize + WIFIHDRSIZE + 2
761 };
762
763 /* RF registers */
764 enum {
765         Rf1 = 0,
766         Rf2 = 2,
767         Rf3 = 1,
768         Rf4 = 3,
769 };
770
771 enum {
772         Rf2820 = 1 /* 2T3R */,
773         Rf2850 = 2 /* dual-band 2T3R */,
774         Rf2720 = 3 /* 1T2R */,
775         Rf2750 = 4 /* dual-band 1T2R */,
776         Rf3020 = 5 /* 1T1R */,
777         Rf2020 = 6 /* b/g */,
778         Rf3021 = 7 /* 1T2R */,
779         Rf3022 = 8 /* 2T2R */,
780         Rf3052 = 9 /* dual-band 2T2R */,
781         Rf3320 = 11 /* 1T1R */,
782         Rf3053 = 13 /* dual-band 3T3R */,
783 };
784
785 enum {  
786         Rt3070RfBlock = (1 << 0),
787         Rt3070Rx0Pd = (1 << 2),
788         Rt3070Tx0Pd = (1 << 3),
789         Rt3070Rx1Pd = (1 << 4),
790         Rt3070Tx1Pd = (1 << 5),
791         Rt3070Rx2Pd = (1 << 6),
792         Rt3070Tx2Pd = (1 << 7),
793         Rt3070Tune = (1 << 0),
794         Rt3070TxLo2 = (1 << 3),
795         Rt3070TxLo1 = (1 << 3),
796         Rt3070RxLo1 = (1 << 3),
797         Rt3070RxLo2 = (1 << 3),
798         Rt3070RxCtb = (1 << 7),
799         Rt3070BbLoopback = (1 << 0),
800
801         Rt3593Vco = (1 << 0),
802         Rt3593Rescal = (1 << 7),
803         Rt3593Vcocal = (1 << 7),
804         Rt3593VcoIc = (1 << 6),
805         Rt3593LdoPllVcMask = 0x0e,
806         Rt3593LdoRfVcMask = 0xe0,
807         Rt3593CpIcMask = 0xe0,
808         Rt3593CpIcShift = 5,
809         Rt3593RxCtb = (1 << 5)
810 };
811
812 static const char* rfnames[] = {
813         [Rf2820] "RT2820",
814         [Rf2850] "RT2850",
815         [Rf2720] "RT2720",
816         [Rf2750] "RT2750",
817         [Rf3020] "RT3020",
818         [Rf2020] "RT2020",
819         [Rf3021] "RT3021",
820         [Rf3022] "RT3022",
821         [Rf3052] "RT3052",
822         [Rf3320] "RT3320",
823         [Rf3053] "RT3053",
824 };
825
826 enum {
827         /* USB commands, RT2870 only */
828         Rt2870Reset = 1,
829         Rt2870Write2 = 2,
830         Rt2870WriteRegion1 = 6,
831         Rt2870ReadRegion1 = 7,
832         Rt2870EepromRead = 9,
833 };
834
835 enum {
836         EepromDelay = 1 /* minimum hold time (microsecond) */,
837
838         EepromVersion = 0x01,
839         EepromMac01 = 0x02,
840         EepromMac23 = 0x03,
841         EepromMac45 = 0x04,
842         EepromPciePslevel = 0x11,
843         EepromRev = 0x12,
844         EepromAntenna = 0x1a,
845         EepromConfig = 0x1b,
846         EepromCountry = 0x1c,
847         EepromFreqLeds = 0x1d,
848         EepromLed1 = 0x1e,
849         EepromLed2 = 0x1f,
850         EepromLed3 = 0x20,
851         EepromLna = 0x22,
852         EepromRssi12ghz = 0x23,
853         EepromRssi22ghz = 0x24,
854         EepromRssi15ghz = 0x25,
855         EepromRssi25ghz = 0x26,
856         EepromDeltapwr = 0x28,
857         EepromPwr2ghzBase1 = 0x29,
858         EepromPwr2ghzBase2 = 0x30,
859         EepromTssi12ghz = 0x37,
860         EepromTssi22ghz = 0x38,
861         EepromTssi32ghz = 0x39,
862         EepromTssi42ghz = 0x3a,
863         EepromTssi52ghz = 0x3b,
864         EepromPwr5ghzBase1 = 0x3c,
865         EepromPwr5ghzBase2 = 0x53,
866         EepromTssi15ghz = 0x6a,
867         EepromTssi25ghz = 0x6b,
868         EepromTssi35ghz = 0x6c,
869         EepromTssi45ghz = 0x6d,
870         EepromTssi55ghz = 0x6e,
871         EepromRpwr = 0x6f,
872         EepromBbpBase = 0x78,
873         Rt3071EepromRfBase = 0x82,
874 };
875
876 enum {
877         RidxCck1 = 0,
878         RidxCck11 = 3,
879         RidxOfdm6 = 4,
880         RidxMax = 11,
881 };
882
883 /* ring and pool count */
884 enum {
885         Nrx = 128,
886         Ntx = 64,
887         Ntxpool = Ntx * 2
888 };
889
890 typedef struct FWImage FWImage;
891 typedef struct TXQ TXQ;
892 typedef struct RXQ RXQ;
893 typedef struct Pool Pool;
894
895 typedef struct Ctlr Ctlr;
896
897 struct FWImage {
898         uint  size;
899         uchar *data;
900 };
901
902 struct TXQ
903 {
904         uint    n; /* next */
905         uint    i; /* current */
906         Block   **b;
907         u32int  *d; /* descriptors */
908
909         Rendez;
910         QLock;
911 };
912
913 struct RXQ
914 {
915         uint    i;
916         Block   **b;
917         u32int  *p;
918 };
919
920 struct Pool
921 {
922         uint i; /* current */
923         uchar *p; /* txwi */
924 };
925
926 struct Ctlr {
927         Lock;
928         QLock;
929
930         Ctlr *link;
931         Pcidev *pdev;
932         Wifi *wifi;
933
934         u16int mac_ver;
935         u16int mac_rev;
936         u8int rf_rev;
937         u8int freq;
938         u8int ntxchains;
939         u8int nrxchains;
940         u8int pslevel;
941         s8int txpow1[54];
942         s8int txpow2[54];
943         s8int rssi_2ghz[3];
944         s8int rssi_5ghz[3];
945         u8int lna[4];
946         u8int rf24_20mhz;
947         u8int rf24_40mhz;
948         u8int patch_dac;
949         u8int rfswitch;
950         u8int ext_2ghz_lna;
951         u8int ext_5ghz_lna;
952         u8int calib_2ghz;
953         u8int calib_5ghz;
954         u8int txmixgain_2ghz;
955         u8int txmixgain_5ghz;
956         u8int tssi_2ghz[9];
957         u8int tssi_5ghz[9];
958         u8int step_2ghz;
959         u8int step_5ghz;
960         uint mgtqid;
961
962         struct {
963                 u8int   reg;
964                 u8int   val;
965         } bbp[8], rf[10];
966         u8int leds;
967         u16int led[3];
968         u32int txpow20mhz[5];
969         u32int txpow40mhz_2ghz[5];
970         u32int txpow40mhz_5ghz[5];
971
972         int flags;
973
974         int port;
975         int power;
976         int active;
977         int broken;
978         int attached;
979
980         u32int *nic;
981
982         /* assigned node ids in hardware node table or -1 if unassigned */
983         int bcastnodeid;
984         int bssnodeid;
985         u8int wcid;
986         /* current receiver settings */
987         uchar bssid[Eaddrlen];
988         int channel;
989         int prom;
990         int aid;
991
992         RXQ rx;
993         TXQ tx[6];
994         Pool pool;
995
996         FWImage *fw;
997 };
998
999 /* controller flags */
1000 enum {
1001         AdvancedPs = 1 << 0,
1002         ConnPciE   = 1 << 1,
1003 };
1004
1005 static const struct rt2860_rate {
1006         u8int           rate;
1007         u8int           mcs;
1008         /*enum          ieee80211_phytype phy;*/
1009         u8int           ctl_ridx;
1010         u16int          sp_ack_dur;
1011         u16int          lp_ack_dur;
1012 } rt2860_rates[] = {
1013         {   2, 0,/* IEEE80211_T_DS,*/   0, 314, 314 },
1014         {   4, 1,/* IEEE80211_T_DS,*/   1, 258, 162 },
1015         {  11, 2,/* IEEE80211_T_DS,*/   2, 223, 127 },
1016         {  22, 3,/* IEEE80211_T_DS,*/   3, 213, 117 },
1017         {  12, 0,/* IEEE80211_T_OFDM,*/ 4,  60,  60 },
1018         {  18, 1,/* IEEE80211_T_OFDM,*/ 4,  52,  52 },
1019         {  24, 2,/* IEEE80211_T_OFDM,*/ 6,  48,  48 },
1020         {  36, 3,/* IEEE80211_T_OFDM,*/ 6,  44,  44 },
1021         {  48, 4,/* IEEE80211_T_OFDM,*/ 8,  44,  44 },
1022         {  72, 5,/* IEEE80211_T_OFDM,*/ 8,  40,  40 },
1023         {  96, 6,/* IEEE80211_T_OFDM,*/ 8,  40,  40 },
1024         { 108, 7,/* IEEE80211_T_OFDM,*/ 8,  40,  40 }
1025 };
1026
1027 /*
1028  * Default values for MAC registers; values taken from the reference driver.
1029  */
1030 static const struct {
1031         u32int  reg;
1032         u32int  val;
1033 } rt2860_def_mac[] = {
1034         { BcnOffset0,            0xf8f0e8e0 }, 
1035         { LegacyBasicRate,       0x0000013f }, 
1036         { HtBasicRate,           0x00008003 }, 
1037         { MacSysCtrl,            0x00000000 }, 
1038         { BkoffSlotCfg,          0x00000209 }, 
1039         { TxSwCfg0,                      0x00000000 }, 
1040         { TxSwCfg1,                      0x00080606 }, 
1041         { TxLinkCfg,             0x00001020 }, 
1042         { TxTimeoutCfg,          0x000a2090 }, 
1043         { LedCfg,                        0x7f031e46 }, 
1044         { WmmAifsnCfg,           0x00002273 }, 
1045         { WmmCwminCfg,           0x00002344 }, 
1046         { WmmCwmaxCfg,           0x000034aa }, 
1047         { MaxPcnt,                       0x1f3fbf9f }, 
1048         { TxRtyCfg,                      0x47d01f0f }, 
1049         { AutoRspCfg,            0x00000013 }, 
1050         { CckProtCfg,            0x05740003 }, 
1051         { OfdmProtCfg,           0x05740003 }, 
1052         { Gf20ProtCfg,           0x01744004 }, 
1053         { Gf40ProtCfg,           0x03f44084 }, 
1054         { Mm20ProtCfg,           0x01744004 }, 
1055         { Mm40ProtCfg,           0x03f54084 }, 
1056         { TxopCtrlCfg,           0x0000583f }, 
1057         { TxopHldrEt,            0x00000002 }, 
1058         { TxRtsCfg,                      0x00092b20 }, 
1059         { ExpAckTime,            0x002400ca }, 
1060         { XifsTimeCfg,           0x33a41010 }, 
1061         { PwrPinCfg,             0x00000003 },
1062 };
1063
1064 /*
1065  * Default values for BBP registers; values taken from the reference driver.
1066  */
1067 static const struct {
1068         u8int   reg;
1069         u8int   val;
1070 } rt2860_def_bbp[] = {
1071         {  65, 0x2c },  
1072         {  66, 0x38 },  
1073         {  69, 0x12 },  
1074         {  70, 0x0a },  
1075         {  73, 0x10 },  
1076         {  81, 0x37 },  
1077         {  82, 0x62 },  
1078         {  83, 0x6a },  
1079         {  84, 0x99 },  
1080         {  86, 0x00 },  
1081         {  91, 0x04 },  
1082         {  92, 0x00 },  
1083         { 103, 0x00 },  
1084         { 105, 0x05 },  
1085         { 106, 0x35 },
1086 };
1087
1088 /*
1089  * Default settings for RF registers; values derived from the reference driver.
1090  */
1091 static const struct rfprog {
1092         u8int           chan;
1093         u32int          r1, r2, r3, r4;
1094 } rt2860_rf2850[] = {
1095         {   1, 0x100bb3, 0x1301e1, 0x05a014, 0x001402 },        
1096         {   2, 0x100bb3, 0x1301e1, 0x05a014, 0x001407 },        
1097         {   3, 0x100bb3, 0x1301e2, 0x05a014, 0x001402 },        
1098         {   4, 0x100bb3, 0x1301e2, 0x05a014, 0x001407 },        
1099         {   5, 0x100bb3, 0x1301e3, 0x05a014, 0x001402 },        
1100         {   6, 0x100bb3, 0x1301e3, 0x05a014, 0x001407 },        
1101         {   7, 0x100bb3, 0x1301e4, 0x05a014, 0x001402 },        
1102         {   8, 0x100bb3, 0x1301e4, 0x05a014, 0x001407 },        
1103         {   9, 0x100bb3, 0x1301e5, 0x05a014, 0x001402 },        
1104         {  10, 0x100bb3, 0x1301e5, 0x05a014, 0x001407 },        
1105         {  11, 0x100bb3, 0x1301e6, 0x05a014, 0x001402 },        
1106         {  12, 0x100bb3, 0x1301e6, 0x05a014, 0x001407 },        
1107         {  13, 0x100bb3, 0x1301e7, 0x05a014, 0x001402 },        
1108         {  14, 0x100bb3, 0x1301e8, 0x05a014, 0x001404 },        
1109         {  36, 0x100bb3, 0x130266, 0x056014, 0x001408 },        
1110         {  38, 0x100bb3, 0x130267, 0x056014, 0x001404 },        
1111         {  40, 0x100bb2, 0x1301a0, 0x056014, 0x001400 },        
1112         {  44, 0x100bb2, 0x1301a0, 0x056014, 0x001408 },        
1113         {  46, 0x100bb2, 0x1301a1, 0x056014, 0x001402 },        
1114         {  48, 0x100bb2, 0x1301a1, 0x056014, 0x001406 },        
1115         {  52, 0x100bb2, 0x1301a2, 0x056014, 0x001404 },        
1116         {  54, 0x100bb2, 0x1301a2, 0x056014, 0x001408 },        
1117         {  56, 0x100bb2, 0x1301a3, 0x056014, 0x001402 },        
1118         {  60, 0x100bb2, 0x1301a4, 0x056014, 0x001400 },        
1119         {  62, 0x100bb2, 0x1301a4, 0x056014, 0x001404 },        
1120         {  64, 0x100bb2, 0x1301a4, 0x056014, 0x001408 },        
1121         { 100, 0x100bb2, 0x1301ac, 0x05e014, 0x001400 },        
1122         { 102, 0x100bb2, 0x1701ac, 0x15e014, 0x001404 },        
1123         { 104, 0x100bb2, 0x1701ac, 0x15e014, 0x001408 },        
1124         { 108, 0x100bb3, 0x17028c, 0x15e014, 0x001404 },        
1125         { 110, 0x100bb3, 0x13028d, 0x05e014, 0x001400 },        
1126         { 112, 0x100bb3, 0x13028d, 0x05e014, 0x001406 },        
1127         { 116, 0x100bb3, 0x13028e, 0x05e014, 0x001408 },        
1128         { 118, 0x100bb3, 0x13028f, 0x05e014, 0x001404 },        
1129         { 120, 0x100bb1, 0x1300e0, 0x05e014, 0x001400 },        
1130         { 124, 0x100bb1, 0x1300e0, 0x05e014, 0x001404 },        
1131         { 126, 0x100bb1, 0x1300e0, 0x05e014, 0x001406 },        
1132         { 128, 0x100bb1, 0x1300e0, 0x05e014, 0x001408 },        
1133         { 132, 0x100bb1, 0x1300e1, 0x05e014, 0x001402 },        
1134         { 134, 0x100bb1, 0x1300e1, 0x05e014, 0x001404 },        
1135         { 136, 0x100bb1, 0x1300e1, 0x05e014, 0x001406 },        
1136         { 140, 0x100bb1, 0x1300e2, 0x05e014, 0x001400 },        
1137         { 149, 0x100bb1, 0x1300e2, 0x05e014, 0x001409 },        
1138         { 151, 0x100bb1, 0x1300e3, 0x05e014, 0x001401 },        
1139         { 153, 0x100bb1, 0x1300e3, 0x05e014, 0x001403 },        
1140         { 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 },        
1141         { 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 },        
1142         { 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 },        
1143         { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 },        
1144         { 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 },        
1145         { 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 },        
1146         { 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 },        
1147         { 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 },
1148 };
1149
1150 struct {
1151         u8int n;
1152         u8int r;
1153         u8int k;
1154 } rt3090_freqs[] = {
1155         { 0xf1, 2,  2 },
1156         { 0xf1, 2,  7 },
1157         { 0xf2, 2,  2 },
1158         { 0xf2, 2,  7 },
1159         { 0xf3, 2,  2 },
1160         { 0xf3, 2,  7 },
1161         { 0xf4, 2,  2 },
1162         { 0xf4, 2,  7 },
1163         { 0xf5, 2,  2 },
1164         { 0xf5, 2,  7 },
1165         { 0xf6, 2,  2 },
1166         { 0xf6, 2,  7 },
1167         { 0xf7, 2,  2 },
1168         { 0xf8, 2,  4 },
1169         { 0x56, 0,  4 },
1170         { 0x56, 0,  6 },
1171         { 0x56, 0,  8 },
1172         { 0x57, 0,  0 },
1173         { 0x57, 0,  2 },
1174         { 0x57, 0,  4 },
1175         { 0x57, 0,  8 },
1176         { 0x57, 0, 10 },
1177         { 0x58, 0,  0 },
1178         { 0x58, 0,  4 },
1179         { 0x58, 0,  6 },
1180         { 0x58, 0,  8 },
1181         { 0x5b, 0,  8 },
1182         { 0x5b, 0, 10 },
1183         { 0x5c, 0,  0 },
1184         { 0x5c, 0,  4 },
1185         { 0x5c, 0,  6 },
1186         { 0x5c, 0,  8 },
1187         { 0x5d, 0,  0 },
1188         { 0x5d, 0,  2 },
1189         { 0x5d, 0,  4 },
1190         { 0x5d, 0,  8 },
1191         { 0x5d, 0, 10 },
1192         { 0x5e, 0,  0 },
1193         { 0x5e, 0,  4 },
1194         { 0x5e, 0,  6 },
1195         { 0x5e, 0,  8 },
1196         { 0x5f, 0,  0 },
1197         { 0x5f, 0,  9 },
1198         { 0x5f, 0, 11 },
1199         { 0x60, 0,  1 },
1200         { 0x60, 0,  5 },
1201         { 0x60, 0,  7 },
1202         { 0x60, 0,  9 },
1203         { 0x61, 0,  1 },
1204         { 0x61, 0,  3 },
1205         { 0x61, 0,  5 },
1206         { 0x61, 0,  7 },
1207         { 0x61, 0,  9 }
1208 };
1209
1210 static const struct {
1211         u8int reg;
1212         u8int val;
1213 } rt3090_def_rf[] = {
1214         {  4, 0x40 },
1215         {  5, 0x03 },
1216         {  6, 0x02 },
1217         {  7, 0x70 },
1218         {  9, 0x0f },
1219         { 10, 0x41 },
1220         { 11, 0x21 },
1221         { 12, 0x7b },
1222         { 14, 0x90 },
1223         { 15, 0x58 },
1224         { 16, 0xb3 },
1225         { 17, 0x92 },
1226         { 18, 0x2c },
1227         { 19, 0x02 },
1228         { 20, 0xba },
1229         { 21, 0xdb },
1230         { 24, 0x16 },
1231         { 25, 0x01 },
1232         { 29, 0x1f }
1233 };
1234
1235 /* vendors */
1236 enum {
1237         Ralink = 0x1814,
1238         Awt = 0x1a3b,
1239 };
1240 /* products */
1241 enum {
1242         RalinkRT2890 = 0x0681,
1243         RalinkRT2790 = 0x0781,
1244         RalinkRT3090 = 0x3090,
1245         AwtRT2890 = 0x1059,
1246 };
1247
1248 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
1249 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
1250
1251 static int rbplant(Ctlr*, int);
1252 static void setchan(Ctlr*, uint);
1253 static void rt3090setchan(Ctlr*, uint);
1254 static void selchangroup(Ctlr*, int);
1255 static void setleds(Ctlr*, u16int);
1256
1257 static uint
1258 get16(uchar *p){
1259         return *((u16int*)p);
1260 }
1261 static uint
1262 get32(uchar *p){
1263         return *((u32int*)p);
1264 }
1265 static void
1266 put32(uchar *p, uint v){
1267         *((u32int*)p) = v;
1268 }
1269 static void
1270 put16(uchar *p, uint v){
1271         *((u16int*)p) = v;
1272 };
1273 static void
1274 memwrite(Ctlr *ctlr, u32int off, uchar *data, uint size){
1275         memmove((uchar*)ctlr->nic + off, data, size);
1276 }
1277 static void
1278 setregion(Ctlr *ctlr, u32int off, uint val, uint size){
1279         memset((uchar*)ctlr->nic + off, val, size);
1280 }
1281
1282 static long
1283 rt2860ctl(Ether *edev, void *buf, long n)
1284 {
1285         Ctlr *ctlr;
1286
1287         ctlr = edev->ctlr;
1288         if(ctlr->wifi)
1289                 return wifictl(ctlr->wifi, buf, n);
1290         return 0;
1291 }
1292
1293 static long
1294 rt2860ifstat(Ether *edev, void *buf, long n, ulong off)
1295 {
1296         Ctlr *ctlr;
1297
1298         ctlr = edev->ctlr;
1299         if(ctlr->wifi)
1300                 return wifistat(ctlr->wifi, buf, n, off);
1301         return 0;
1302 }
1303
1304 static void
1305 setoptions(Ether *edev)
1306 {
1307         Ctlr *ctlr;
1308         int i;
1309
1310         ctlr = edev->ctlr;
1311         for(i = 0; i < edev->nopt; i++)
1312                 wificfg(ctlr->wifi, edev->opt[i]);
1313 }
1314
1315 static void
1316 rxon(Ether *edev, Wnode *bss)
1317 {
1318         u32int tmp;
1319         Ctlr *ctlr;
1320         int cap;
1321
1322         ctlr = edev->ctlr;
1323
1324         if(bss != nil){
1325                 cap = bss->cap;
1326                 ctlr->channel = bss->channel;
1327                 memmove(ctlr->bssid, bss->bssid, Eaddrlen);
1328                 ctlr->aid = bss->aid;
1329                 if(ctlr->aid != 0){
1330                         if(ctlr->wifi->debug)
1331                                 print("new assoc!");
1332                         ctlr->bssnodeid = -1;
1333                 }else
1334                         ctlr->bcastnodeid = -1;
1335         }else{
1336                 cap = 0;
1337                 memmove(ctlr->bssid, edev->bcast, Eaddrlen);
1338                 ctlr->aid = 0;
1339                 ctlr->bcastnodeid = -1;
1340                 ctlr->bssnodeid = -1;
1341         }
1342         if(ctlr->aid != 0)
1343                 setleds(ctlr, LedRadio | LedLink2ghz);
1344         else
1345                 setleds(ctlr, LedRadio);
1346
1347         if(ctlr->wifi->debug)
1348                 print("#l%d: rxon: bssid %E, aid %x, channel %d wcid %d\n",
1349                         edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, ctlr->wcid);
1350
1351         /* Set channel */
1352         if(ctlr->mac_ver >= 0x3071)
1353                 rt3090setchan(ctlr, ctlr->channel);
1354         else
1355                 setchan(ctlr, ctlr->channel);
1356         selchangroup(ctlr, 0);
1357         microdelay(1000);
1358
1359         /* enable mrr(?) */
1360 #define CCK(mcs)        (mcs)
1361 #define OFDM(mcs)       (1 << 3 | (mcs))
1362         csr32w(ctlr, LgFbkCfg0,
1363             OFDM(6) << 28 |     /* 54->48 */
1364             OFDM(5) << 24 |     /* 48->36 */
1365             OFDM(4) << 20 |     /* 36->24 */
1366             OFDM(3) << 16 |     /* 24->18 */
1367             OFDM(2) << 12 |     /* 18->12 */
1368             OFDM(1) <<  8 |     /* 12-> 9 */
1369             OFDM(0) <<  4 |     /*  9-> 6 */
1370             OFDM(0));           /*  6-> 6 */
1371
1372         csr32w(ctlr, LgFbkCfg1,
1373             CCK(2) << 12 |      /* 11->5.5 */
1374             CCK(1) <<  8 |      /* 5.5-> 2 */
1375             CCK(0) <<  4 |      /*   2-> 1 */
1376             CCK(0));            /*   1-> 1 */
1377 #undef OFDM
1378 #undef CCK
1379         /* update slot */
1380         tmp = csr32r(ctlr, BkoffSlotCfg);
1381         tmp &= ~0xff;
1382         tmp |= (cap & (1<<10)) ? 9 : 20;
1383         csr32w(ctlr, BkoffSlotCfg, tmp);
1384         
1385         /* set TX preamble */
1386         tmp = csr32r(ctlr, AutoRspCfg);
1387         tmp &= ~CckShortEn;
1388         if(cap & (1<<5)) tmp |= CckShortEn;     
1389         csr32w(ctlr, AutoRspCfg, tmp);
1390
1391         /* set basic rates */
1392         csr32w(ctlr, LegacyBasicRate, 0x003); /* 11B */
1393
1394         /* Set BSSID */
1395         csr32w(ctlr, MacBssidDw0,
1396             ctlr->bssid[0] | ctlr->bssid[1] << 8 | ctlr->bssid[2] << 16 | ctlr->bssid[3] << 24);
1397         csr32w(ctlr, MacBssidDw1,
1398             ctlr->bssid[4] | ctlr->bssid[5] << 8);
1399
1400         if(ctlr->bcastnodeid == -1){
1401                 ctlr->bcastnodeid = 0xff;
1402                 memwrite(ctlr, WcidEntry(ctlr->bcastnodeid), edev->bcast, Eaddrlen);
1403         }
1404         if(ctlr->bssnodeid == -1 && bss != nil && ctlr->aid != 0){
1405                 ctlr->bssnodeid = 0;
1406                 memwrite(ctlr, WcidEntry(ctlr->bssnodeid), ctlr->bssid, Eaddrlen);
1407         }
1408 }
1409
1410 static void
1411 rt2860promiscuous(void *arg, int on)
1412 {
1413         Ether *edev;
1414         Ctlr *ctlr;
1415
1416         edev = arg;
1417         ctlr = edev->ctlr;
1418         if(ctlr->attached == 0)
1419                 return;
1420         qlock(ctlr);
1421         ctlr->prom = on;
1422         rxon(edev, ctlr->wifi->bss);
1423         qunlock(ctlr);
1424 }
1425
1426 static void
1427 rt2860multicast(void *, uchar*, int)
1428 {
1429 }
1430
1431 static FWImage*
1432 readfirmware(void){
1433         static char name[] = "ral-rt2860";
1434         uchar dirbuf[sizeof(Dir)+100], *data;
1435         char buf[128];
1436         FWImage *fw;
1437         int n, r;
1438         Chan *c;
1439         Dir d;
1440
1441         if(!iseve())
1442                 error(Eperm);
1443         if(!waserror()){
1444                 snprint(buf, sizeof buf, "/boot/%s", name);
1445                 c = namec(buf, Aopen, OREAD, 0);
1446                 poperror();
1447         }else{
1448                 snprint(buf, sizeof buf, "/lib/firmware/%s", name);
1449                 c = namec(buf, Aopen, OREAD, 0);
1450         }
1451         if(waserror()){
1452                 cclose(c);
1453                 nexterror();
1454         }
1455         n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf);
1456         if(n <= 0)
1457                 error("can't stat firmware");
1458         convM2D(dirbuf, n, &d, nil);
1459         fw = malloc(sizeof(*fw));
1460         fw->size = d.length;
1461         data = fw->data = smalloc(d.length);
1462         if(waserror()){
1463                 free(fw);
1464                 nexterror();
1465         }
1466         r = 0;
1467         while(r < d.length){
1468                 n = devtab[c->type]->read(c, data+r, d.length-r, (vlong)r);
1469                 if(n <= 0)
1470                         break;
1471                 r += n;
1472         }
1473         poperror();
1474         poperror();
1475         cclose(c);
1476         return fw;
1477 }
1478
1479 static char*
1480 boot(Ctlr *ctlr)
1481 {
1482         int ntries;
1483
1484         /* set "host program ram write selection" bit */
1485         csr32w(ctlr, SysCtrl, HstPmSel);
1486         /* write microcode image */
1487         memwrite(ctlr, FwBase, ctlr->fw->data, ctlr->fw->size);
1488         /* kick microcontroller unit */
1489         csr32w(ctlr, SysCtrl, 0);
1490         coherence();
1491         csr32w(ctlr, SysCtrl, McuReset);
1492
1493         csr32w(ctlr, H2mBbpagent, 0);
1494         csr32w(ctlr, H2mMailbox, 0);
1495
1496         /* wait until microcontroller is ready */
1497         coherence();
1498         for(ntries = 0; ntries < 1000; ntries++){
1499                 if(csr32r(ctlr, SysCtrl) & McuReady)
1500                         break;
1501                 microdelay(1000);
1502         }
1503         if(ntries == 1000)
1504                 return "timeout waiting for MCU to initialize";
1505         return 0;
1506 }
1507
1508 /*
1509  * Send a command to the 8051 microcontroller unit.
1510  */
1511 static int
1512 mcucmd(Ctlr *ctlr, u8int cmd, u16int arg, int wait)
1513 {
1514         int slot, ntries;
1515         u32int tmp;
1516         u8int cid;
1517
1518         SET(slot);
1519         for(ntries = 0; ntries < 100; ntries++){
1520                 if(!(csr32r(ctlr, H2mMailbox) & H2mBusy))
1521                         break;
1522                 microdelay(2);
1523         }
1524         if(ntries == 100)
1525                 return -1;
1526
1527         cid = wait ? cmd : TokenNoIntr;
1528         csr32w(ctlr, H2mMailbox, H2mBusy | cid << 16 | arg);
1529         coherence();
1530         csr32w(ctlr, HostCmd, cmd);
1531
1532         if(!wait)
1533                 return 0;
1534         /* wait for the command to complete */
1535         for(ntries = 0; ntries < 200; ntries++){
1536                 tmp = csr32r(ctlr, H2mMailboxCid);
1537                 /* find the command slot */
1538                 for(slot = 0; slot < 4; slot++, tmp >>= 8)
1539                         if((tmp & 0xff) == cid)
1540                                 break;
1541                 if(slot < 4)
1542                         break;
1543                 microdelay(100);
1544         }
1545         if(ntries == 200){
1546                 /* clear command and status */
1547                 csr32w(ctlr, H2mMailboxStatus, 0xffffffff);
1548                 csr32w(ctlr, H2mMailboxCid, 0xffffffff);
1549                 return -1;
1550         }
1551         /* get command status (1 means success) */
1552         tmp = csr32r(ctlr, H2mMailboxStatus);
1553         tmp = (tmp >> (slot * 8)) & 0xff;
1554         /* clear command and status */
1555         csr32w(ctlr, H2mMailboxStatus, 0xffffffff);
1556         csr32w(ctlr, H2mMailboxCid, 0xffffffff);
1557         return (tmp == 1) ? 0 : -1;
1558 }
1559
1560
1561 /*
1562  * Reading and writing from/to the BBP is different from RT2560 and RT2661.
1563  * We access the BBP through the 8051 microcontroller unit which means that
1564  * the microcode must be loaded first.
1565  */
1566 static void
1567 bbpwrite(Ctlr *ctlr, u8int reg, u8int val)
1568 {
1569         int ntries;
1570
1571         for(ntries = 0; ntries < 100; ntries++){
1572                 if(!(csr32r(ctlr, H2mBbpagent) & BbpCsrKick))
1573                         break;
1574                 microdelay(1);
1575         }
1576         if(ntries == 100){
1577                 print("could not write to BBP through MCU\n");
1578                 return;
1579         }
1580
1581         csr32w(ctlr, H2mBbpagent, BbpRwParallel |
1582             BbpCsrKick | reg << 8 | val);
1583         coherence();
1584
1585         mcucmd(ctlr, McuCmdBbp, 0, 0);
1586         microdelay(1000);
1587 }
1588
1589 static u8int
1590 bbpread(Ctlr *ctlr, u8int reg)
1591 {
1592         u32int val;
1593         int ntries;
1594
1595         for(ntries = 0; ntries < 100; ntries++){
1596                 if(!(csr32r(ctlr, H2mBbpagent) & BbpCsrKick))
1597                         break;
1598                 microdelay(1);
1599         }
1600         if(ntries == 100){
1601                 print("could not read from BBP through MCU");
1602                 return 0;
1603         }
1604
1605         csr32w(ctlr, H2mBbpagent, BbpRwParallel |
1606             BbpCsrKick | BbpCsrRead | reg << 8);
1607         coherence();
1608
1609         mcucmd(ctlr, McuCmdBbp, 0, 0);
1610         microdelay(1000);
1611
1612         for(ntries = 0; ntries < 100; ntries++){
1613                 val = csr32r(ctlr, H2mBbpagent);
1614                 if(!(val & BbpCsrKick))
1615                         return val & 0xff;
1616                 microdelay(1);
1617         }
1618         print("could not read from BBP through MCU\n");
1619
1620         return 0;
1621 }
1622
1623 static char*
1624 bbpinit(Ctlr *ctlr)
1625 {
1626         int i, ntries;
1627         char *err;
1628
1629         /* wait for BBP to wake up */
1630         for(ntries = 0; ntries < 20; ntries++){
1631                 u8int bbp0 = bbpread(ctlr, 0);
1632                 if(bbp0 != 0 && bbp0 != 0xff)
1633                         break;
1634         }
1635         if(ntries == 20){
1636                 err = "timeout waiting for BBP to wake up";
1637                 return err;
1638         }
1639
1640         /* initialize BBP registers to default values */
1641         for(i = 0; i < nelem(rt2860_def_bbp); i++){
1642                 bbpwrite(ctlr, rt2860_def_bbp[i].reg,
1643                     rt2860_def_bbp[i].val);
1644         }
1645
1646         /* fix BBP84 for RT2860E */
1647         if(ctlr->mac_ver == 0x2860 && ctlr->mac_rev != 0x0101)
1648                 bbpwrite(ctlr, 84, 0x19);
1649
1650         if(ctlr->mac_ver >= 0x3071){
1651                 bbpwrite(ctlr, 79, 0x13);
1652                 bbpwrite(ctlr, 80, 0x05);
1653                 bbpwrite(ctlr, 81, 0x33);
1654         }else if(ctlr->mac_ver == 0x2860 && ctlr->mac_rev == 0x0100){
1655                 bbpwrite(ctlr, 69, 0x16);
1656                 bbpwrite(ctlr, 73, 0x12);
1657         }
1658
1659         return nil;
1660
1661 }
1662
1663 static void
1664 setleds(Ctlr *ctlr, u16int which)
1665 {
1666         mcucmd(ctlr, McuCmdLeds,
1667             which | (ctlr->leds & 0x7f), 0);
1668 }
1669
1670 static char*
1671 txrxon(Ctlr *ctlr)
1672 {
1673         u32int tmp;
1674         int ntries;
1675         char *err;
1676
1677         SET(tmp);
1678         /* enable Tx/Rx DMA engine */
1679         csr32w(ctlr, MacSysCtrl, MacTxEn);
1680         coherence();
1681         for(ntries = 0; ntries < 200; ntries++){
1682                 tmp = csr32r(ctlr, WpdmaGloCfg);
1683                 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
1684                         break;
1685                 microdelay(1000);
1686         }
1687         if(ntries == 200){
1688                 err = "timeout waiting for DMA engine";
1689                 return err;
1690         }
1691
1692         microdelay(50);
1693
1694         tmp |= RxDmaEn | TxDmaEn |
1695             WpdmaBtSize64 << WpdmaBtSizeShift;
1696         csr32w(ctlr, WpdmaGloCfg, tmp);
1697
1698         /* set Rx filter */
1699         tmp = DropCrcErr | DropPhyErr;
1700         if(!ctlr->prom){
1701                 tmp |= DropUcNome | DropDupl |
1702                     DropCts | DropBa | DropAck |
1703                     DropVerErr | DropCtrlRsv |
1704                     DropCfack | DropCfend;
1705                 tmp |= DropRts | DropPspoll;
1706         } 
1707         csr32w(ctlr, RxFiltrCfg, tmp);
1708
1709         csr32w(ctlr, MacSysCtrl, MacRxEn | MacTxEn);
1710
1711         return 0;
1712 }
1713
1714 /*
1715  * Write to one of the 4 programmable 24-bit RF registers.
1716  */
1717 static void
1718 rfwrite(Ctlr *ctlr, u8int reg, u32int val)
1719 {
1720         u32int tmp;
1721         int ntries;
1722
1723         for(ntries = 0; ntries < 100; ntries++){
1724                 if(!(csr32r(ctlr, RfCsrCfg0) & RfRegCtrl))
1725                         break;
1726                 microdelay(1);
1727         }
1728         if(ntries == 100){
1729                 print("could not write to RF\n");
1730                 return;
1731         }
1732
1733         /* RF registers are 24-bit on the RT2860 */
1734         tmp = RfRegCtrl | 24 << RfRegWidthShift |
1735             (val & 0x3fffff) << 2 | (reg & 3);
1736         csr32w(ctlr, RfCsrCfg0, tmp);
1737 }
1738
1739 u8int
1740 rt3090rfread(Ctlr *ctlr, u8int reg)
1741 {
1742         u32int tmp;
1743         int ntries;
1744
1745         for(ntries = 0; ntries < 100; ntries++){
1746                 if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
1747                         break;
1748                 microdelay(1);
1749         }
1750         if(ntries == 100){
1751                 print("could not read RF register\n");
1752                 return 0xff;
1753         }
1754         tmp = Rt3070RfKick | reg << 8;
1755         csr32w(ctlr, Rt3070RfCsrCfg, tmp);
1756
1757         for(ntries = 0; ntries < 100; ntries++){
1758                 tmp = csr32r(ctlr, Rt3070RfCsrCfg);
1759                 if(!(tmp & Rt3070RfKick))
1760                         break;
1761                 microdelay(1);
1762         }
1763         if(ntries == 100){
1764                 print("could not read RF register\n");
1765                 return 0xff;
1766         }
1767         return tmp & 0xff;
1768 }
1769
1770 static void
1771 rt3090rfwrite(Ctlr *ctlr, u8int reg, u8int val)
1772 {
1773         u32int tmp;
1774         int ntries;
1775
1776         for(ntries = 0; ntries < 10; ntries++){
1777                 if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
1778                         break;
1779                 microdelay(10);
1780         }
1781         if(ntries == 10){
1782                 print("could not write to RF\n");
1783                 return;
1784         }
1785
1786         tmp = Rt3070RfWrite | Rt3070RfKick | reg << 8 | val;
1787         csr32w(ctlr, Rt3070RfCsrCfg, tmp);
1788 }
1789
1790 static void
1791 selchangroup(Ctlr *ctlr, int group)
1792 {
1793         u32int tmp;
1794         u8int agc;
1795
1796         bbpwrite(ctlr, 62, 0x37 - ctlr->lna[group]);
1797         bbpwrite(ctlr, 63, 0x37 - ctlr->lna[group]);
1798         bbpwrite(ctlr, 64, 0x37 - ctlr->lna[group]);
1799         bbpwrite(ctlr, 86, 0x00);
1800
1801         if(group == 0){
1802                 if(ctlr->ext_2ghz_lna){
1803                         bbpwrite(ctlr, 82, 0x62);
1804                         bbpwrite(ctlr, 75, 0x46);
1805                 }else{
1806                         bbpwrite(ctlr, 82, 0x84);
1807                         bbpwrite(ctlr, 75, 0x50);
1808                 }
1809         }else{
1810                 if(ctlr->ext_5ghz_lna){
1811                         bbpwrite(ctlr, 82, 0xf2);
1812                         bbpwrite(ctlr, 75, 0x46);
1813                 }else{
1814                         bbpwrite(ctlr, 82, 0xf2);
1815                         bbpwrite(ctlr, 75, 0x50);
1816                 }
1817         }
1818
1819         tmp = csr32r(ctlr, TxBandCfg);
1820         tmp &= ~(Tx5gBandSelN | Tx5gBandSelP);
1821         tmp |= (group == 0) ? Tx5gBandSelN : Tx5gBandSelP;
1822         csr32w(ctlr, TxBandCfg, tmp);
1823
1824         /* enable appropriate Power Amplifiers and Low Noise Amplifiers */
1825         tmp = RftrEn | TrswEn | LnaPe0En;
1826         if(ctlr->nrxchains > 1)
1827                 tmp |= LnaPe1En;
1828         if(ctlr->mac_ver == 0x3593 && ctlr->nrxchains > 2)
1829                 tmp |= Rt3593LnaPe2En;
1830         if(group == 0){ /* 2GHz */
1831                 tmp |= PaPeG0En;
1832                 if(ctlr->ntxchains > 1)
1833                         tmp |= PaPeG1En;
1834                 if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains > 2)
1835                         tmp |= Rt3593PaPeG2En;
1836         }else{          /* 5GHz */
1837                 tmp |= PaPeA0En;
1838                 if(ctlr->ntxchains > 1)
1839                         tmp |= PaPeA1En;
1840                 if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains > 2)
1841                         tmp |= Rt3593PaPeA2En;
1842         }
1843         csr32w(ctlr, TxPinCfg, tmp);
1844
1845         if(ctlr->mac_ver == 0x3593){
1846                 tmp = csr32r(ctlr, GpioCtrl);
1847                 if(ctlr->flags & ConnPciE){
1848                         tmp &= ~0x01010000;
1849                         if(group == 0)
1850                                 tmp |= 0x00010000;
1851                 }else{
1852                         tmp &= ~0x00008080;
1853                         if(group == 0)
1854                                 tmp |= 0x00000080;
1855                 }
1856                 tmp = (tmp & ~0x00001000) | 0x00000010;
1857                 csr32w(ctlr, GpioCtrl, tmp);
1858         }
1859
1860         /* set initial AGC value */
1861         if(group == 0){ /* 2GHz band */
1862                 if(ctlr->mac_ver >= 0x3071)
1863                         agc = 0x1c + ctlr->lna[0] * 2;
1864                 else
1865                         agc = 0x2e + ctlr->lna[0];
1866         }else{          /* 5GHz band */
1867                 agc = 0x32 + (ctlr->lna[group] * 5) / 3;
1868         }
1869         bbpwrite(ctlr, 66, agc);
1870
1871         microdelay(1000);
1872
1873 }
1874
1875 static void
1876 setchan(Ctlr *ctlr, uint chan)
1877 {
1878         const struct rfprog *rfprog = rt2860_rf2850;
1879         u32int r2, r3, r4;
1880         s8int txpow1, txpow2;
1881         uint i;
1882
1883         /* find the settings for this channel (we know it exists) */
1884         for(i = 0; rfprog[i].chan != chan; i++);
1885
1886         r2 = rfprog[i].r2;
1887         if(ctlr->ntxchains == 1)
1888                 r2 |= 1 << 12;          /* 1T: disable Tx chain 2 */
1889         if(ctlr->nrxchains == 1)
1890                 r2 |= 1 << 15 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */
1891         else if(ctlr->nrxchains == 2)
1892                 r2 |= 1 << 4;           /* 2R: disable Rx chain 3 */
1893
1894         /* use Tx power values from EEPROM */
1895         txpow1 = ctlr->txpow1[i];
1896         txpow2 = ctlr->txpow2[i];
1897         if(chan > 14){
1898                 if(txpow1 >= 0)
1899                         txpow1 = txpow1 << 1 | 1;
1900                 else
1901                         txpow1 = (7 + txpow1) << 1;
1902                 if(txpow2 >= 0)
1903                         txpow2 = txpow2 << 1 | 1;
1904                 else
1905                         txpow2 = (7 + txpow2) << 1;
1906         }
1907         r3 = rfprog[i].r3 | txpow1 << 7;
1908         r4 = rfprog[i].r4 | ctlr->freq << 13 | txpow2 << 4;
1909
1910         rfwrite(ctlr, Rf1, rfprog[i].r1);
1911         rfwrite(ctlr, Rf2, r2);
1912         rfwrite(ctlr, Rf3, r3);
1913         rfwrite(ctlr, Rf4, r4);
1914
1915         microdelay(200);
1916
1917         rfwrite(ctlr, Rf1, rfprog[i].r1);
1918         rfwrite(ctlr, Rf2, r2);
1919         rfwrite(ctlr, Rf3, r3 | 1);
1920         rfwrite(ctlr, Rf4, r4);
1921
1922         microdelay(200);
1923
1924         rfwrite(ctlr, Rf1, rfprog[i].r1);
1925         rfwrite(ctlr, Rf2, r2);
1926         rfwrite(ctlr, Rf3, r3);
1927         rfwrite(ctlr, Rf4, r4);
1928 }
1929
1930 static void
1931 rt3090setchan(Ctlr *ctlr, uint chan)
1932 {
1933         s8int txpow1, txpow2;
1934         u8int rf;
1935         int i;
1936
1937         assert(chan >= 1 && chan <= 14);        /* RT3090 is 2GHz only */
1938
1939         /* find the settings for this channel (we know it exists) */
1940         for(i = 0; rt2860_rf2850[i].chan != chan; i++);
1941
1942         /* use Tx power values from EEPROM */
1943         txpow1 = ctlr->txpow1[i];
1944         txpow2 = ctlr->txpow2[i];
1945
1946         rt3090rfwrite(ctlr, 2, rt3090_freqs[i].n);
1947         rf = rt3090rfread(ctlr, 3);
1948         rf = (rf & ~0x0f) | rt3090_freqs[i].k;
1949         rt3090rfwrite(ctlr, 3, rf);
1950         rf = rt3090rfread(ctlr, 6);
1951         rf = (rf & ~0x03) | rt3090_freqs[i].r;
1952         rt3090rfwrite(ctlr, 6, rf);
1953
1954         /* set Tx0 power */
1955         rf = rt3090rfread(ctlr, 12);
1956         rf = (rf & ~0x1f) | txpow1;
1957         rt3090rfwrite(ctlr, 12, rf);
1958
1959         /* set Tx1 power */
1960         rf = rt3090rfread(ctlr, 13);
1961         rf = (rf & ~0x1f) | txpow2;
1962         rt3090rfwrite(ctlr, 13, rf);
1963
1964         rf = rt3090rfread(ctlr, 1);
1965         rf &= ~0xfc;
1966         if(ctlr->ntxchains == 1)
1967                 rf |= Rt3070Tx1Pd | Rt3070Tx2Pd;
1968         else if(ctlr->ntxchains == 2)
1969                 rf |= Rt3070Tx2Pd;
1970         if(ctlr->nrxchains == 1)
1971                 rf |= Rt3070Rx1Pd | Rt3070Rx2Pd;
1972         else if(ctlr->nrxchains == 2)
1973                 rf |= Rt3070Rx2Pd;
1974         rt3090rfwrite(ctlr, 1, rf);
1975
1976         /* set RF offset */
1977         rf = rt3090rfread(ctlr, 23);
1978         rf = (rf & ~0x7f) | ctlr->freq;
1979         rt3090rfwrite(ctlr, 23, rf);
1980
1981         /* program RF filter */
1982         rf = rt3090rfread(ctlr, 24);    /* Tx */
1983         rf = (rf & ~0x3f) | ctlr->rf24_20mhz;
1984         rt3090rfwrite(ctlr, 24, rf);
1985         rf = rt3090rfread(ctlr, 31);    /* Rx */
1986         rf = (rf & ~0x3f) | ctlr->rf24_20mhz;
1987         rt3090rfwrite(ctlr, 31, rf);
1988
1989         /* enable RF tuning */
1990         rf = rt3090rfread(ctlr, 7);
1991         rt3090rfwrite(ctlr, 7, rf | Rt3070Tune);
1992 }
1993
1994 static int
1995 rt3090filtercalib(Ctlr *ctlr, u8int init, u8int target, u8int *val)
1996 {
1997         u8int rf22, rf24;
1998         u8int bbp55_pb, bbp55_sb, delta;
1999         int ntries;
2000
2001         /* program filter */
2002         rf24 = rt3090rfread(ctlr, 24);
2003         rf24 = (rf24 & 0xc0) | init;    /* initial filter value */
2004         rt3090rfwrite(ctlr, 24, rf24);
2005
2006         /* enable baseband loopback mode */
2007         rf22 = rt3090rfread(ctlr, 22);
2008         rt3090rfwrite(ctlr, 22, rf22 | Rt3070BbLoopback);
2009
2010         /* set power and frequency of passband test tone */
2011         bbpwrite(ctlr, 24, 0x00);
2012         for(ntries = 0, bbp55_pb = 0; ntries < 100; ntries++){
2013                 /* transmit test tone */
2014                 bbpwrite(ctlr, 25, 0x90);
2015                 microdelay(1000);
2016                 /* read received power */
2017                 bbp55_pb = bbpread(ctlr, 55);
2018                 if(bbp55_pb != 0)
2019                         break;
2020         }
2021         if(ntries == 100)
2022                 return -1;
2023
2024         /* set power and frequency of stopband test tone */
2025         bbpwrite(ctlr, 24, 0x06);
2026         for(ntries = 0; ntries < 100; ntries++){
2027                 /* transmit test tone */
2028                 bbpwrite(ctlr, 25, 0x90);
2029                 microdelay(1000);
2030                 /* read received power */
2031                 bbp55_sb = bbpread(ctlr, 55);
2032
2033                 delta = bbp55_pb - bbp55_sb;
2034                 if(delta > target)
2035                         break;
2036
2037                 /* reprogram filter */
2038                 rf24++;
2039                 rt3090rfwrite(ctlr, 24, rf24);
2040         }
2041         if(ntries < 100){
2042                 if(rf24 != init)
2043                         rf24--; /* backtrack */
2044                 *val = rf24;
2045                 rt3090rfwrite(ctlr, 24, rf24);
2046         }
2047
2048         /* restore initial state */
2049         bbpwrite(ctlr, 24, 0x00);
2050
2051         /* disable baseband loopback mode */
2052         rf22 = rt3090rfread(ctlr, 22);
2053         rt3090rfwrite(ctlr, 22, rf22 & ~Rt3070BbLoopback);
2054
2055         return 0;
2056 }
2057
2058 static void
2059 rt3090setrxantenna(Ctlr *ctlr, int aux)
2060 {
2061         u32int tmp;
2062
2063         if(aux){
2064                 tmp = csr32r(ctlr, PciEectrl);
2065                 csr32w(ctlr, PciEectrl, tmp & ~EectrlC);
2066                 tmp = csr32r(ctlr, GpioCtrl);
2067                 csr32w(ctlr, GpioCtrl, (tmp & ~0x0808) | 0x08);
2068         }else{
2069                 tmp = csr32r(ctlr, PciEectrl);
2070                 csr32w(ctlr, PciEectrl, tmp | EectrlC);
2071                 tmp = csr32r(ctlr, GpioCtrl);
2072                 csr32w(ctlr, GpioCtrl, tmp & ~0x0808);
2073         }
2074 }
2075
2076 static int
2077 rt3090rfinit(Ctlr *ctlr)
2078 {
2079         u32int tmp;
2080         u8int rf, bbp;
2081         int i;
2082
2083         rf = rt3090rfread(ctlr, 30);
2084         /* toggle RF R30 bit 7 */
2085         rt3090rfwrite(ctlr, 30, rf | 0x80);
2086         microdelay(1000);
2087         rt3090rfwrite(ctlr, 30, rf & ~0x80);
2088
2089         tmp = csr32r(ctlr, Rt3070LdoCfg0);
2090         tmp &= ~0x1f000000;
2091         if(ctlr->patch_dac && ctlr->mac_rev < 0x0211)
2092                 tmp |= 0x0d000000;      /* 1.35V */
2093         else
2094                 tmp |= 0x01000000;      /* 1.2V */
2095         csr32w(ctlr, Rt3070LdoCfg0, tmp);
2096
2097         /* patch LNA_PE_G1 */
2098         tmp = csr32r(ctlr, Rt3070GpioSwitch);
2099         csr32w(ctlr, Rt3070GpioSwitch, tmp & ~0x20);
2100
2101         /* initialize RF registers to default value */
2102         for(i = 0; i < nelem(rt3090_def_rf); i++){
2103                 rt3090rfwrite(ctlr, rt3090_def_rf[i].reg,
2104                     rt3090_def_rf[i].val);
2105         }
2106
2107         /* select 20MHz bandwidth */
2108         rt3090rfwrite(ctlr, 31, 0x14);
2109
2110         rf = rt3090rfread(ctlr, 6);
2111         rt3090rfwrite(ctlr, 6, rf | 0x40);
2112
2113         if(ctlr->mac_ver != 0x3593){
2114                 /* calibrate filter for 20MHz bandwidth */
2115                 ctlr->rf24_20mhz = 0x1f;        /* default value */
2116                 rt3090filtercalib(ctlr, 0x07, 0x16, &ctlr->rf24_20mhz);
2117
2118                 /* select 40MHz bandwidth */
2119                 bbp = bbpread(ctlr, 4);
2120                 bbpwrite(ctlr, 4, (bbp & ~0x08) | 0x10);
2121                 rf = rt3090rfread(ctlr, 31);
2122                 rt3090rfwrite(ctlr, 31, rf | 0x20);
2123
2124                 /* calibrate filter for 40MHz bandwidth */
2125                 ctlr->rf24_40mhz = 0x2f;        /* default value */
2126                 rt3090filtercalib(ctlr, 0x27, 0x19, &ctlr->rf24_40mhz);
2127
2128                 /* go back to 20MHz bandwidth */
2129                 bbp = bbpread(ctlr, 4);
2130                 bbpwrite(ctlr, 4, bbp & ~0x18);
2131         }
2132         if(ctlr->mac_rev < 0x0211)
2133                 rt3090rfwrite(ctlr, 27, 0x03);
2134
2135         tmp = csr32r(ctlr, Rt3070Opt14);
2136         csr32w(ctlr, Rt3070Opt14, tmp | 1);
2137
2138         if(ctlr->rf_rev == Rf3020)
2139                 rt3090setrxantenna(ctlr, 0);
2140
2141         bbp = bbpread(ctlr, 138);
2142         if(ctlr->mac_ver == 0x3593){
2143                 if(ctlr->ntxchains == 1)
2144                         bbp |= 0x60;    /* turn off DAC1 and DAC2 */
2145                 else if(ctlr->ntxchains == 2)
2146                         bbp |= 0x40;    /* turn off DAC2 */
2147                 if(ctlr->nrxchains == 1)
2148                         bbp &= ~0x06;   /* turn off ADC1 and ADC2 */
2149                 else if(ctlr->nrxchains == 2)
2150                         bbp &= ~0x04;   /* turn off ADC2 */
2151         }else{
2152                 if(ctlr->ntxchains == 1)
2153                         bbp |= 0x20;    /* turn off DAC1 */
2154                 if(ctlr->nrxchains == 1)
2155                         bbp &= ~0x02;   /* turn off ADC1 */
2156         }
2157         bbpwrite(ctlr, 138, bbp);
2158
2159         rf = rt3090rfread(ctlr, 1);
2160         rf &= ~(Rt3070Rx0Pd | Rt3070Tx0Pd);
2161         rf |= Rt3070RfBlock | Rt3070Rx1Pd | Rt3070Tx1Pd;
2162         rt3090rfwrite(ctlr, 1, rf);
2163
2164         rf = rt3090rfread(ctlr, 15);
2165         rt3090rfwrite(ctlr, 15, rf & ~Rt3070TxLo2);
2166
2167         rf = rt3090rfread(ctlr, 17);
2168         rf &= ~Rt3070TxLo1;
2169         if(ctlr->mac_rev >= 0x0211 && !ctlr->ext_2ghz_lna)
2170                 rf |= 0x20;     /* fix for long range Rx issue */
2171         if(ctlr->txmixgain_2ghz >= 2)
2172                 rf = (rf & ~0x7) | ctlr->txmixgain_2ghz;
2173         rt3090rfwrite(ctlr, 17, rf);
2174
2175         rf = rt3090rfread(ctlr, 20);
2176         rt3090rfwrite(ctlr, 20, rf & ~Rt3070RxLo1);
2177
2178         rf = rt3090rfread(ctlr, 21);
2179         rt3090rfwrite(ctlr, 21, rf & ~Rt3070RxLo2);
2180
2181         return 0;
2182 }
2183
2184 static void
2185 rt3090rfwakeup(Ctlr *ctlr)
2186 {
2187         u32int tmp;
2188         u8int rf;
2189
2190         if(ctlr->mac_ver == 0x3593){
2191                 /* enable VCO */
2192                 rf = rt3090rfread(ctlr, 1);
2193                 rt3090rfwrite(ctlr, 1, rf | Rt3593Vco);
2194
2195                 /* initiate VCO calibration */
2196                 rf = rt3090rfread(ctlr, 3);
2197                 rt3090rfwrite(ctlr, 3, rf | Rt3593Vcocal);
2198
2199                 /* enable VCO bias current control */
2200                 rf = rt3090rfread(ctlr, 6);
2201                 rt3090rfwrite(ctlr, 6, rf | Rt3593VcoIc);
2202
2203                 /* initiate res calibration */
2204                 rf = rt3090rfread(ctlr, 2);
2205                 rt3090rfwrite(ctlr, 2, rf | Rt3593Rescal);
2206
2207                 /* set reference current control to 0.33 mA */
2208                 rf = rt3090rfread(ctlr, 22);
2209                 rf &= ~Rt3593CpIcMask;
2210                 rf |= 1 << Rt3593CpIcShift;
2211                 rt3090rfwrite(ctlr, 22, rf);
2212
2213                 /* enable RX CTB */
2214                 rf = rt3090rfread(ctlr, 46);
2215                 rt3090rfwrite(ctlr, 46, rf | Rt3593RxCtb);
2216
2217                 rf = rt3090rfread(ctlr, 20);
2218                 rf &= ~(Rt3593LdoRfVcMask | Rt3593LdoPllVcMask);
2219                 rt3090rfwrite(ctlr, 20, rf);
2220         }else{
2221                 /* enable RF block */
2222                 rf = rt3090rfread(ctlr, 1);
2223                 rt3090rfwrite(ctlr, 1, rf | Rt3070RfBlock);
2224
2225                 /* enable VCO bias current control */
2226                 rf = rt3090rfread(ctlr, 7);
2227                 rt3090rfwrite(ctlr, 7, rf | 0x30);
2228
2229                 rf = rt3090rfread(ctlr, 9);
2230                 rt3090rfwrite(ctlr, 9, rf | 0x0e);
2231
2232                 /* enable RX CTB */
2233                 rf = rt3090rfread(ctlr, 21);
2234                 rt3090rfwrite(ctlr, 21, rf | Rt3070RxCtb);
2235
2236                 /* fix Tx to Rx IQ glitch by raising RF voltage */
2237                 rf = rt3090rfread(ctlr, 27);
2238                 rf &= ~0x77;
2239                 if(ctlr->mac_rev < 0x0211)
2240                         rf |= 0x03;
2241                 rt3090rfwrite(ctlr, 27, rf);
2242         }
2243         if(ctlr->patch_dac && ctlr->mac_rev < 0x0211){
2244                 tmp = csr32r(ctlr, Rt3070LdoCfg0);
2245                 tmp = (tmp & ~0x1f000000) | 0x0d000000;
2246                 csr32w(ctlr, Rt3070LdoCfg0, tmp);
2247         }
2248 }
2249
2250 static void
2251 rt3090rfsetup(Ctlr *ctlr)
2252 {
2253         u8int bbp;
2254         int i;
2255
2256         if(ctlr->mac_rev >= 0x0211){
2257                 /* enable DC filter */
2258                 bbpwrite(ctlr, 103, 0xc0);
2259
2260                 /* improve power consumption */
2261                 bbp = bbpread(ctlr, 31);
2262                 bbpwrite(ctlr, 31, bbp & ~0x03);
2263         }
2264
2265         csr32w(ctlr, TxSwCfg1, 0);
2266         if(ctlr->mac_rev < 0x0211){
2267                 csr32w(ctlr, TxSwCfg2,
2268                     ctlr->patch_dac ? 0x2c : 0x0f);
2269         }else
2270                 csr32w(ctlr, TxSwCfg2, 0);
2271
2272         /* initialize RF registers from ROM */
2273         for(i = 0; i < 10; i++){
2274                 if(ctlr->rf[i].reg == 0 || ctlr->rf[i].reg == 0xff)
2275                         continue;
2276                 rt3090rfwrite(ctlr, ctlr->rf[i].reg, ctlr->rf[i].val);
2277         }
2278 }
2279
2280 static void
2281 updateprot(Ctlr *ctlr)
2282 {
2283         u32int tmp;
2284
2285         tmp = RtsthEn | ProtNavShort | TxopAllowAll;
2286         /* setup protection frame rate (MCS code) */
2287         tmp |= /*(ic->ic_curmode == IEEE80211_MODE_11A) ?
2288             rt2860_rates[RT2860_RIDX_OFDM6].mcs :*/
2289             rt2860_rates[RidxCck11].mcs;
2290
2291         /* CCK frames don't require protection */
2292         csr32w(ctlr, CckProtCfg, tmp);
2293 /* XXX
2294         if(ic->ic_flags & IEEE80211_F_USEPROT){
2295                 if(ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2296                         tmp |= ProtCtrlRtsCts;
2297                 else if(ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2298                         tmp |= ProtCtrlCts;
2299         }
2300         csr32w(ctlr, OfdmProtCfg, tmp); */
2301 }
2302
2303 static char*
2304 rt2860start(Ether *edev)
2305 {
2306         u32int tmp;
2307         u8int bbp1, bbp3;
2308         int i, qid, ridx, ntries;
2309         char *err;
2310         Ctlr *ctlr;
2311
2312         ctlr = edev->ctlr;
2313         csr32w(ctlr, PwrPinCfg, IoRaPe);
2314
2315         /* disable DMA */
2316         tmp = csr32r(ctlr, WpdmaGloCfg);
2317         tmp &= 0xff0;
2318         csr32w(ctlr, WpdmaGloCfg, tmp);
2319
2320         /* PBF hardware reset */
2321         csr32w(ctlr, SysCtrl, 0xe1f);
2322         coherence();
2323         csr32w(ctlr, SysCtrl, 0xe00);
2324
2325         if((err = boot(ctlr)) != nil){
2326                 /*XXX: rt2860stop(ifp, 1);*/
2327                 return err;
2328         }
2329         /* set MAC address */
2330         csr32w(ctlr, MacAddrDw0,
2331             edev->ea[0] | edev->ea[1] << 8 | edev->ea[2] << 16 | edev->ea[3] << 24);
2332         csr32w(ctlr, MacAddrDw1,
2333             edev->ea[4] | edev->ea[5] << 8 | 0xff << 16);
2334
2335         /* init Tx power for all Tx rates (from EEPROM) */
2336         for(ridx = 0; ridx < 5; ridx++){
2337                 if(ctlr->txpow20mhz[ridx] == 0xffffffff)
2338                         continue;
2339                 csr32w(ctlr, TxPwrCfg(ridx), ctlr->txpow20mhz[ridx]);
2340         }
2341
2342         for(ntries = 0; ntries < 100; ntries++){
2343                 tmp = csr32r(ctlr, WpdmaGloCfg);
2344                 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
2345                         break;
2346                 microdelay(1000);
2347         }
2348         if(ntries == 100){
2349                 err = "timeout waiting for DMA engine";
2350                 /*rt2860_stop(ifp, 1);*/
2351                 return err;
2352         }
2353         tmp &= 0xff0;
2354         csr32w(ctlr, WpdmaGloCfg, tmp);
2355
2356         /* reset Rx ring and all 6 Tx rings */
2357         csr32w(ctlr, WpdmaRstIdx, 0x1003f);
2358
2359         /* PBF hardware reset */
2360         csr32w(ctlr, SysCtrl, 0xe1f);
2361         coherence();
2362         csr32w(ctlr, SysCtrl, 0xe00);
2363
2364         csr32w(ctlr, PwrPinCfg, IoRaPe | IoRfPe);
2365
2366         csr32w(ctlr, MacSysCtrl, BbpHrst | MacSrst);
2367         coherence();
2368         csr32w(ctlr, MacSysCtrl, 0);
2369
2370         for(i = 0; i < nelem(rt2860_def_mac); i++)
2371                 csr32w(ctlr, rt2860_def_mac[i].reg, rt2860_def_mac[i].val);
2372         if(ctlr->mac_ver >= 0x3071){
2373                 /* set delay of PA_PE assertion to 1us (unit of 0.25us) */
2374                 csr32w(ctlr, TxSwCfg0,
2375                     4 << DlyPapeEnShift);
2376         }
2377
2378         if(!(csr32r(ctlr, PciCfg) & PciCfgPci)){
2379                 ctlr->flags |= ConnPciE;
2380                 /* PCIe has different clock cycle count than PCI */
2381                 tmp = csr32r(ctlr, UsCycCnt);
2382                 tmp = (tmp & ~0xff) | 0x7d;
2383                 csr32w(ctlr, UsCycCnt, tmp);
2384         }
2385
2386         /* wait while MAC is busy */
2387         for(ntries = 0; ntries < 100; ntries++){
2388                 if(!(csr32r(ctlr, MacStatusReg) &
2389                     (RxStatusBusy | TxStatusBusy)))
2390                         break;
2391                 microdelay(1000);
2392         }
2393         if(ntries == 100){
2394                 err = "timeout waiting for MAC";
2395                 /*rt2860_stop(ifp, 1);*/
2396                 return err;
2397         }
2398
2399         /* clear Host to MCU mailbox */
2400         csr32w(ctlr, H2mBbpagent, 0);
2401         csr32w(ctlr, H2mMailbox, 0);
2402
2403         mcucmd(ctlr, McuCmdRfreset, 0, 0);
2404         microdelay(1000);
2405
2406         if((err = bbpinit(ctlr)) != nil){
2407                 /*rt2860_stop(ifp, 1);*/
2408                 return err;
2409         }
2410         /* clear RX WCID search table */
2411         setregion(ctlr, WcidEntry(0), 0, 512);
2412         /* clear pairwise key table */
2413         setregion(ctlr, Pkey(0), 0, 2048);
2414         /* clear IV/EIV table */
2415         setregion(ctlr, Iveiv(0), 0, 512);
2416         /* clear WCID attribute table */
2417         setregion(ctlr, WcidAttr(0), 0, 256);
2418         /* clear shared key table */
2419         setregion(ctlr, Skey(0, 0), 0, 8 * 32);
2420         /* clear shared key mode */
2421         setregion(ctlr, SkeyMode07, 0, 4);
2422
2423         /* init Tx rings (4 EDCAs + HCCA + Mgt) */
2424         for(qid = 0; qid < 6; qid++){
2425                 csr32w(ctlr, TxBasePtr(qid), PCIWADDR(ctlr->tx[qid].d));
2426                 csr32w(ctlr, TxMaxCnt(qid), Ntx);
2427                 csr32w(ctlr, TxCtxIdx(qid), 0);
2428         }
2429
2430         /* init Rx ring */
2431         csr32w(ctlr, RxBasePtr, PCIWADDR(ctlr->rx.p));
2432         csr32w(ctlr, RxMaxCnt, Nrx);
2433         csr32w(ctlr, RxCalcIdx, Nrx - 1);
2434
2435         /* setup maximum buffer sizes */
2436         csr32w(ctlr, MaxLenCfg, 1 << 12 |
2437             (Rbufsize - Rxwisize - 2));
2438
2439         for(ntries = 0; ntries < 100; ntries++){
2440                 tmp = csr32r(ctlr, WpdmaGloCfg);
2441                 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
2442                         break;
2443                 microdelay(1000);
2444         }
2445         if(ntries == 100){
2446                 err = "timeout waiting for DMA engine";
2447                 /*rt2860_stop(ifp, 1);*/
2448                 return err;
2449         }
2450         tmp &= 0xff0;
2451         csr32w(ctlr, WpdmaGloCfg, tmp);
2452
2453         /* disable interrupts mitigation */
2454         csr32w(ctlr, DelayIntCfg, 0);
2455
2456         /* write vendor-specific BBP values (from EEPROM) */
2457         for(i = 0; i < 8; i++){
2458                 if(ctlr->bbp[i].reg == 0 || ctlr->bbp[i].reg == 0xff)
2459                         continue;
2460                 bbpwrite(ctlr, ctlr->bbp[i].reg, ctlr->bbp[i].val);
2461         }
2462
2463         /* select Main antenna for 1T1R devices */
2464         if(ctlr->rf_rev == Rf2020 ||
2465             ctlr->rf_rev == Rf3020 ||
2466             ctlr->rf_rev == Rf3320)
2467                 rt3090setrxantenna(ctlr, 0);
2468
2469         /* send LEDs operating mode to microcontroller */
2470         mcucmd(ctlr, McuCmdLed1, ctlr->led[0], 0);
2471         mcucmd(ctlr, McuCmdLed2, ctlr->led[1], 0);
2472         mcucmd(ctlr, McuCmdLed3, ctlr->led[2], 0);
2473
2474         if(ctlr->mac_ver >= 0x3071)
2475                 rt3090rfinit(ctlr);
2476
2477         mcucmd(ctlr, McuCmdSleep, 0x02ff, 1);
2478         mcucmd(ctlr, McuCmdWakeup, 0, 1);
2479
2480         if(ctlr->mac_ver >= 0x3071)
2481                 rt3090rfwakeup(ctlr);
2482
2483         /* disable non-existing Rx chains */
2484         bbp3 = bbpread(ctlr, 3);
2485         bbp3 &= ~(1 << 3 | 1 << 4);
2486         if(ctlr->nrxchains == 2)
2487                 bbp3 |= 1 << 3;
2488         else if(ctlr->nrxchains == 3)
2489                 bbp3 |= 1 << 4;
2490         bbpwrite(ctlr, 3, bbp3);
2491
2492         /* disable non-existing Tx chains */
2493         bbp1 = bbpread(ctlr, 1);
2494         if(ctlr->ntxchains == 1)
2495                 bbp1 = (bbp1 & ~(1 << 3 | 1 << 4));
2496         else if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains == 2)
2497                 bbp1 = (bbp1 & ~(1 << 4)) | 1 << 3;
2498         else if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains == 3)
2499                 bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4;
2500         bbpwrite(ctlr, 1, bbp1);
2501
2502         if(ctlr->mac_ver >= 0x3071)
2503                 rt3090rfsetup(ctlr);
2504
2505         /* select default channel */
2506         if(ctlr->mac_ver >= 0x3071)
2507                 rt3090setchan(ctlr, 3);
2508         else
2509                 setchan(ctlr, 3);
2510
2511         /* reset RF from MCU */
2512         mcucmd(ctlr, McuCmdRfreset, 0, 0);
2513
2514         /* set RTS threshold */
2515         tmp = csr32r(ctlr, TxRtsCfg);
2516         tmp &= ~0xffff00;
2517         tmp |= 1 /* ic->ic_rtsthreshold */ << 8;
2518         csr32w(ctlr, TxRtsCfg, tmp);
2519
2520         /* setup initial protection mode */
2521         updateprot(ctlr);
2522
2523         /* turn radio LED on */
2524         setleds(ctlr, LedRadio);
2525
2526         /* enable Tx/Rx DMA engine */
2527         if((err = txrxon(ctlr)) != 0){
2528                 /*rt2860_stop(ifp, 1);*/
2529                 return err;
2530         }
2531
2532         /* clear pending interrupts */
2533         csr32w(ctlr, IntStatus, 0xffffffff);
2534         /* enable interrupts */
2535         csr32w(ctlr, IntMask, 0x3fffc);
2536
2537         if(ctlr->flags & AdvancedPs)
2538                 mcucmd(ctlr, McuCmdPslevel, ctlr->pslevel, 0);
2539         return nil;
2540 }
2541
2542 /*
2543  * Add `delta' (signed) to each 4-bit sub-word of a 32-bit word.
2544  * Used to adjust per-rate Tx power registers.
2545  */
2546 static u32int
2547 b4inc(u32int b32, s8int delta)
2548 {
2549         s8int i, b4;
2550
2551         for(i = 0; i < 8; i++){
2552                 b4 = b32 & 0xf;
2553                 b4 += delta;
2554                 if(b4 < 0)
2555                         b4 = 0;
2556                 else if(b4 > 0xf)
2557                         b4 = 0xf;
2558                 b32 = b32 >> 4 | b4 << 28;
2559         }
2560         return b32;
2561 }
2562
2563 static void
2564 transmit(Wifi *wifi, Wnode *wn, Block *b)
2565 {
2566         Ether *edev;
2567         Ctlr *ctlr;
2568         Wifipkt *w;
2569         u8int mcs, qid;
2570         int ridx, /*ctl_ridx,*/ hdrlen;
2571         uchar *p;
2572         int nodeid;
2573         Block *outb;
2574         TXQ *tx;
2575         Pool *pool;
2576
2577         edev = wifi->ether;
2578         ctlr = edev->ctlr;
2579
2580         qlock(ctlr);
2581         if(ctlr->attached == 0 || ctlr->broken){
2582                 qunlock(ctlr);
2583                 freeb(b);
2584                 return;
2585         }
2586         if((wn->channel != ctlr->channel)
2587         || (!ctlr->prom && (wn->aid != ctlr->aid || memcmp(wn->bssid, ctlr->bssid, Eaddrlen) != 0)))
2588                 rxon(edev, wn);
2589
2590         if(b == nil){
2591                 /* association note has no data to transmit */
2592                 qunlock(ctlr);
2593                 return;
2594         }
2595
2596         pool = &ctlr->pool;
2597         qid = 0; /* for now */
2598         ridx = 0; 
2599         tx = &ctlr->tx[qid];
2600
2601         nodeid = ctlr->bcastnodeid;
2602         w = (Wifipkt*)b->rp;
2603         hdrlen = wifihdrlen(w);
2604
2605         p = pool->p + pool->i * TxwiDmaSz;
2606         if((w->a1[0] & 1) == 0){
2607                 *(p+4) = TxAck; /* xflags */
2608
2609                 if(BLEN(b) > 512-4)
2610                         *(p+1) = TxTxopBackoff; /* txop */ 
2611
2612                 if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
2613                         nodeid = ctlr->bssnodeid;
2614                         ridx = 2; /* BUG: hardcode 11Mbit */
2615                 }
2616         }
2617
2618         /*ctl_ridx = rt2860_rates[ridx].ctl_ridx;*/
2619         mcs = rt2860_rates[ridx].mcs;
2620
2621         /* setup TX Wireless Information */
2622         *p = 0; /* flags */
2623         *(p+2) = PhyCck | mcs; /* phy */
2624         /* let HW generate seq numbers */
2625         *(p+4) |= TxNseq; /* xflags */
2626         put16(p + 6, BLEN(b) | (((mcs+1) & 0xf) << TxPidShift) ); /* length */
2627
2628 /*      put16((uchar*)&w->dur[0], rt2860_rates[ctl_ridx].lp_ack_dur); */
2629
2630         *(p+5) = nodeid; /* wcid */
2631
2632         /* copy packet header */
2633         memmove(p + Txwisize, b->rp, hdrlen);
2634         
2635         /* setup tx descriptor */
2636         /* first segment is TXWI + 802.11 header */
2637         p = (uchar*)tx->d + Tdscsize * tx->i;
2638         put32(p, PCIWADDR(pool->p + pool->i * TxwiDmaSz)); /* sdp0 */
2639         put16(p + 6, Txwisize + hdrlen); /* sdl0 */
2640         *(p + 15) = TxQselEdca; /* flags */
2641
2642         /* allocate output buffer */
2643         b->rp += hdrlen;
2644         tx->b[tx->i] = outb = iallocb(BLEN(b) + 256);
2645         if(outb == nil){
2646                 print("outb = nil\n");
2647                 return;
2648         }
2649         outb->rp = (uchar*)ROUND((uintptr)outb->base, 256);
2650         memset(outb->rp, 0, BLEN(b));
2651         memmove(outb->rp, b->rp, BLEN(b));
2652         outb->wp = outb->rp + BLEN(b);
2653         freeb(b);
2654
2655         /* setup payload segments */
2656         put32(p + 8, PCIWADDR(outb->rp)); /* sdp1 */
2657         put16(p + 4, BLEN(outb) | TxLs1); /* sdl1 */
2658
2659         p = pool->p + pool->i * TxwiDmaSz;
2660         w = (Wifipkt*)(p + Txwisize);
2661         if(ctlr->wifi->debug){
2662                 print("transmit: %E->%E,%E nodeid=%x txq[%d]=%d size=%zd\n", w->a2, w->a1, w->a3, nodeid, qid, ctlr->tx[qid].i, BLEN(outb));
2663         }
2664
2665         tx->i = (tx->i + 1) % Ntx;
2666         pool->i = (pool->i + 1) % Ntxpool;
2667
2668         coherence();
2669
2670         /* kick Tx */
2671         csr32w(ctlr, TxCtxIdx(qid), ctlr->tx[qid].i);
2672
2673         qunlock(ctlr);
2674         return;
2675 }
2676
2677 static void
2678 rt2860attach(Ether *edev)
2679 {
2680         FWImage *fw;
2681         Ctlr *ctlr;
2682         char *err;
2683
2684         ctlr = edev->ctlr;
2685         eqlock(ctlr);
2686         if(waserror()){
2687                 print("#l%d: %s\n", edev->ctlrno, up->errstr);
2688                 /*if(ctlr->power)
2689                         poweroff(ctlr);*/
2690                 qunlock(ctlr);
2691                 nexterror();
2692         }
2693         if(ctlr->attached == 0){
2694                 if(ctlr->wifi == nil)
2695                         ctlr->wifi = wifiattach(edev, transmit);
2696
2697                 if(ctlr->fw == nil){
2698                         fw = readfirmware();
2699                         ctlr->fw = fw;
2700                 }
2701                 if((err = rt2860start(edev)) != nil){
2702                         error(err);
2703                 } 
2704
2705                 ctlr->bcastnodeid = -1;
2706                 ctlr->bssnodeid = -1;
2707                 ctlr->channel = 1;
2708                 ctlr->aid = 0;
2709
2710                 setoptions(edev);
2711
2712                 ctlr->attached = 1;
2713         }
2714         qunlock(ctlr);
2715         poperror();
2716 }
2717
2718 static void
2719 receive(Ctlr *ctlr)
2720 {
2721         u32int hw;
2722         RXQ *rx;
2723         Block *b;
2724         uchar *d;
2725
2726         rx = &ctlr->rx;
2727         if(rx->b == nil){
2728                 print("rx->b == nil!");
2729                 return;
2730         }
2731         hw = csr32r(ctlr, FsDrxIdx) & 0xfff;
2732         while(rx->i != hw){
2733                 u16int sdl0, len;
2734                 u32int flags;
2735                 uchar *p;
2736                 Wifipkt *w;
2737                 int hdrlen;
2738
2739                 p = (uchar*)rx->p + Rdscsize * rx->i;
2740                 sdl0 = get16(p + 4 /* sdp0 */ + 2 /* sdl1 */);
2741                 if(!(sdl0 & RxDdone)){
2742                         print("rxd ddone bit not set\n");
2743                         break; /* should not happen */
2744                 }
2745                 flags = get32(p + 12);
2746                 if(flags & (RxCrcerr | RxIcverr)){
2747                 /*      print("crc | icv err\n"); */
2748                         goto skip; 
2749                 }
2750
2751                 b = rx->b[rx->i];
2752                 if(b == nil){
2753                         print("no buf\n");
2754                         goto skip;
2755                 }       
2756                 d = b->rp;
2757                 if(ctlr->wifi == nil)
2758                         goto skip;
2759                 if(rbplant(ctlr, rx->i) < 0){
2760                         print("can't plant");
2761                         goto skip;
2762                 }
2763                 ctlr->wcid = *b->rp;
2764                 len = get16(b->rp + 2 /* wcid, keyidx */) & 0xfff;
2765                 b->rp = d + Rxwisize;
2766                 b->wp = b->rp + len;
2767                 w = (Wifipkt*)b->rp;
2768                 hdrlen = wifihdrlen(w);
2769                 /* HW may insert 2 padding bytes after 802.11 header */
2770                 if(flags & RxL2pad){
2771                         memmove(b->rp + 2, b->rp, hdrlen);
2772                         b->rp += 2;
2773                 }
2774                 w = (Wifipkt*)b->rp;
2775                 if(ctlr->wifi->debug)
2776                         print("receive: %E->%E,%E wcid 0x%x \n", w->a2, w->a1, w->a3, ctlr->wcid);
2777                 wifiiq(ctlr->wifi, b);
2778 skip:
2779                 put16(p + 4 /* sdp0 */ + 2 /* sdl1 */, sdl0 & ~RxDdone);
2780                 rx->i = (rx->i + 1) % Nrx;
2781         }
2782         coherence();
2783         /* tell HW what we have processed */
2784         csr32w(ctlr, RxCalcIdx, (rx->i - 1) % Nrx);
2785 }
2786
2787 static void
2788 stats(Ctlr *ctlr)
2789 {
2790         u32int stat;
2791         u8int wcid;
2792
2793         while((stat = csr32r(ctlr, TxStatFifo)) & TxqVld){
2794                 wcid = (stat >> TxqWcidShift) & 0xff;
2795                 /* if no ACK was requested, no feedback is available */
2796                 if(!(stat & TxqAckreq) || wcid == 0xff){
2797                         continue;
2798                 }
2799         }
2800 }
2801
2802 static void
2803 rt2860tx(Ctlr *ctlr, u8int q)
2804 {
2805         u32int hw;
2806         TXQ *tx;
2807
2808         stats(ctlr);
2809         tx = &ctlr->tx[q];
2810         hw = csr32r(ctlr, TxDtxIdx(q));
2811         while(tx->n != hw){
2812                 uchar *p = (uchar*)tx->d + Rdscsize * tx->n;
2813                 u16int sdl0;
2814
2815                 if(tx->b[tx->n]){
2816                         freeb(tx->b[tx->n]);
2817                         tx->b[tx->n] = nil;
2818                 }
2819                 sdl0 = get16(p + 4 /* sdp0 */ + 2 /* sdl1 */);
2820                 if(!(sdl0 & TxDdone)){
2821                         print("txd ddone bit not set\n");
2822                         break; /* should not happen */
2823                 }
2824                 memset((uchar*)ctlr->pool.p + TxwiDmaSz * tx->n, 0, TxwiDmaSz);
2825                 memset((uchar*)tx->d + Tdscsize * tx->n, 0, Tdscsize);
2826                 // put16(p + 4 /* sdp0 */ + 2 /* sdl1 */, sdl0 & ~TxDdone);
2827                 tx->n = (tx->n + 1) % Ntx;
2828         }
2829         coherence();
2830 }
2831
2832 static void
2833 rt2860interrupt(Ureg*, void *arg)
2834 {
2835         u32int r;
2836         Ether *edev;
2837         Ctlr *ctlr;
2838         int debug;
2839
2840         edev = arg;
2841         ctlr = edev->ctlr;
2842         ilock(ctlr);
2843
2844         debug = ctlr->wifi->debug;
2845
2846         r = csr32r(ctlr, IntStatus);
2847         if(r == 0xffffffff){
2848                 iunlock(ctlr);
2849                 return;
2850         }
2851         if(r == 0){
2852                 iunlock(ctlr);
2853                 return;
2854         }
2855
2856         /* acknowledge interrupts */
2857         csr32w(ctlr, IntStatus, r);
2858
2859         if(r & TxRxCoherent){
2860                 u32int tmp;
2861                 /* DMA finds data coherent event when checking the DDONE bit */
2862                 if(debug)
2863                         print("txrx coherent intr\n");
2864
2865                 /* restart DMA engine */
2866                 tmp = csr32r(ctlr, WpdmaGloCfg);
2867                 tmp &= ~(TxWbDdone | RxDmaEn | TxDmaEn);
2868                 csr32w(ctlr, WpdmaGloCfg, tmp);
2869
2870                 txrxon(ctlr);
2871         }
2872         if(r & MacInt2)
2873                 stats(ctlr);
2874         
2875         if(r & TxDoneInt5)
2876                 rt2860tx(ctlr, 5);
2877
2878         if(r & RxDoneInt)
2879                 receive(ctlr);
2880
2881         if(r & TxDoneInt4)
2882                 rt2860tx(ctlr, 4);
2883
2884         if(r & TxDoneInt3)
2885                 rt2860tx(ctlr, 3);
2886
2887         if(r & TxDoneInt2)
2888                 rt2860tx(ctlr, 2);
2889
2890         if(r & TxDoneInt1)
2891                 rt2860tx(ctlr, 1);
2892
2893         if(r & TxDoneInt0)
2894                 rt2860tx(ctlr, 0);
2895
2896         iunlock(ctlr);
2897 }
2898
2899 static void
2900 eepromctl(Ctlr *ctlr, u32int val)
2901 {
2902         csr32w(ctlr, PciEectrl, val);
2903         coherence();
2904         microdelay(EepromDelay);        
2905 }
2906
2907 /*
2908  * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46,
2909  * 93C66 or 93C86).
2910  */
2911 static u16int
2912 eeread2(Ctlr *ctlr, u16int addr)
2913 {
2914         u32int tmp;
2915         u16int val;
2916         int n;
2917
2918         /* clock C once before the first command */
2919         eepromctl(ctlr, 0);
2920
2921         eepromctl(ctlr, EectrlS);
2922         eepromctl(ctlr, EectrlS | EectrlC);
2923         eepromctl(ctlr, EectrlS);
2924
2925         /* write start bit (1) */
2926         eepromctl(ctlr, EectrlS | EectrlD);
2927         eepromctl(ctlr, EectrlS | EectrlD | EectrlC);
2928
2929         /* write READ opcode (10) */
2930         eepromctl(ctlr, EectrlS | EectrlD);
2931         eepromctl(ctlr, EectrlS | EectrlD | EectrlC);
2932         eepromctl(ctlr, EectrlS);
2933         eepromctl(ctlr, EectrlS | EectrlC);
2934
2935         /* write address (A5-A0 or A7-A0) */
2936         n = ((csr32r(ctlr, PciEectrl) & 0x30) == 0) ? 5 : 7;
2937         for(; n >= 0; n--){
2938                 eepromctl(ctlr, EectrlS |
2939                     (((addr >> n) & 1) << EectrlShiftD));
2940                 eepromctl(ctlr, EectrlS |
2941                     (((addr >> n) & 1) << EectrlShiftD) | EectrlC);
2942         }
2943
2944         eepromctl(ctlr, EectrlS);
2945
2946         /* read data Q15-Q0 */
2947         val = 0;
2948         for(n = 15; n >= 0; n--){
2949                 eepromctl(ctlr, EectrlS | EectrlC);
2950                 tmp = csr32r(ctlr, PciEectrl);
2951                 val |= ((tmp & EectrlQ) >> EectrlShiftQ) << n;
2952                 eepromctl(ctlr, EectrlS);
2953         }
2954
2955         eepromctl(ctlr, 0);
2956
2957         /* clear Chip Select and clock C */
2958         eepromctl(ctlr, EectrlS);
2959         eepromctl(ctlr, 0);
2960         eepromctl(ctlr, EectrlC);
2961
2962         return val;
2963 }
2964
2965 /* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
2966 static u16int
2967 efuseread2(Ctlr *ctlr, u16int addr)
2968 {
2969         u32int tmp;
2970         u16int reg;
2971         int ntries;
2972
2973         addr *= 2;
2974         /*-
2975          * Read one 16-byte block into registers EFUSE_DATA[0-3]:
2976          * DATA0: F E D C
2977          * DATA1: B A 9 8
2978          * DATA2: 7 6 5 4
2979          * DATA3: 3 2 1 0
2980          */
2981         tmp = csr32r(ctlr, Rt3070EfuseCtrl);
2982         tmp &= ~(Rt3070EfsromModeMask | Rt3070EfsromAinMask);
2983         tmp |= (addr & ~0xf) << Rt3070EfsromAinShift | Rt3070EfsromKick;
2984         csr32w(ctlr, Rt3070EfuseCtrl, tmp);
2985         for(ntries = 0; ntries < 500; ntries++){
2986                 tmp = csr32r(ctlr, Rt3070EfuseCtrl);
2987                 if(!(tmp & Rt3070EfsromKick))
2988                         break;
2989                 microdelay(2);
2990         }
2991         if(ntries == 500)
2992                 return 0xffff;
2993
2994         if((tmp & Rt3070EfuseAoutMask) == Rt3070EfuseAoutMask)
2995                 return 0xffff;  /* address not found */
2996
2997         /* determine to which 32-bit register our 16-bit word belongs */
2998         reg = Rt3070EfuseData3 - (addr & 0xc);
2999         tmp = csr32r(ctlr, reg);
3000
3001         return (addr & 2) ? tmp >> 16 : tmp & 0xffff;
3002 }
3003
3004 static char*
3005 eepromread(Ether *edev)
3006 {
3007         s8int delta_2ghz, delta_5ghz;
3008         u32int tmp;
3009         u16int val;
3010         int ridx, ant, i;
3011         u16int (*rom_read)(Ctlr*, u16int);
3012         Ctlr *ctlr;
3013
3014         enum { DefLna = 10 };
3015
3016         ctlr = edev->ctlr;
3017         /* check whether the ROM is eFUSE ROM or EEPROM */
3018         rom_read = eeread2;
3019         if(ctlr->mac_ver >= 0x3071){
3020                 tmp = csr32r(ctlr, Rt3070EfuseCtrl);
3021                 if(tmp & Rt3070SelEfuse)
3022                         rom_read = efuseread2;
3023         }
3024
3025         /* read MAC address */
3026         val = rom_read(ctlr, EepromMac01);
3027         edev->ea[0] = val & 0xff;
3028         edev->ea[1] = val >> 8;
3029         val = rom_read(ctlr, EepromMac23);
3030         edev->ea[2] = val & 0xff;
3031         edev->ea[3] = val >> 8;
3032         val = rom_read(ctlr, EepromMac45);
3033         edev->ea[4] = val & 0xff;
3034         edev->ea[5] = val >> 8;
3035
3036         /* read vendor BBP settings */
3037         for(i = 0; i < 8; i++){
3038                 val = rom_read(ctlr, EepromBbpBase + i);
3039                 ctlr->bbp[i].val = val & 0xff;
3040                 ctlr->bbp[i].reg = val >> 8;
3041         }
3042
3043         if(ctlr->mac_ver >= 0x3071){
3044                 /* read vendor RF settings */
3045                 for(i = 0; i < 10; i++){
3046                         val = rom_read(ctlr, Rt3071EepromRfBase + i);
3047                         ctlr->rf[i].val = val & 0xff;
3048                         ctlr->rf[i].reg = val >> 8;
3049                 }
3050         }
3051
3052         /* read RF frequency offset from EEPROM */
3053         val = rom_read(ctlr, EepromFreqLeds);
3054         ctlr->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0;
3055         if((val >> 8) != 0xff){
3056                 /* read LEDs operating mode */
3057                 ctlr->leds = val >> 8;
3058                 ctlr->led[0] = rom_read(ctlr, EepromLed1);
3059                 ctlr->led[1] = rom_read(ctlr, EepromLed2);
3060                 ctlr->led[2] = rom_read(ctlr, EepromLed3);
3061         }else{
3062                 /* broken EEPROM, use default settings */
3063                 ctlr->leds = 0x01;
3064                 ctlr->led[0] = 0x5555;
3065                 ctlr->led[1] = 0x2221;
3066                 ctlr->led[2] = 0xa9f8;
3067         }
3068         /* read RF information */
3069         val = rom_read(ctlr, EepromAntenna);
3070         if(val == 0xffff){
3071                 if(ctlr->mac_ver == 0x3593){
3072                         /* default to RF3053 3T3R */
3073                         ctlr->rf_rev = Rf3053;
3074                         ctlr->ntxchains = 3;
3075                         ctlr->nrxchains = 3;
3076                 }else if(ctlr->mac_ver >= 0x3071){
3077                         /* default to RF3020 1T1R */
3078                         ctlr->rf_rev = Rf3020;
3079                         ctlr->ntxchains = 1;
3080                         ctlr->nrxchains = 1;
3081                 }else{
3082                         /* default to RF2820 1T2R */
3083                         ctlr->rf_rev = Rf2820;
3084                         ctlr->ntxchains = 1;
3085                         ctlr->nrxchains = 2;
3086                 }
3087         }else{
3088                 ctlr->rf_rev = (val >> 8) & 0xf;
3089                 ctlr->ntxchains = (val >> 4) & 0xf;
3090                 ctlr->nrxchains = val & 0xf;
3091         }
3092
3093         /* check if RF supports automatic Tx access gain control */
3094         val = rom_read(ctlr, EepromConfig);
3095         /* check if driver should patch the DAC issue */
3096         if((val >> 8) != 0xff)
3097                 ctlr->patch_dac = (val >> 15) & 1;
3098         if((val & 0xff) != 0xff){
3099                 ctlr->ext_5ghz_lna = (val >> 3) & 1;
3100                 ctlr->ext_2ghz_lna = (val >> 2) & 1;
3101                 /* check if RF supports automatic Tx access gain control */
3102                 ctlr->calib_2ghz = ctlr->calib_5ghz = 0; /* XXX (val >> 1) & 1 */;
3103                 /* check if we have a hardware radio switch */
3104                 ctlr->rfswitch = val & 1;
3105         }
3106         if(ctlr->flags & AdvancedPs){
3107                 /* read PCIe power save level */
3108                 val = rom_read(ctlr, EepromPciePslevel);
3109                 if((val & 0xff) != 0xff){
3110                         ctlr->pslevel = val & 0x3;
3111                         val = rom_read(ctlr, EepromRev);
3112                         if((val & 0xff80) != 0x9280)
3113                                 ctlr->pslevel = MIN(ctlr->pslevel, 1);
3114                 }
3115         }
3116
3117         /* read power settings for 2GHz channels */
3118         for(i = 0; i < 14; i += 2){
3119                 val = rom_read(ctlr,
3120                     EepromPwr2ghzBase1 + i / 2);
3121                 ctlr->txpow1[i + 0] = (s8int)(val & 0xff);
3122                 ctlr->txpow1[i + 1] = (s8int)(val >> 8);
3123
3124                 val = rom_read(ctlr,
3125                     EepromPwr2ghzBase2 + i / 2);
3126                 ctlr->txpow2[i + 0] = (s8int)(val & 0xff);
3127                 ctlr->txpow2[i + 1] = (s8int)(val >> 8);
3128         }
3129         /* fix broken Tx power entries */
3130
3131         for(i = 0; i < 14; i++){
3132                 if(ctlr->txpow1[i] < 0 || ctlr->txpow1[i] > 31)
3133                         ctlr->txpow1[i] = 5;
3134                 if(ctlr->txpow2[i] < 0 || ctlr->txpow2[i] > 31)
3135                         ctlr->txpow2[i] = 5;
3136         }
3137         /* read power settings for 5GHz channels */
3138         for(i = 0; i < 40; i += 2){
3139                 val = rom_read(ctlr,
3140                     EepromPwr5ghzBase1 + i / 2);
3141                 ctlr->txpow1[i + 14] = (s8int)(val & 0xff);
3142                 ctlr->txpow1[i + 15] = (s8int)(val >> 8);
3143
3144                 val = rom_read(ctlr,
3145                     EepromPwr5ghzBase2 + i / 2);
3146                 ctlr->txpow2[i + 14] = (s8int)(val & 0xff);
3147                 ctlr->txpow2[i + 15] = (s8int)(val >> 8);
3148         }
3149
3150         /* fix broken Tx power entries */
3151         for(i = 0; i < 40; i++){
3152                 if(ctlr->txpow1[14 + i] < -7 || ctlr->txpow1[14 + i] > 15)
3153                         ctlr->txpow1[14 + i] = 5;
3154                 if(ctlr->txpow2[14 + i] < -7 || ctlr->txpow2[14 + i] > 15)
3155                         ctlr->txpow2[14 + i] = 5;
3156         }
3157
3158         /* read Tx power compensation for each Tx rate */
3159         val = rom_read(ctlr, EepromDeltapwr);
3160         delta_2ghz = delta_5ghz = 0;
3161         if((val & 0xff) != 0xff && (val & 0x80)){
3162                 delta_2ghz = val & 0xf;
3163                 if(!(val & 0x40))       /* negative number */
3164                         delta_2ghz = -delta_2ghz;
3165         }
3166         val >>= 8;
3167         if((val & 0xff) != 0xff && (val & 0x80)){
3168                 delta_5ghz = val & 0xf;
3169                 if(!(val & 0x40))       /* negative number */
3170                         delta_5ghz = -delta_5ghz;
3171         }
3172
3173         for(ridx = 0; ridx < 5; ridx++){
3174                 u32int reg;
3175
3176                 val = rom_read(ctlr, EepromRpwr + ridx * 2);
3177                 reg = val;
3178                 val = rom_read(ctlr, EepromRpwr + ridx * 2 + 1);
3179                 reg |= (u32int)val << 16;
3180
3181                 ctlr->txpow20mhz[ridx] = reg;
3182                 ctlr->txpow40mhz_2ghz[ridx] = b4inc(reg, delta_2ghz);
3183                 ctlr->txpow40mhz_5ghz[ridx] = b4inc(reg, delta_5ghz);
3184         }
3185
3186         /* read factory-calibrated samples for temperature compensation */
3187         val = rom_read(ctlr, EepromTssi12ghz);
3188         ctlr->tssi_2ghz[0] = val & 0xff;        /* [-4] */
3189         ctlr->tssi_2ghz[1] = val >> 8;  /* [-3] */
3190         val = rom_read(ctlr, EepromTssi22ghz);
3191         ctlr->tssi_2ghz[2] = val & 0xff;        /* [-2] */
3192         ctlr->tssi_2ghz[3] = val >> 8;  /* [-1] */
3193         val = rom_read(ctlr, EepromTssi32ghz);
3194         ctlr->tssi_2ghz[4] = val & 0xff;        /* [+0] */
3195         ctlr->tssi_2ghz[5] = val >> 8;  /* [+1] */
3196         val = rom_read(ctlr, EepromTssi42ghz);
3197         ctlr->tssi_2ghz[6] = val & 0xff;        /* [+2] */
3198         ctlr->tssi_2ghz[7] = val >> 8;  /* [+3] */
3199         val = rom_read(ctlr, EepromTssi52ghz);
3200         ctlr->tssi_2ghz[8] = val & 0xff;        /* [+4] */
3201         ctlr->step_2ghz = val >> 8;
3202         /* check that ref value is correct, otherwise disable calibration */
3203         if(ctlr->tssi_2ghz[4] == 0xff)
3204                 ctlr->calib_2ghz = 0;
3205
3206         val = rom_read(ctlr, EepromTssi15ghz);
3207         ctlr->tssi_5ghz[0] = val & 0xff;        /* [-4] */
3208         ctlr->tssi_5ghz[1] = val >> 8;  /* [-3] */
3209         val = rom_read(ctlr, EepromTssi25ghz);
3210         ctlr->tssi_5ghz[2] = val & 0xff;        /* [-2] */
3211         ctlr->tssi_5ghz[3] = val >> 8;  /* [-1] */
3212         val = rom_read(ctlr, EepromTssi35ghz);
3213         ctlr->tssi_5ghz[4] = val & 0xff;        /* [+0] */
3214         ctlr->tssi_5ghz[5] = val >> 8;  /* [+1] */
3215         val = rom_read(ctlr, EepromTssi45ghz);
3216         ctlr->tssi_5ghz[6] = val & 0xff;        /* [+2] */
3217         ctlr->tssi_5ghz[7] = val >> 8;  /* [+3] */
3218         val = rom_read(ctlr, EepromTssi55ghz);
3219         ctlr->tssi_5ghz[8] = val & 0xff;        /* [+4] */
3220         ctlr->step_5ghz = val >> 8;
3221         /* check that ref value is correct, otherwise disable calibration */
3222         if(ctlr->tssi_5ghz[4] == 0xff)
3223                 ctlr->calib_5ghz = 0;
3224
3225         /* read RSSI offsets and LNA gains from EEPROM */
3226         val = rom_read(ctlr, EepromRssi12ghz);
3227         ctlr->rssi_2ghz[0] = val & 0xff;        /* Ant A */
3228         ctlr->rssi_2ghz[1] = val >> 8;  /* Ant B */
3229         val = rom_read(ctlr, EepromRssi22ghz);
3230         if(ctlr->mac_ver >= 0x3071){
3231                 /*
3232                  * On RT3090 chips (limited to 2 Rx chains), this ROM
3233                  * field contains the Tx mixer gain for the 2GHz band.
3234                  */
3235                 if((val & 0xff) != 0xff)
3236                         ctlr->txmixgain_2ghz = val & 0x7;
3237         }else
3238                 ctlr->rssi_2ghz[2] = val & 0xff;        /* Ant C */
3239         ctlr->lna[2] = val >> 8;                /* channel group 2 */
3240
3241         val = rom_read(ctlr, EepromRssi15ghz);
3242         ctlr->rssi_5ghz[0] = val & 0xff;        /* Ant A */
3243         ctlr->rssi_5ghz[1] = val >> 8;  /* Ant B */
3244         val = rom_read(ctlr, EepromRssi25ghz);
3245         ctlr->rssi_5ghz[2] = val & 0xff;        /* Ant C */
3246         ctlr->lna[3] = val >> 8;                /* channel group 3 */
3247
3248         val = rom_read(ctlr, EepromLna);
3249         if(ctlr->mac_ver >= 0x3071)
3250                 ctlr->lna[0] = DefLna;
3251         else                            /* channel group 0 */
3252                 ctlr->lna[0] = val & 0xff;
3253         ctlr->lna[1] = val >> 8;                /* channel group 1 */
3254
3255         /* fix broken 5GHz LNA entries */
3256         if(ctlr->lna[2] == 0 || ctlr->lna[2] == 0xff){
3257                 ctlr->lna[2] = ctlr->lna[1];
3258         }
3259         if(ctlr->lna[3] == 0 || ctlr->lna[3] == 0xff){
3260                 ctlr->lna[3] = ctlr->lna[1];
3261         }
3262
3263         /* fix broken RSSI offset entries */
3264         for(ant = 0; ant < 3; ant++){
3265                 if(ctlr->rssi_2ghz[ant] < -10 || ctlr->rssi_2ghz[ant] > 10){
3266                         ctlr->rssi_2ghz[ant] = 0;
3267                 }
3268                 if(ctlr->rssi_5ghz[ant] < -10 || ctlr->rssi_5ghz[ant] > 10){
3269                         ctlr->rssi_5ghz[ant] = 0;
3270                 }
3271         }
3272
3273         return 0;
3274 }
3275
3276 static const char *
3277 getrfname(u8int rev)
3278 {
3279         if((rev == 0) || (rev >= nelem(rfnames)))
3280                 return "unknown";
3281         if(rfnames[rev][0] == '\0')
3282                 return "unknown";
3283         return rfnames[rev];
3284 }
3285
3286 static int
3287 rbplant(Ctlr *ctlr, int i)
3288 {
3289         Block *b;
3290         uchar *p;
3291
3292         b = iallocb(Rbufsize + 256);
3293         if(b == nil)
3294                 return -1;
3295         b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, 256);
3296         memset(b->rp, 0, Rbufsize);
3297         ctlr->rx.b[i] = b;
3298         p = (uchar*)&ctlr->rx.p[i * 4]; /* sdp0 */
3299         memset(p, 0, Rdscsize);
3300         put32(p, PCIWADDR(b->rp)); 
3301         p = (uchar*)&ctlr->rx.p[i * 4 + 1]; /* sdl0 */
3302         p += 2; /* sdl1 */
3303         put16(p, Rbufsize);;
3304         
3305         return 0;
3306 }
3307
3308 static char*
3309 allocrx(Ctlr *ctlr, RXQ *rx)
3310 {
3311         int i;
3312
3313         if(rx->b == nil)
3314                 rx->b = malloc(sizeof(Block*) * Nrx);
3315         if(rx->p == nil) /* Rx descriptors */
3316                 rx->p = mallocalign(Nrx * Rdscsize, 16, 0, 0);
3317         if(rx->b == nil || rx->p == nil)
3318                 return "no memory for rx ring";
3319         memset(rx->p, 0, Nrx * Rdscsize);
3320         for(i=0; i<Nrx; i++){
3321                 if(rx->b[i] != nil){
3322                         freeb(rx->b[i]);
3323                         rx->b[i] = nil;
3324                 }
3325                 if(rbplant(ctlr, i) < 0)
3326                         return "no memory for rx descriptors";
3327         }
3328         rx->i = 0;
3329         return nil;
3330 }
3331
3332 static void 
3333 freerx(Ctlr *, RXQ *rx)
3334 {
3335         int i;
3336
3337         for(i = 0; i < Nrx; i++){
3338                 if(rx->b[i] != nil){
3339                         freeb(rx->b[i]);
3340                         rx->b[i] = nil;
3341                 }
3342         }
3343         free(rx->b);
3344         free(rx->p);
3345         rx->p = nil;
3346         rx->b = nil;
3347         rx->i = 0;
3348 }
3349
3350 static char*
3351 alloctx(Ctlr *, TXQ *tx)
3352 {
3353         if(tx->b == nil)
3354                 tx->b = malloc(sizeof(Block*) * Ntx);
3355         if(tx->d == nil) /* Tx descriptors */
3356                 tx->d = mallocalign(Ntx * Tdscsize, 16, 0, 0);
3357         if(tx->b == nil || tx->d == nil)
3358                 return "no memory for tx ring";
3359         memset(tx->d, 0, Ntx * Tdscsize);
3360         memset(tx->b, 0, Ntx * sizeof(Block*));
3361         tx->i = 0;
3362         return nil;
3363 }
3364
3365 static void
3366 freetx(Ctlr *, TXQ *tx)
3367 {
3368         free(tx->b);
3369         free(tx->d);
3370         tx->d = nil;
3371         tx->i = 0;
3372 }
3373
3374 static char*
3375 alloctxpool(Ctlr *ctlr)
3376 {
3377         Pool *pool;
3378
3379         pool = &ctlr->pool;
3380         if(pool->p == nil)
3381                 pool->p = mallocalign(Ntxpool * TxwiDmaSz, 4096, 0, 0);
3382         if(pool->p == nil)
3383                 return "no memory for pool";
3384         memset(pool->p, 0, Ntxpool * TxwiDmaSz);
3385         pool->i = 0;
3386         return 0;
3387 }
3388
3389 static char*
3390 initring(Ctlr *ctlr)
3391 {
3392         int qid;
3393         char *err;
3394
3395         /*
3396          * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings.
3397          */
3398         for(qid = 0; qid < 6; qid++){
3399                 if((err = alloctx(ctlr, &ctlr->tx[qid])) != nil)
3400                         goto fail1;
3401         }
3402         if((err = allocrx(ctlr, &ctlr->rx)) != nil)
3403                 goto fail1;
3404
3405         if((err = alloctxpool(ctlr)) != nil)
3406                 goto fail2;
3407         /* mgmt ring is broken on RT2860C, use EDCA AC VO ring instead */
3408
3409         ctlr->mgtqid = (ctlr->mac_ver == 0x2860 && ctlr->mac_rev == 0x0100) ?
3410             3 : 5;
3411
3412                 return nil;
3413 fail2:  freerx(ctlr, &ctlr->rx);
3414                 return err;
3415 fail1:  while(--qid >= 0)
3416                         freetx(ctlr, &ctlr->tx[qid]);
3417                 return err;
3418 }
3419
3420 static int
3421 rt2860init(Ether *edev)
3422 {
3423         Ctlr *ctlr;
3424         int ntries;
3425         char *err;
3426         u32int tmp;
3427
3428         SET(tmp);
3429         ctlr = edev->ctlr;
3430         /* wait for NIC to initialize */
3431         for(ntries = 0; ntries < 100; ntries++){
3432                 tmp = csr32r(ctlr, AsicVerId);
3433                 if(tmp != 0 && tmp != 0xffffffff)
3434                         break;
3435                 microdelay(10);
3436         }
3437         if(ntries == 100){
3438                 print("timeout waiting for NIC to initialize");
3439                 return -1;
3440         }
3441         ctlr->mac_ver = tmp >> 16;
3442         ctlr->mac_rev = tmp & 0xffff;
3443
3444         if(ctlr->mac_ver != 0x2860){
3445                 switch(ctlr->pdev->did){
3446                         default:
3447                                         break;
3448                         case RalinkRT2890:
3449                         case RalinkRT2790:
3450                         case RalinkRT3090:
3451                         case AwtRT2890:
3452                                         ctlr->flags = AdvancedPs;
3453                                         break;
3454                 }
3455         }
3456         /* retrieve RF rev. no and various other things from EEPROM */
3457         eepromread(edev);
3458
3459         print("MAC/BBP RT%X (rev 0x%04X), RF %s (MIMO %dT%dR)\n",
3460             ctlr->mac_ver, ctlr->mac_rev,
3461             getrfname(ctlr->rf_rev), ctlr->ntxchains, ctlr->nrxchains);
3462         if((err = initring(ctlr)) != nil){
3463                 print("error: %s", err);
3464                 return -1;
3465         }
3466
3467         return 0;
3468 }
3469
3470 static Ctlr *rt2860head, *rt2860tail;
3471
3472 static void
3473 rt2860pci(void)
3474 {
3475         Pcidev *pdev;
3476         
3477         pdev = nil;
3478         while(pdev = pcimatch(pdev, 0, 0)){
3479                 Ctlr *ctlr;
3480                 void *mem;
3481                 
3482                 if(pdev->ccrb != 2 || pdev->ccru != 0x80)
3483                         continue;
3484                 if(pdev->vid != 0x1814) /* Ralink */
3485                         continue;
3486
3487                 switch(pdev->did){
3488                 default:
3489                         continue;
3490                 case RalinkRT2790:
3491                 case RalinkRT3090:
3492                         break;
3493                 }
3494
3495                 pcisetbme(pdev);
3496                 pcisetpms(pdev, 0);
3497
3498                 ctlr = malloc(sizeof(Ctlr));
3499                 if(ctlr == nil){
3500                         print("rt2860: unable to alloc Ctlr\n");
3501                         continue;
3502                 }
3503                 ctlr->port = pdev->mem[0].bar & ~0x0F;
3504                 mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
3505                 if(mem == nil){
3506                         print("rt2860: can't map %8.8luX\n", pdev->mem[0].bar);
3507                         free(ctlr);
3508                         continue;
3509                 }
3510                 ctlr->nic = mem;
3511                 ctlr->pdev = pdev;
3512
3513                 if(rt2860head != nil)
3514                         rt2860tail->link = ctlr;
3515                 else
3516                         rt2860head = ctlr;
3517                 rt2860tail = ctlr;
3518         }
3519 }
3520
3521 static int
3522 rt2860pnp(Ether* edev)
3523 {
3524         Ctlr *ctlr;
3525         
3526         if(rt2860head == nil)
3527                 rt2860pci();
3528 again:
3529         for(ctlr = rt2860head; ctlr != nil; ctlr = ctlr->link){
3530                 if(ctlr->active)
3531                         continue;
3532                 if(edev->port == 0 || edev->port == ctlr->port){
3533                         ctlr->active = 1;
3534                         break;
3535                 }
3536         }
3537
3538         if(ctlr == nil)
3539                 return -1;
3540
3541         edev->ctlr = ctlr;
3542         edev->port = ctlr->port;
3543         edev->irq = ctlr->pdev->intl;
3544         edev->tbdf = ctlr->pdev->tbdf;
3545         edev->arg = edev;
3546         edev->attach = rt2860attach;
3547         edev->ifstat = rt2860ifstat;
3548         edev->ctl = rt2860ctl;
3549         edev->promiscuous = rt2860promiscuous;
3550         edev->multicast = rt2860multicast;
3551         edev->mbps = 10;
3552
3553         if(rt2860init(edev) < 0){
3554                 edev->ctlr = nil;
3555                 goto again;
3556         }
3557
3558         intrenable(edev->irq, rt2860interrupt, edev, edev->tbdf, edev->name);
3559
3560         return 0;
3561 }
3562
3563 void
3564 etherrt2860link(void)
3565 {
3566         addethercard("rt2860", rt2860pnp);
3567 }