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