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.
10 #include "../port/lib.h"
15 #include "../port/error.h"
16 #include "../port/netif.h"
17 #include "../port/etherif.h"
18 #include "../port/wifi.h"
23 PciCfgUsb = (1 << 17),
24 PciCfgPci = (1 << 16),
36 Rt3090AuxCtrl = 0x010c,
42 /* SCH/DMA registers */
44 /* flags for registers IntStatus/IntMask */
45 TxCoherent = (1 << 17),
46 RxCoherent = (1 << 16),
52 TxRxCoherent = (1 << 10),
54 TxDoneInt5 = (1 << 8),
55 TxDoneInt4 = (1 << 7),
56 TxDoneInt3 = (1 << 6),
57 TxDoneInt2 = (1 << 5),
58 TxDoneInt1 = (1 << 4),
59 TxDoneInt0 = (1 << 3),
79 TxdlyIntEn = (1 << 31),
82 RxdlyIntEn = (1 << 15),
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)
102 UsbDmaCfg = 0x02a0 /* RT2870 only */,
103 UsbTxBusy = (1 << 31),
104 UsbRxBusy = (1 << 30),
105 UsbEpoutVldShift = 24,
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 */
125 HstPmSel = (1 << 16),
128 Clkselect = (1 << 12),
129 PbfClkEn = (1 << 11),
130 MacClkEn = (1 << 10),
142 LedRadio = (1 << 13),
143 LedLink2ghz = (1 << 14),
144 LedLink5ghz = (1 << 15),
145 McuCmdLedRssi = 0x51,
149 McuCmdRfreset = 0x72,
152 McuCmdPslevel = 0x83,
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),
170 #define WriteTxq(qid) (1 << (11 - (qid)))
171 Null0Kick = (1 << 7),
172 Null1Kick = (1 << 6),
174 #define ReadTxq(qid) = (1 << (3 - (qid))
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),
199 #define TxqIo(qid) (0x041c + (qid) * 4)
205 Rx0qPcntMask = 0xff000000,
206 Tx2qPcntMask = 0x00ff0000,
207 Tx1qPcntMask = 0x0000ff00,
208 Tx0qPcntMask = 0x000000ff,
211 CapAdcFeq = (1 << 31),
212 CapStart = (1 << 30),
214 TrigOffsetShift = 16,
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,
244 WlanHaltEn = (1 << 6),
245 PbfLoopEn = (1 << 5),
246 ContTxTest = (1 << 4),
253 MacBssidDw0 = 0x1010,
254 MacBssidDw1 = 0x1014,
255 MultiBcnNumShift = 18,
256 MultiBssidModeShift = 16,
258 MinMpduLenShift = 16,
259 MaxPsduLenShift = 12,
266 BbpRwParallel = (1 << 19),
267 BbpParDur1125 = (1 << 18),
268 BbpCsrKick = (1 << 17),
269 BbpCsrRead = (1 << 16),
273 RfRegCtrl = (1 << 31),
274 RfLeSel1 = (1 << 30),
275 RfLeStby = (1 << 29),
276 RfRegWidthShift = 24,
289 LedModeSlowBlink = 2,
291 SlowBlkTimeShift = 16,
297 /* undocumented registers */
302 /* MAC Timing control registers */
303 XifsTimeCfg = 0x1100,
304 BbRxendEn = (1 << 29),
306 OfdmXifsTimeShift = 16,
307 OfdmSifsTimeShift = 8,
308 CckSifsTimeShift = 0,
309 BkoffSlotCfg = 0x1104,
310 CcDelayTimeShift = 8,
315 NavClrEn = (1 << 15),
318 EifsAsChBusy = (1 << 4),
319 NavAsChBusy = (1 << 3),
320 RxAsChBusy = (1 << 2),
321 TxAsChBusy = (1 << 1),
322 ChStaTimerEn = (1 << 0),
323 PbfLifeTimer = 0x1110,
325 TsfInsCompShift = 24,
327 TbttTimerEn = (1 << 19),
328 TsfSyncModeShift = 17,
332 TsfSyncModeHostap = 3,
333 TsfTimerEn = (1 << 16),
335 TbttSyncCfg = 0x1118,
340 TsfTimerDw0 = 0x111c,
341 TsfTimerDw1 = 0x1120,
343 IntTimerCfg = 0x1128,
345 PreTbttTimerShift = 0,
347 GpTimerEn = (1 << 1),
348 PreTbttIntEn = (1 << 0),
353 /* MAC Power Save configuration registers */
354 MacStatusReg = 0x1200,
355 RxStatusBusy = (1 << 1),
356 TxStatusBusy = (1 << 0),
362 AutoWakeupCfg = 0x1208,
363 AutoWakeupEn = (1 << 15),
364 SleepTbttNumShift = 8,
365 WakeupLeadTimeShift = 0,
369 /* MAC TX configuration registers */
370 #define EdcaAcCfg(aci) (0x1300 + (aci) * 4)
371 EdcaTidAcMap = 0x1310,
372 #define TxPwrCfg(ridx) (0x1314 + (ridx) * 4)
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),
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),
406 Tx5gBandSelN = (1 << 2),
407 Tx5gBandSelP = (1 << 1),
408 TxBandSel = (1 << 0),
415 DlyRftrDisShift = 16,
423 TxopThresCfg = 0x133c,
424 TxopRemThresShift = 24,
425 CfEndThresShift = 16,
428 TxopCtrlCfg = 0x1340,
432 LsigTxopEn = (1 << 6),
433 TxopTrunEnMimops = (1 << 4),
434 TxopTrunEnTxop = (1 << 3),
435 TxopTrunEnRate = (1 << 2),
436 TxopTrunEnAc = (1 << 1),
437 TxopTrunEnTimeout = (1 << 0),
439 RtsFbkEn = (1 << 24),
441 RtsRtyLimitShift = 0,
442 TxTimeoutCfg = 0x1348,
443 TxopTimeoutShift = 16,
444 RxAckTimeoutShift = 8,
445 MpduLifeTimeShift = 4,
447 TxAutofbEn = (1 << 30),
448 AggRtyModeTimer = (1 << 29),
449 NagRtyModeTimer = (1 << 28),
450 LongRtyThresShift = 16,
451 LongRtyLimitShift = 8,
452 ShortRtyLimitShift = 0,
456 TxCfackEn = (1 << 12),
459 RemoteUmfsEn = (1 << 9),
461 RemoteMfbLtShift = 0,
467 /* possible flags for registers *ProtCfg */
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,
486 /* possible flags for registers EXP_{CTS,ACK}_TIME */
487 ExpOfdmTimeShift = 16,
493 /* MAC RX configuration registers */
495 DropCtrlRsv = (1 << 16),
498 DropPspoll = (1 << 13),
502 DropCfend = (1 << 9),
503 DropCfack = (1 << 8),
507 DropVerErr = (1 << 4),
508 DropNotMybss = (1 << 3),
509 DropUcNome = (1 << 2),
510 DropPhyErr = (1 << 1),
511 DropCrcErr = (1 << 0),
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,
523 SifsCostCfg = 0x1414,
524 OfdmSifsCostShift = 8,
525 CckSifsCostShift = 0,
526 RxParserCfg = 0x1418,
530 /* MAC Security configuration registers */
537 /* MAC HCCA/PSMP configuration registers */
538 TxopHldrAddr0 = 0x1600,
539 TxopHldrAddr1 = 0x1604,
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,
553 /* MAC Statistics Counters */
563 TxqAckreq = (1 << 7),
570 /* RX WCID search table */
571 #define WcidEntry(wcid) (0x1800 + (wcid) * 8)
575 Rt2870FwBase = 0x3000,
578 /* Pair-wise key table */
579 #define Pkey(wcid) (0x4000 + (wcid) * 32)
582 #define Iveiv(wcid) (0x6000 + (wcid) * 8)
584 /* WCID attribute table */
585 #define WcidAttr(wcid) (0x6800 + (wcid) * 4)
587 /* possible flags for register WCID_ATTR */
600 /* Shared Key Table */
601 #define Skey(vap, kidx) (0x6c00 + (vap) * 128 + (kidx) * 32)
603 /* Shared Key Mode */
606 SkeyMode815 = 0x7004,
607 SkeyMode1623 = 0x7008,
608 SkeyMode2431 = 0x700c,
612 /* Shared Memory between MCU and host */
616 H2mMailboxCid = 0x7014,
617 H2mMailboxStatus = 0x701c,
618 H2mBbpagent = 0x7028,
619 #define BcnBase(vap) (0x7800 + (vap) * 512)
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
636 TxLs1 = (1 << 14) /* SDP1 is the last segment */,
639 TxLs0 = (1 << 14) /* SDP0 is the last segment */,
642 TxQselMgmt = (0 << 1),
643 TxQselHcca = (1 << 1),
644 TxQselEdca = (2 << 1),
649 * TX Wireless Information
650 * -----------------------
655 * u8int wcid Wireless Client ID
663 TxMpduDsityShift = 5,
685 TxBawinsizeShift = 2,
693 * RT2860 RX descriptor
694 * --------------------
713 RxMicerr = (1 << 10),
727 * RX Wireless Information
728 * -----------------------
749 WIFIHDRSIZE = 2+2+3*6+2,
756 /* first DMA segment contains TXWI + 802.11 header + 32-bit padding */
757 TxwiDmaSz = Txwisize + WIFIHDRSIZE + 2
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 */,
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),
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,
806 Rt3593RxCtb = (1 << 5)
809 static const char* rfnames[] = {
824 /* USB commands, RT2870 only */
827 Rt2870WriteRegion1 = 6,
828 Rt2870ReadRegion1 = 7,
829 Rt2870EepromRead = 9,
833 EepromDelay = 1 /* minimum hold time (microsecond) */,
835 EepromVersion = 0x01,
839 EepromPciePslevel = 0x11,
841 EepromAntenna = 0x1a,
843 EepromCountry = 0x1c,
844 EepromFreqLeds = 0x1d,
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,
869 EepromBbpBase = 0x78,
870 Rt3071EepromRfBase = 0x82,
880 /* ring and pool count */
887 typedef struct FWImage FWImage;
888 typedef struct TXQ TXQ;
889 typedef struct RXQ RXQ;
890 typedef struct Pool Pool;
892 typedef struct Ctlr Ctlr;
902 uint i; /* current */
904 u32int *d; /* descriptors */
919 uint i; /* current */
951 u8int txmixgain_2ghz;
952 u8int txmixgain_5ghz;
965 u32int txpow20mhz[5];
966 u32int txpow40mhz_2ghz[5];
967 u32int txpow40mhz_5ghz[5];
979 /* assigned node ids in hardware node table or -1 if unassigned */
983 /* current receiver settings */
984 uchar bssid[Eaddrlen];
996 /* controller flags */
1002 static const struct rt2860_rate {
1005 /*enum ieee80211_phytype phy;*/
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 }
1025 * Default values for MAC registers; values taken from the reference driver.
1027 static const struct {
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 },
1062 * Default values for BBP registers; values taken from the reference driver.
1064 static const struct {
1067 } rt2860_def_bbp[] = {
1086 * Default settings for RF registers; values derived from the reference driver.
1088 static const struct rfprog {
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 },
1151 } rt3090_freqs[] = {
1207 static const struct {
1210 } rt3090_def_rf[] = {
1239 RalinkRT2890 = 0x0681,
1240 RalinkRT2790 = 0x0781,
1241 RalinkRT3090 = 0x3090,
1245 #define csr32r(c, r) (*((c)->nic+((r)/4)))
1246 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
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);
1256 return *((u16int*)p);
1260 return *((u32int*)p);
1263 put32(uchar *p, uint v){
1267 put16(uchar *p, uint v){
1271 memwrite(Ctlr *ctlr, u32int off, uchar *data, uint size){
1272 memmove((uchar*)ctlr->nic + off, data, size);
1275 setregion(Ctlr *ctlr, u32int off, uint val, uint size){
1276 memset((uchar*)ctlr->nic + off, val, size);
1280 rt2860ctl(Ether *edev, void *buf, long n)
1286 return wifictl(ctlr->wifi, buf, n);
1291 rt2860ifstat(Ether *edev, void *buf, long n, ulong off)
1297 return wifistat(ctlr->wifi, buf, n, off);
1302 setoptions(Ether *edev)
1308 for(i = 0; i < edev->nopt; i++)
1309 wificfg(ctlr->wifi, edev->opt[i]);
1313 rxon(Ether *edev, Wnode *bss)
1323 ctlr->channel = bss->channel;
1324 memmove(ctlr->bssid, bss->bssid, Eaddrlen);
1325 ctlr->aid = bss->aid;
1327 if(ctlr->wifi->debug)
1328 print("new assoc!");
1329 ctlr->bssnodeid = -1;
1331 ctlr->bcastnodeid = -1;
1334 memmove(ctlr->bssid, edev->bcast, Eaddrlen);
1336 ctlr->bcastnodeid = -1;
1337 ctlr->bssnodeid = -1;
1340 setleds(ctlr, LedRadio | LedLink2ghz);
1342 setleds(ctlr, LedRadio);
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);
1349 if(ctlr->mac_ver >= 0x3071)
1350 rt3090setchan(ctlr, ctlr->channel);
1352 setchan(ctlr, ctlr->channel);
1353 selchangroup(ctlr, 0);
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 */
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 */
1377 tmp = csr32r(ctlr, BkoffSlotCfg);
1379 tmp |= (cap & (1<<10)) ? 9 : 20;
1380 csr32w(ctlr, BkoffSlotCfg, tmp);
1382 /* set TX preamble */
1383 tmp = csr32r(ctlr, AutoRspCfg);
1385 if(cap & (1<<5)) tmp |= CckShortEn;
1386 csr32w(ctlr, AutoRspCfg, tmp);
1388 /* set basic rates */
1389 csr32w(ctlr, LegacyBasicRate, 0x003); /* 11B */
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);
1397 if(ctlr->bcastnodeid == -1){
1398 ctlr->bcastnodeid = 0xff;
1399 memwrite(ctlr, WcidEntry(ctlr->bcastnodeid), edev->bcast, Eaddrlen);
1401 if(ctlr->bssnodeid == -1 && bss != nil && ctlr->aid != 0){
1402 ctlr->bssnodeid = 0;
1403 memwrite(ctlr, WcidEntry(ctlr->bssnodeid), ctlr->bssid, Eaddrlen);
1408 rt2860promiscuous(void *arg, int on)
1415 if(ctlr->attached == 0)
1419 rxon(edev, ctlr->wifi->bss);
1424 rt2860multicast(void *, uchar*, int)
1430 static char name[] = "ral-rt2860";
1431 uchar dirbuf[sizeof(Dir)+100], *data;
1441 snprint(buf, sizeof buf, "/boot/%s", name);
1442 c = namec(buf, Aopen, OREAD, 0);
1445 snprint(buf, sizeof buf, "/lib/firmware/%s", name);
1446 c = namec(buf, Aopen, OREAD, 0);
1452 n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf);
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);
1464 while(r < d.length){
1465 n = devtab[c->type]->read(c, data+r, d.length-r, (vlong)r);
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);
1488 csr32w(ctlr, SysCtrl, McuReset);
1490 csr32w(ctlr, H2mBbpagent, 0);
1491 csr32w(ctlr, H2mMailbox, 0);
1493 /* wait until microcontroller is ready */
1495 for(ntries = 0; ntries < 1000; ntries++){
1496 if(csr32r(ctlr, SysCtrl) & McuReady)
1501 return "timeout waiting for MCU to initialize";
1506 * Send a command to the 8051 microcontroller unit.
1509 mcucmd(Ctlr *ctlr, u8int cmd, u16int arg, int wait)
1516 for(ntries = 0; ntries < 100; ntries++){
1517 if(!(csr32r(ctlr, H2mMailbox) & H2mBusy))
1524 cid = wait ? cmd : TokenNoIntr;
1525 csr32w(ctlr, H2mMailbox, H2mBusy | cid << 16 | arg);
1527 csr32w(ctlr, HostCmd, cmd);
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)
1543 /* clear command and status */
1544 csr32w(ctlr, H2mMailboxStatus, 0xffffffff);
1545 csr32w(ctlr, H2mMailboxCid, 0xffffffff);
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;
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.
1564 bbpwrite(Ctlr *ctlr, u8int reg, u8int val)
1568 for(ntries = 0; ntries < 100; ntries++){
1569 if(!(csr32r(ctlr, H2mBbpagent) & BbpCsrKick))
1574 print("could not write to BBP through MCU\n");
1578 csr32w(ctlr, H2mBbpagent, BbpRwParallel |
1579 BbpCsrKick | reg << 8 | val);
1582 mcucmd(ctlr, McuCmdBbp, 0, 0);
1587 bbpread(Ctlr *ctlr, u8int reg)
1592 for(ntries = 0; ntries < 100; ntries++){
1593 if(!(csr32r(ctlr, H2mBbpagent) & BbpCsrKick))
1598 print("could not read from BBP through MCU");
1602 csr32w(ctlr, H2mBbpagent, BbpRwParallel |
1603 BbpCsrKick | BbpCsrRead | reg << 8);
1606 mcucmd(ctlr, McuCmdBbp, 0, 0);
1609 for(ntries = 0; ntries < 100; ntries++){
1610 val = csr32r(ctlr, H2mBbpagent);
1611 if(!(val & BbpCsrKick))
1615 print("could not read from BBP through MCU\n");
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)
1633 err = "timeout waiting for BBP to wake up";
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);
1643 /* fix BBP84 for RT2860E */
1644 if(ctlr->mac_ver == 0x2860 && ctlr->mac_rev != 0x0101)
1645 bbpwrite(ctlr, 84, 0x19);
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);
1661 setleds(Ctlr *ctlr, u16int which)
1663 mcucmd(ctlr, McuCmdLeds,
1664 which | (ctlr->leds & 0x7f), 0);
1675 /* enable Tx/Rx DMA engine */
1676 csr32w(ctlr, MacSysCtrl, MacTxEn);
1678 for(ntries = 0; ntries < 200; ntries++){
1679 tmp = csr32r(ctlr, WpdmaGloCfg);
1680 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
1685 err = "timeout waiting for DMA engine";
1691 tmp |= RxDmaEn | TxDmaEn |
1692 WpdmaBtSize64 << WpdmaBtSizeShift;
1693 csr32w(ctlr, WpdmaGloCfg, tmp);
1696 tmp = DropCrcErr | DropPhyErr;
1698 tmp |= DropUcNome | DropDupl |
1699 DropCts | DropBa | DropAck |
1700 DropVerErr | DropCtrlRsv |
1701 DropCfack | DropCfend;
1702 tmp |= DropRts | DropPspoll;
1704 csr32w(ctlr, RxFiltrCfg, tmp);
1706 csr32w(ctlr, MacSysCtrl, MacRxEn | MacTxEn);
1712 * Write to one of the 4 programmable 24-bit RF registers.
1715 rfwrite(Ctlr *ctlr, u8int reg, u32int val)
1720 for(ntries = 0; ntries < 100; ntries++){
1721 if(!(csr32r(ctlr, RfCsrCfg0) & RfRegCtrl))
1726 print("could not write to RF\n");
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);
1737 rt3090rfread(Ctlr *ctlr, u8int reg)
1742 for(ntries = 0; ntries < 100; ntries++){
1743 if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
1748 print("could not read RF register\n");
1751 tmp = Rt3070RfKick | reg << 8;
1752 csr32w(ctlr, Rt3070RfCsrCfg, tmp);
1754 for(ntries = 0; ntries < 100; ntries++){
1755 tmp = csr32r(ctlr, Rt3070RfCsrCfg);
1756 if(!(tmp & Rt3070RfKick))
1761 print("could not read RF register\n");
1768 rt3090rfwrite(Ctlr *ctlr, u8int reg, u8int val)
1773 for(ntries = 0; ntries < 10; ntries++){
1774 if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
1779 print("could not write to RF\n");
1783 tmp = Rt3070RfWrite | Rt3070RfKick | reg << 8 | val;
1784 csr32w(ctlr, Rt3070RfCsrCfg, tmp);
1788 selchangroup(Ctlr *ctlr, int group)
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);
1799 if(ctlr->ext_2ghz_lna){
1800 bbpwrite(ctlr, 82, 0x62);
1801 bbpwrite(ctlr, 75, 0x46);
1803 bbpwrite(ctlr, 82, 0x84);
1804 bbpwrite(ctlr, 75, 0x50);
1807 if(ctlr->ext_5ghz_lna){
1808 bbpwrite(ctlr, 82, 0xf2);
1809 bbpwrite(ctlr, 75, 0x46);
1811 bbpwrite(ctlr, 82, 0xf2);
1812 bbpwrite(ctlr, 75, 0x50);
1816 tmp = csr32r(ctlr, TxBandCfg);
1817 tmp &= ~(Tx5gBandSelN | Tx5gBandSelP);
1818 tmp |= (group == 0) ? Tx5gBandSelN : Tx5gBandSelP;
1819 csr32w(ctlr, TxBandCfg, tmp);
1821 /* enable appropriate Power Amplifiers and Low Noise Amplifiers */
1822 tmp = RftrEn | TrswEn | LnaPe0En;
1823 if(ctlr->nrxchains > 1)
1825 if(ctlr->mac_ver == 0x3593 && ctlr->nrxchains > 2)
1826 tmp |= Rt3593LnaPe2En;
1827 if(group == 0){ /* 2GHz */
1829 if(ctlr->ntxchains > 1)
1831 if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains > 2)
1832 tmp |= Rt3593PaPeG2En;
1835 if(ctlr->ntxchains > 1)
1837 if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains > 2)
1838 tmp |= Rt3593PaPeA2En;
1840 csr32w(ctlr, TxPinCfg, tmp);
1842 if(ctlr->mac_ver == 0x3593){
1843 tmp = csr32r(ctlr, GpioCtrl);
1844 if(ctlr->flags & ConnPciE){
1853 tmp = (tmp & ~0x00001000) | 0x00000010;
1854 csr32w(ctlr, GpioCtrl, tmp);
1857 /* set initial AGC value */
1858 if(group == 0){ /* 2GHz band */
1859 if(ctlr->mac_ver >= 0x3071)
1860 agc = 0x1c + ctlr->lna[0] * 2;
1862 agc = 0x2e + ctlr->lna[0];
1863 }else{ /* 5GHz band */
1864 agc = 0x32 + (ctlr->lna[group] * 5) / 3;
1866 bbpwrite(ctlr, 66, agc);
1873 setchan(Ctlr *ctlr, uint chan)
1875 const struct rfprog *rfprog = rt2860_rf2850;
1877 s8int txpow1, txpow2;
1880 /* find the settings for this channel (we know it exists) */
1881 for(i = 0; rfprog[i].chan != chan; i++);
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 */
1891 /* use Tx power values from EEPROM */
1892 txpow1 = ctlr->txpow1[i];
1893 txpow2 = ctlr->txpow2[i];
1896 txpow1 = txpow1 << 1 | 1;
1898 txpow1 = (7 + txpow1) << 1;
1900 txpow2 = txpow2 << 1 | 1;
1902 txpow2 = (7 + txpow2) << 1;
1904 r3 = rfprog[i].r3 | txpow1 << 7;
1905 r4 = rfprog[i].r4 | ctlr->freq << 13 | txpow2 << 4;
1907 rfwrite(ctlr, Rf1, rfprog[i].r1);
1908 rfwrite(ctlr, Rf2, r2);
1909 rfwrite(ctlr, Rf3, r3);
1910 rfwrite(ctlr, Rf4, r4);
1914 rfwrite(ctlr, Rf1, rfprog[i].r1);
1915 rfwrite(ctlr, Rf2, r2);
1916 rfwrite(ctlr, Rf3, r3 | 1);
1917 rfwrite(ctlr, Rf4, r4);
1921 rfwrite(ctlr, Rf1, rfprog[i].r1);
1922 rfwrite(ctlr, Rf2, r2);
1923 rfwrite(ctlr, Rf3, r3);
1924 rfwrite(ctlr, Rf4, r4);
1928 rt3090setchan(Ctlr *ctlr, uint chan)
1930 s8int txpow1, txpow2;
1934 assert(chan >= 1 && chan <= 14); /* RT3090 is 2GHz only */
1936 /* find the settings for this channel (we know it exists) */
1937 for(i = 0; rt2860_rf2850[i].chan != chan; i++);
1939 /* use Tx power values from EEPROM */
1940 txpow1 = ctlr->txpow1[i];
1941 txpow2 = ctlr->txpow2[i];
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);
1952 rf = rt3090rfread(ctlr, 12);
1953 rf = (rf & ~0x1f) | txpow1;
1954 rt3090rfwrite(ctlr, 12, rf);
1957 rf = rt3090rfread(ctlr, 13);
1958 rf = (rf & ~0x1f) | txpow2;
1959 rt3090rfwrite(ctlr, 13, rf);
1961 rf = rt3090rfread(ctlr, 1);
1963 if(ctlr->ntxchains == 1)
1964 rf |= Rt3070Tx1Pd | Rt3070Tx2Pd;
1965 else if(ctlr->ntxchains == 2)
1967 if(ctlr->nrxchains == 1)
1968 rf |= Rt3070Rx1Pd | Rt3070Rx2Pd;
1969 else if(ctlr->nrxchains == 2)
1971 rt3090rfwrite(ctlr, 1, rf);
1974 rf = rt3090rfread(ctlr, 23);
1975 rf = (rf & ~0x7f) | ctlr->freq;
1976 rt3090rfwrite(ctlr, 23, rf);
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);
1986 /* enable RF tuning */
1987 rf = rt3090rfread(ctlr, 7);
1988 rt3090rfwrite(ctlr, 7, rf | Rt3070Tune);
1992 rt3090filtercalib(Ctlr *ctlr, u8int init, u8int target, u8int *val)
1995 u8int bbp55_pb, bbp55_sb, delta;
1998 /* program filter */
1999 rf24 = rt3090rfread(ctlr, 24);
2000 rf24 = (rf24 & 0xc0) | init; /* initial filter value */
2001 rt3090rfwrite(ctlr, 24, rf24);
2003 /* enable baseband loopback mode */
2004 rf22 = rt3090rfread(ctlr, 22);
2005 rt3090rfwrite(ctlr, 22, rf22 | Rt3070BbLoopback);
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);
2013 /* read received power */
2014 bbp55_pb = bbpread(ctlr, 55);
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);
2027 /* read received power */
2028 bbp55_sb = bbpread(ctlr, 55);
2030 delta = bbp55_pb - bbp55_sb;
2034 /* reprogram filter */
2036 rt3090rfwrite(ctlr, 24, rf24);
2040 rf24--; /* backtrack */
2042 rt3090rfwrite(ctlr, 24, rf24);
2045 /* restore initial state */
2046 bbpwrite(ctlr, 24, 0x00);
2048 /* disable baseband loopback mode */
2049 rf22 = rt3090rfread(ctlr, 22);
2050 rt3090rfwrite(ctlr, 22, rf22 & ~Rt3070BbLoopback);
2056 rt3090setrxantenna(Ctlr *ctlr, int aux)
2061 tmp = csr32r(ctlr, PciEectrl);
2062 csr32w(ctlr, PciEectrl, tmp & ~EectrlC);
2063 tmp = csr32r(ctlr, GpioCtrl);
2064 csr32w(ctlr, GpioCtrl, (tmp & ~0x0808) | 0x08);
2066 tmp = csr32r(ctlr, PciEectrl);
2067 csr32w(ctlr, PciEectrl, tmp | EectrlC);
2068 tmp = csr32r(ctlr, GpioCtrl);
2069 csr32w(ctlr, GpioCtrl, tmp & ~0x0808);
2074 rt3090rfinit(Ctlr *ctlr)
2080 rf = rt3090rfread(ctlr, 30);
2081 /* toggle RF R30 bit 7 */
2082 rt3090rfwrite(ctlr, 30, rf | 0x80);
2084 rt3090rfwrite(ctlr, 30, rf & ~0x80);
2086 tmp = csr32r(ctlr, Rt3070LdoCfg0);
2088 if(ctlr->patch_dac && ctlr->mac_rev < 0x0211)
2089 tmp |= 0x0d000000; /* 1.35V */
2091 tmp |= 0x01000000; /* 1.2V */
2092 csr32w(ctlr, Rt3070LdoCfg0, tmp);
2094 /* patch LNA_PE_G1 */
2095 tmp = csr32r(ctlr, Rt3070GpioSwitch);
2096 csr32w(ctlr, Rt3070GpioSwitch, tmp & ~0x20);
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);
2104 /* select 20MHz bandwidth */
2105 rt3090rfwrite(ctlr, 31, 0x14);
2107 rf = rt3090rfread(ctlr, 6);
2108 rt3090rfwrite(ctlr, 6, rf | 0x40);
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);
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);
2121 /* calibrate filter for 40MHz bandwidth */
2122 ctlr->rf24_40mhz = 0x2f; /* default value */
2123 rt3090filtercalib(ctlr, 0x27, 0x19, &ctlr->rf24_40mhz);
2125 /* go back to 20MHz bandwidth */
2126 bbp = bbpread(ctlr, 4);
2127 bbpwrite(ctlr, 4, bbp & ~0x18);
2129 if(ctlr->mac_rev < 0x0211)
2130 rt3090rfwrite(ctlr, 27, 0x03);
2132 tmp = csr32r(ctlr, Rt3070Opt14);
2133 csr32w(ctlr, Rt3070Opt14, tmp | 1);
2135 if(ctlr->rf_rev == Rf3020)
2136 rt3090setrxantenna(ctlr, 0);
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 */
2149 if(ctlr->ntxchains == 1)
2150 bbp |= 0x20; /* turn off DAC1 */
2151 if(ctlr->nrxchains == 1)
2152 bbp &= ~0x02; /* turn off ADC1 */
2154 bbpwrite(ctlr, 138, bbp);
2156 rf = rt3090rfread(ctlr, 1);
2157 rf &= ~(Rt3070Rx0Pd | Rt3070Tx0Pd);
2158 rf |= Rt3070RfBlock | Rt3070Rx1Pd | Rt3070Tx1Pd;
2159 rt3090rfwrite(ctlr, 1, rf);
2161 rf = rt3090rfread(ctlr, 15);
2162 rt3090rfwrite(ctlr, 15, rf & ~Rt3070TxLo2);
2164 rf = rt3090rfread(ctlr, 17);
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);
2172 rf = rt3090rfread(ctlr, 20);
2173 rt3090rfwrite(ctlr, 20, rf & ~Rt3070RxLo1);
2175 rf = rt3090rfread(ctlr, 21);
2176 rt3090rfwrite(ctlr, 21, rf & ~Rt3070RxLo2);
2182 rt3090rfwakeup(Ctlr *ctlr)
2187 if(ctlr->mac_ver == 0x3593){
2189 rf = rt3090rfread(ctlr, 1);
2190 rt3090rfwrite(ctlr, 1, rf | Rt3593Vco);
2192 /* initiate VCO calibration */
2193 rf = rt3090rfread(ctlr, 3);
2194 rt3090rfwrite(ctlr, 3, rf | Rt3593Vcocal);
2196 /* enable VCO bias current control */
2197 rf = rt3090rfread(ctlr, 6);
2198 rt3090rfwrite(ctlr, 6, rf | Rt3593VcoIc);
2200 /* initiate res calibration */
2201 rf = rt3090rfread(ctlr, 2);
2202 rt3090rfwrite(ctlr, 2, rf | Rt3593Rescal);
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);
2211 rf = rt3090rfread(ctlr, 46);
2212 rt3090rfwrite(ctlr, 46, rf | Rt3593RxCtb);
2214 rf = rt3090rfread(ctlr, 20);
2215 rf &= ~(Rt3593LdoRfVcMask | Rt3593LdoPllVcMask);
2216 rt3090rfwrite(ctlr, 20, rf);
2218 /* enable RF block */
2219 rf = rt3090rfread(ctlr, 1);
2220 rt3090rfwrite(ctlr, 1, rf | Rt3070RfBlock);
2222 /* enable VCO bias current control */
2223 rf = rt3090rfread(ctlr, 7);
2224 rt3090rfwrite(ctlr, 7, rf | 0x30);
2226 rf = rt3090rfread(ctlr, 9);
2227 rt3090rfwrite(ctlr, 9, rf | 0x0e);
2230 rf = rt3090rfread(ctlr, 21);
2231 rt3090rfwrite(ctlr, 21, rf | Rt3070RxCtb);
2233 /* fix Tx to Rx IQ glitch by raising RF voltage */
2234 rf = rt3090rfread(ctlr, 27);
2236 if(ctlr->mac_rev < 0x0211)
2238 rt3090rfwrite(ctlr, 27, rf);
2240 if(ctlr->patch_dac && ctlr->mac_rev < 0x0211){
2241 tmp = csr32r(ctlr, Rt3070LdoCfg0);
2242 tmp = (tmp & ~0x1f000000) | 0x0d000000;
2243 csr32w(ctlr, Rt3070LdoCfg0, tmp);
2248 rt3090rfsetup(Ctlr *ctlr)
2253 if(ctlr->mac_rev >= 0x0211){
2254 /* enable DC filter */
2255 bbpwrite(ctlr, 103, 0xc0);
2257 /* improve power consumption */
2258 bbp = bbpread(ctlr, 31);
2259 bbpwrite(ctlr, 31, bbp & ~0x03);
2262 csr32w(ctlr, TxSwCfg1, 0);
2263 if(ctlr->mac_rev < 0x0211){
2264 csr32w(ctlr, TxSwCfg2,
2265 ctlr->patch_dac ? 0x2c : 0x0f);
2267 csr32w(ctlr, TxSwCfg2, 0);
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)
2273 rt3090rfwrite(ctlr, ctlr->rf[i].reg, ctlr->rf[i].val);
2278 updateprot(Ctlr *ctlr)
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;
2288 /* CCK frames don't require protection */
2289 csr32w(ctlr, CckProtCfg, tmp);
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)
2297 csr32w(ctlr, OfdmProtCfg, tmp); */
2301 rt2860start(Ether *edev)
2305 int i, qid, ridx, ntries;
2310 csr32w(ctlr, PwrPinCfg, IoRaPe);
2313 tmp = csr32r(ctlr, WpdmaGloCfg);
2315 csr32w(ctlr, WpdmaGloCfg, tmp);
2317 /* PBF hardware reset */
2318 csr32w(ctlr, SysCtrl, 0xe1f);
2320 csr32w(ctlr, SysCtrl, 0xe00);
2322 if((err = boot(ctlr)) != nil){
2323 /*XXX: rt2860stop(ifp, 1);*/
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);
2332 /* init Tx power for all Tx rates (from EEPROM) */
2333 for(ridx = 0; ridx < 5; ridx++){
2334 if(ctlr->txpow20mhz[ridx] == 0xffffffff)
2336 csr32w(ctlr, TxPwrCfg(ridx), ctlr->txpow20mhz[ridx]);
2339 for(ntries = 0; ntries < 100; ntries++){
2340 tmp = csr32r(ctlr, WpdmaGloCfg);
2341 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
2346 err = "timeout waiting for DMA engine";
2347 /*rt2860_stop(ifp, 1);*/
2351 csr32w(ctlr, WpdmaGloCfg, tmp);
2353 /* reset Rx ring and all 6 Tx rings */
2354 csr32w(ctlr, WpdmaRstIdx, 0x1003f);
2356 /* PBF hardware reset */
2357 csr32w(ctlr, SysCtrl, 0xe1f);
2359 csr32w(ctlr, SysCtrl, 0xe00);
2361 csr32w(ctlr, PwrPinCfg, IoRaPe | IoRfPe);
2363 csr32w(ctlr, MacSysCtrl, BbpHrst | MacSrst);
2365 csr32w(ctlr, MacSysCtrl, 0);
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);
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);
2383 /* wait while MAC is busy */
2384 for(ntries = 0; ntries < 100; ntries++){
2385 if(!(csr32r(ctlr, MacStatusReg) &
2386 (RxStatusBusy | TxStatusBusy)))
2391 err = "timeout waiting for MAC";
2392 /*rt2860_stop(ifp, 1);*/
2396 /* clear Host to MCU mailbox */
2397 csr32w(ctlr, H2mBbpagent, 0);
2398 csr32w(ctlr, H2mMailbox, 0);
2400 mcucmd(ctlr, McuCmdRfreset, 0, 0);
2403 if((err = bbpinit(ctlr)) != nil){
2404 /*rt2860_stop(ifp, 1);*/
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);
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);
2428 csr32w(ctlr, RxBasePtr, PCIWADDR(ctlr->rx.p));
2429 csr32w(ctlr, RxMaxCnt, Nrx);
2430 csr32w(ctlr, RxCalcIdx, Nrx - 1);
2432 /* setup maximum buffer sizes */
2433 csr32w(ctlr, MaxLenCfg, 1 << 12 |
2434 (Rbufsize - Rxwisize - 2));
2436 for(ntries = 0; ntries < 100; ntries++){
2437 tmp = csr32r(ctlr, WpdmaGloCfg);
2438 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
2443 err = "timeout waiting for DMA engine";
2444 /*rt2860_stop(ifp, 1);*/
2448 csr32w(ctlr, WpdmaGloCfg, tmp);
2450 /* disable interrupts mitigation */
2451 csr32w(ctlr, DelayIntCfg, 0);
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)
2457 bbpwrite(ctlr, ctlr->bbp[i].reg, ctlr->bbp[i].val);
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);
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);
2471 if(ctlr->mac_ver >= 0x3071)
2474 mcucmd(ctlr, McuCmdSleep, 0x02ff, 1);
2475 mcucmd(ctlr, McuCmdWakeup, 0, 1);
2477 if(ctlr->mac_ver >= 0x3071)
2478 rt3090rfwakeup(ctlr);
2480 /* disable non-existing Rx chains */
2481 bbp3 = bbpread(ctlr, 3);
2482 bbp3 &= ~(1 << 3 | 1 << 4);
2483 if(ctlr->nrxchains == 2)
2485 else if(ctlr->nrxchains == 3)
2487 bbpwrite(ctlr, 3, bbp3);
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);
2499 if(ctlr->mac_ver >= 0x3071)
2500 rt3090rfsetup(ctlr);
2502 /* select default channel */
2503 if(ctlr->mac_ver >= 0x3071)
2504 rt3090setchan(ctlr, 3);
2508 /* reset RF from MCU */
2509 mcucmd(ctlr, McuCmdRfreset, 0, 0);
2511 /* set RTS threshold */
2512 tmp = csr32r(ctlr, TxRtsCfg);
2514 tmp |= 1 /* ic->ic_rtsthreshold */ << 8;
2515 csr32w(ctlr, TxRtsCfg, tmp);
2517 /* setup initial protection mode */
2520 /* turn radio LED on */
2521 setleds(ctlr, LedRadio);
2523 /* enable Tx/Rx DMA engine */
2524 if((err = txrxon(ctlr)) != 0){
2525 /*rt2860_stop(ifp, 1);*/
2529 /* clear pending interrupts */
2530 csr32w(ctlr, IntStatus, 0xffffffff);
2531 /* enable interrupts */
2532 csr32w(ctlr, IntMask, 0x3fffc);
2534 if(ctlr->flags & AdvancedPs)
2535 mcucmd(ctlr, McuCmdPslevel, ctlr->pslevel, 0);
2540 * Add `delta' (signed) to each 4-bit sub-word of a 32-bit word.
2541 * Used to adjust per-rate Tx power registers.
2544 b4inc(u32int b32, s8int delta)
2548 for(i = 0; i < 8; i++){
2555 b32 = b32 >> 4 | b4 << 28;
2561 transmit(Wifi *wifi, Wnode *wn, Block *b)
2567 int ridx, /*ctl_ridx,*/ hdrlen;
2578 if(ctlr->attached == 0 || ctlr->broken){
2583 if((wn->channel != ctlr->channel)
2584 || (!ctlr->prom && (wn->aid != ctlr->aid || memcmp(wn->bssid, ctlr->bssid, Eaddrlen) != 0)))
2588 /* association note has no data to transmit */
2594 qid = 0; /* for now */
2596 tx = &ctlr->tx[qid];
2598 nodeid = ctlr->bcastnodeid;
2599 w = (Wifipkt*)b->rp;
2600 hdrlen = wifihdrlen(w);
2602 p = pool->p + pool->i * TxwiDmaSz;
2603 if((w->a1[0] & 1) == 0){
2604 *(p+4) = TxAck; /* xflags */
2607 *(p+1) = TxTxopBackoff; /* txop */
2609 if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
2610 nodeid = ctlr->bssnodeid;
2611 ridx = 2; /* BUG: hardcode 11Mbit */
2615 /*ctl_ridx = rt2860_rates[ridx].ctl_ridx;*/
2616 mcs = rt2860_rates[ridx].mcs;
2618 /* setup TX Wireless Information */
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 */
2625 /* put16((uchar*)&w->dur[0], rt2860_rates[ctl_ridx].lp_ack_dur); */
2627 *(p+5) = nodeid; /* wcid */
2629 /* copy packet header */
2630 memmove(p + Txwisize, b->rp, hdrlen);
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 */
2639 /* allocate output buffer */
2641 tx->b[tx->i] = outb = iallocb(BLEN(b) + 256);
2643 print("outb = nil\n");
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);
2652 /* setup payload segments */
2653 put32(p + 8, PCIWADDR(outb->rp)); /* sdp1 */
2654 put16(p + 4, BLEN(outb) | TxLs1); /* sdl1 */
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));
2662 tx->i = (tx->i + 1) % Ntx;
2663 pool->i = (pool->i + 1) % Ntxpool;
2668 csr32w(ctlr, TxCtxIdx(qid), ctlr->tx[qid].i);
2675 rt2860attach(Ether *edev)
2684 print("#l%d: %s\n", edev->ctlrno, up->errstr);
2690 if(ctlr->attached == 0){
2691 if(ctlr->wifi == nil)
2692 ctlr->wifi = wifiattach(edev, transmit);
2694 if(ctlr->fw == nil){
2695 fw = readfirmware();
2698 if((err = rt2860start(edev)) != nil){
2702 ctlr->bcastnodeid = -1;
2703 ctlr->bssnodeid = -1;
2725 print("rx->b == nil!");
2728 hw = csr32r(ctlr, FsDrxIdx) & 0xfff;
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 */
2742 flags = get32(p + 12);
2743 if(flags & (RxCrcerr | RxIcverr)){
2744 /* print("crc | icv err\n"); */
2754 if(ctlr->wifi == nil)
2756 if(rbplant(ctlr, rx->i) < 0){
2757 print("can't plant");
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);
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);
2776 put16(p + 4 /* sdp0 */ + 2 /* sdl1 */, sdl0 & ~RxDdone);
2777 rx->i = (rx->i + 1) % Nrx;
2780 /* tell HW what we have processed */
2781 csr32w(ctlr, RxCalcIdx, (rx->i - 1) % Nrx);
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){
2800 rt2860tx(Ctlr *ctlr, u8int q)
2807 hw = csr32r(ctlr, TxDtxIdx(q));
2809 uchar *p = (uchar*)tx->d + Rdscsize * tx->n;
2813 freeb(tx->b[tx->n]);
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 */
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;
2830 rt2860interrupt(Ureg*, void *arg)
2841 debug = ctlr->wifi->debug;
2843 r = csr32r(ctlr, IntStatus);
2844 if(r == 0xffffffff){
2853 /* acknowledge interrupts */
2854 csr32w(ctlr, IntStatus, r);
2856 if(r & TxRxCoherent){
2858 /* DMA finds data coherent event when checking the DDONE bit */
2860 print("txrx coherent intr\n");
2862 /* restart DMA engine */
2863 tmp = csr32r(ctlr, WpdmaGloCfg);
2864 tmp &= ~(TxWbDdone | RxDmaEn | TxDmaEn);
2865 csr32w(ctlr, WpdmaGloCfg, tmp);
2897 eepromctl(Ctlr *ctlr, u32int val)
2899 csr32w(ctlr, PciEectrl, val);
2901 microdelay(EepromDelay);
2905 * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46,
2909 eeread2(Ctlr *ctlr, u16int addr)
2915 /* clock C once before the first command */
2918 eepromctl(ctlr, EectrlS);
2919 eepromctl(ctlr, EectrlS | EectrlC);
2920 eepromctl(ctlr, EectrlS);
2922 /* write start bit (1) */
2923 eepromctl(ctlr, EectrlS | EectrlD);
2924 eepromctl(ctlr, EectrlS | EectrlD | EectrlC);
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);
2932 /* write address (A5-A0 or A7-A0) */
2933 n = ((csr32r(ctlr, PciEectrl) & 0x30) == 0) ? 5 : 7;
2935 eepromctl(ctlr, EectrlS |
2936 (((addr >> n) & 1) << EectrlShiftD));
2937 eepromctl(ctlr, EectrlS |
2938 (((addr >> n) & 1) << EectrlShiftD) | EectrlC);
2941 eepromctl(ctlr, EectrlS);
2943 /* read data Q15-Q0 */
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);
2954 /* clear Chip Select and clock C */
2955 eepromctl(ctlr, EectrlS);
2957 eepromctl(ctlr, EectrlC);
2962 /* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
2964 efuseread2(Ctlr *ctlr, u16int addr)
2972 * Read one 16-byte block into registers EFUSE_DATA[0-3]:
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))
2991 if((tmp & Rt3070EfuseAoutMask) == Rt3070EfuseAoutMask)
2992 return 0xffff; /* address not found */
2994 /* determine to which 32-bit register our 16-bit word belongs */
2995 reg = Rt3070EfuseData3 - (addr & 0xc);
2996 tmp = csr32r(ctlr, reg);
2998 return (addr & 2) ? tmp >> 16 : tmp & 0xffff;
3002 eepromread(Ether *edev)
3004 s8int delta_2ghz, delta_5ghz;
3008 u16int (*rom_read)(Ctlr*, u16int);
3011 enum { DefLna = 10 };
3014 /* check whether the ROM is eFUSE ROM or EEPROM */
3016 if(ctlr->mac_ver >= 0x3071){
3017 tmp = csr32r(ctlr, Rt3070EfuseCtrl);
3018 if(tmp & Rt3070SelEfuse)
3019 rom_read = efuseread2;
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;
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;
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;
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);
3059 /* broken EEPROM, use default settings */
3061 ctlr->led[0] = 0x5555;
3062 ctlr->led[1] = 0x2221;
3063 ctlr->led[2] = 0xa9f8;
3065 /* read RF information */
3066 val = rom_read(ctlr, EepromAntenna);
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;
3079 /* default to RF2820 1T2R */
3080 ctlr->rf_rev = Rf2820;
3081 ctlr->ntxchains = 1;
3082 ctlr->nrxchains = 2;
3085 ctlr->rf_rev = (val >> 8) & 0xf;
3086 ctlr->ntxchains = (val >> 4) & 0xf;
3087 ctlr->nrxchains = val & 0xf;
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;
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);
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);
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);
3126 /* fix broken Tx power entries */
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;
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);
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);
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;
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;
3164 if((val & 0xff) != 0xff && (val & 0x80)){
3165 delta_5ghz = val & 0xf;
3166 if(!(val & 0x40)) /* negative number */
3167 delta_5ghz = -delta_5ghz;
3170 for(ridx = 0; ridx < 5; ridx++){
3173 val = rom_read(ctlr, EepromRpwr + ridx * 2);
3175 val = rom_read(ctlr, EepromRpwr + ridx * 2 + 1);
3176 reg |= (u32int)val << 16;
3178 ctlr->txpow20mhz[ridx] = reg;
3179 ctlr->txpow40mhz_2ghz[ridx] = b4inc(reg, delta_2ghz);
3180 ctlr->txpow40mhz_5ghz[ridx] = b4inc(reg, delta_5ghz);
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;
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;
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){
3229 * On RT3090 chips (limited to 2 Rx chains), this ROM
3230 * field contains the Tx mixer gain for the 2GHz band.
3232 if((val & 0xff) != 0xff)
3233 ctlr->txmixgain_2ghz = val & 0x7;
3235 ctlr->rssi_2ghz[2] = val & 0xff; /* Ant C */
3236 ctlr->lna[2] = val >> 8; /* channel group 2 */
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 */
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 */
3252 /* fix broken 5GHz LNA entries */
3253 if(ctlr->lna[2] == 0 || ctlr->lna[2] == 0xff){
3254 ctlr->lna[2] = ctlr->lna[1];
3256 if(ctlr->lna[3] == 0 || ctlr->lna[3] == 0xff){
3257 ctlr->lna[3] = ctlr->lna[1];
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;
3265 if(ctlr->rssi_5ghz[ant] < -10 || ctlr->rssi_5ghz[ant] > 10){
3266 ctlr->rssi_5ghz[ant] = 0;
3274 getrfname(u8int rev)
3276 if((rev == 0) || (rev >= nelem(rfnames)))
3278 if(rfnames[rev][0] == '\0')
3280 return rfnames[rev];
3284 rbplant(Ctlr *ctlr, int i)
3289 b = iallocb(Rbufsize + 256);
3292 b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, 256);
3293 memset(b->rp, 0, Rbufsize);
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 */
3300 put16(p, Rbufsize);;
3306 allocrx(Ctlr *ctlr, RXQ *rx)
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){
3322 if(rbplant(ctlr, i) < 0)
3323 return "no memory for rx descriptors";
3330 freerx(Ctlr *, RXQ *rx)
3334 for(i = 0; i < Nrx; i++){
3335 if(rx->b[i] != nil){
3348 alloctx(Ctlr *, TXQ *tx)
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*));
3363 freetx(Ctlr *, TXQ *tx)
3372 alloctxpool(Ctlr *ctlr)
3378 pool->p = mallocalign(Ntxpool * TxwiDmaSz, 4096, 0, 0);
3380 return "no memory for pool";
3381 memset(pool->p, 0, Ntxpool * TxwiDmaSz);
3387 initring(Ctlr *ctlr)
3393 * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings.
3395 for(qid = 0; qid < 6; qid++){
3396 if((err = alloctx(ctlr, &ctlr->tx[qid])) != nil)
3399 if((err = allocrx(ctlr, &ctlr->rx)) != nil)
3402 if((err = alloctxpool(ctlr)) != nil)
3404 /* mgmt ring is broken on RT2860C, use EDCA AC VO ring instead */
3406 ctlr->mgtqid = (ctlr->mac_ver == 0x2860 && ctlr->mac_rev == 0x0100) ?
3410 fail2: freerx(ctlr, &ctlr->rx);
3412 fail1: while(--qid >= 0)
3413 freetx(ctlr, &ctlr->tx[qid]);
3418 rt2860init(Ether *edev)
3427 /* wait for NIC to initialize */
3428 for(ntries = 0; ntries < 100; ntries++){
3429 tmp = csr32r(ctlr, AsicVerId);
3430 if(tmp != 0 && tmp != 0xffffffff)
3435 print("timeout waiting for NIC to initialize");
3438 ctlr->mac_ver = tmp >> 16;
3439 ctlr->mac_rev = tmp & 0xffff;
3441 if(ctlr->mac_ver != 0x2860){
3442 switch(ctlr->pdev->did){
3449 ctlr->flags = AdvancedPs;
3453 /* retrieve RF rev. no and various other things from EEPROM */
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);
3467 static Ctlr *rt2860head, *rt2860tail;
3475 while(pdev = pcimatch(pdev, 0, 0)){
3479 if(pdev->ccrb != 2 || pdev->ccru != 0x80)
3481 if(pdev->vid != 0x1814) /* Ralink */
3495 ctlr = malloc(sizeof(Ctlr));
3497 print("rt2860: unable to alloc Ctlr\n");
3500 ctlr->port = pdev->mem[0].bar & ~0x0F;
3501 mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
3503 print("rt2860: can't map %8.8luX\n", pdev->mem[0].bar);
3510 if(rt2860head != nil)
3511 rt2860tail->link = ctlr;
3519 rt2860pnp(Ether* edev)
3523 if(rt2860head == nil)
3526 for(ctlr = rt2860head; ctlr != nil; ctlr = ctlr->link){
3529 if(edev->port == 0 || edev->port == ctlr->port){
3539 edev->port = ctlr->port;
3540 edev->irq = ctlr->pdev->intl;
3541 edev->tbdf = ctlr->pdev->tbdf;
3543 edev->attach = rt2860attach;
3544 edev->ifstat = rt2860ifstat;
3545 edev->ctl = rt2860ctl;
3546 edev->promiscuous = rt2860promiscuous;
3547 edev->multicast = rt2860multicast;
3550 if(rt2860init(edev) < 0){
3555 intrenable(edev->irq, rt2860interrupt, edev, edev->tbdf, edev->name);
3561 etherrt2860link(void)
3563 addethercard("rt2860", rt2860pnp);