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"
21 typedef signed char s8int;
26 PciCfgUsb = (1 << 17),
27 PciCfgPci = (1 << 16),
39 Rt3090AuxCtrl = 0x010c,
45 /* SCH/DMA registers */
47 /* flags for registers IntStatus/IntMask */
48 TxCoherent = (1 << 17),
49 RxCoherent = (1 << 16),
55 TxRxCoherent = (1 << 10),
57 TxDoneInt5 = (1 << 8),
58 TxDoneInt4 = (1 << 7),
59 TxDoneInt3 = (1 << 6),
60 TxDoneInt2 = (1 << 5),
61 TxDoneInt1 = (1 << 4),
62 TxDoneInt0 = (1 << 3),
82 TxdlyIntEn = (1 << 31),
85 RxdlyIntEn = (1 << 15),
97 #define TxBasePtr(qid) (0x0230 + (qid) * 16)
98 #define TxMaxCnt(qid) (0x0234 + (qid) * 16)
99 #define TxCtxIdx(qid) (0x0238 + (qid) * 16)
100 #define TxDtxIdx(qid) (0x023c + (qid) * 16)
105 UsbDmaCfg = 0x02a0 /* RT2870 only */,
106 UsbTxBusy = (1 << 31),
107 UsbRxBusy = (1 << 30),
108 UsbEpoutVldShift = 24,
111 UsbRxAggEn = (1 << 21),
112 UsbTxopHalt = (1 << 20),
113 UsbTxClear = (1 << 19),
114 UsbPhyWdEn = (1 << 16),
115 UsbPhyManRst = (1 << 15),
116 #define UsbRxAggLmt(x) ((x) << 8) /* in unit of 1KB */
117 #define UsbRxAggTo(x) ((x) & 0xff) /* in unit of 33ns */
128 HstPmSel = (1 << 16),
131 Clkselect = (1 << 12),
132 PbfClkEn = (1 << 11),
133 MacClkEn = (1 << 10),
145 LedRadio = (1 << 13),
146 LedLink2ghz = (1 << 14),
147 LedLink5ghz = (1 << 15),
148 McuCmdLedRssi = 0x51,
152 McuCmdRfreset = 0x72,
155 McuCmdPslevel = 0x83,
159 Null0Mode = (1 << 15),
160 Null1Mode = (1 << 14),
161 RxDropMode = (1 << 13),
162 Tx0qManual = (1 << 12),
163 Tx1qManual = (1 << 11),
164 Tx2qManual = (1 << 10),
165 Rx0qManual = (1 << 9),
173 #define WriteTxq(qid) (1 << (11 - (qid)))
174 Null0Kick = (1 << 7),
175 Null1Kick = (1 << 6),
177 #define ReadTxq(qid) = (1 << (3 - (qid))
180 /* flags for registers McuIntSta/McuIntEna */
181 McuMacInt8 = (1 << 24),
182 McuMacInt7 = (1 << 23),
183 McuMacInt6 = (1 << 22),
184 McuMacInt4 = (1 << 20),
185 McuMacInt3 = (1 << 19),
186 McuMacInt2 = (1 << 18),
187 McuMacInt1 = (1 << 17),
188 McuMacInt0 = (1 << 16),
202 #define TxqIo(qid) (0x041c + (qid) * 4)
208 Rx0qPcntMask = 0xff000000,
209 Tx2qPcntMask = 0x00ff0000,
210 Tx1qPcntMask = 0x0000ff00,
211 Tx0qPcntMask = 0x000000ff,
214 CapAdcFeq = (1 << 31),
215 CapStart = (1 << 30),
217 TrigOffsetShift = 16,
222 /* RT3070 registers */
223 Rt3070RfCsrCfg = 0x0500,
224 Rt3070RfKick = (1 << 17),
225 Rt3070RfWrite = (1 << 16),
226 Rt3070EfuseCtrl = 0x0580,
227 Rt3070SelEfuse = (1 << 31),
228 Rt3070EfsromKick = (1 << 30),
229 Rt3070EfsromAinMask = 0x03ff0000,
230 Rt3070EfsromAinShift = 16,
231 Rt3070EfsromModeMask = 0x000000c0,
232 Rt3070EfuseAoutMask = 0x0000003f,
233 Rt3070EfuseData0 = 0x0590,
234 Rt3070EfuseData1 = 0x0594,
235 Rt3070EfuseData2 = 0x0598,
236 Rt3070EfuseData3 = 0x059c,
237 Rt3090OscCtrl = 0x05a4,
238 Rt3070LdoCfg0 = 0x05d4,
239 Rt3070GpioSwitch = 0x05dc,
247 WlanHaltEn = (1 << 6),
248 PbfLoopEn = (1 << 5),
249 ContTxTest = (1 << 4),
256 MacBssidDw0 = 0x1010,
257 MacBssidDw1 = 0x1014,
258 MultiBcnNumShift = 18,
259 MultiBssidModeShift = 16,
261 MinMpduLenShift = 16,
262 MaxPsduLenShift = 12,
269 BbpRwParallel = (1 << 19),
270 BbpParDur1125 = (1 << 18),
271 BbpCsrKick = (1 << 17),
272 BbpCsrRead = (1 << 16),
276 RfRegCtrl = (1 << 31),
277 RfLeSel1 = (1 << 30),
278 RfLeStby = (1 << 29),
279 RfRegWidthShift = 24,
292 LedModeSlowBlink = 2,
294 SlowBlkTimeShift = 16,
300 /* undocumented registers */
305 /* MAC Timing control registers */
306 XifsTimeCfg = 0x1100,
307 BbRxendEn = (1 << 29),
309 OfdmXifsTimeShift = 16,
310 OfdmSifsTimeShift = 8,
311 CckSifsTimeShift = 0,
312 BkoffSlotCfg = 0x1104,
313 CcDelayTimeShift = 8,
318 NavClrEn = (1 << 15),
321 EifsAsChBusy = (1 << 4),
322 NavAsChBusy = (1 << 3),
323 RxAsChBusy = (1 << 2),
324 TxAsChBusy = (1 << 1),
325 ChStaTimerEn = (1 << 0),
326 PbfLifeTimer = 0x1110,
328 TsfInsCompShift = 24,
330 TbttTimerEn = (1 << 19),
331 TsfSyncModeShift = 17,
335 TsfSyncModeHostap = 3,
336 TsfTimerEn = (1 << 16),
338 TbttSyncCfg = 0x1118,
343 TsfTimerDw0 = 0x111c,
344 TsfTimerDw1 = 0x1120,
346 IntTimerCfg = 0x1128,
348 PreTbttTimerShift = 0,
350 GpTimerEn = (1 << 1),
351 PreTbttIntEn = (1 << 0),
356 /* MAC Power Save configuration registers */
357 MacStatusReg = 0x1200,
358 RxStatusBusy = (1 << 1),
359 TxStatusBusy = (1 << 0),
365 AutoWakeupCfg = 0x1208,
366 AutoWakeupEn = (1 << 15),
367 SleepTbttNumShift = 8,
368 WakeupLeadTimeShift = 0,
372 /* MAC TX configuration registers */
373 #define EdcaAcCfg(aci) (0x1300 + (aci) * 4)
374 EdcaTidAcMap = 0x1310,
375 #define TxPwrCfg(ridx) (0x1314 + (ridx) * 4)
377 Rt3593LnaPeG2Pol = (1 << 31),
378 Rt3593LnaPeA2Pol = (1 << 30),
379 Rt3593LnaPeG2En = (1 << 29),
380 Rt3593LnaPeA2En = (1 << 28),
381 Rt3593LnaPe2En = (Rt3593LnaPeA2En | Rt3593LnaPeG2En),
382 Rt3593PaPeG2Pol = (1 << 27),
383 Rt3593PaPeA2Pol = (1 << 26),
384 Rt3593PaPeG2En = (1 << 25),
385 Rt3593PaPeA2En = (1 << 24),
390 LnaPeG1Pol = (1 << 15),
391 LnaPeA1Pol = (1 << 14),
392 LnaPeG0Pol = (1 << 13),
393 LnaPeA0Pol = (1 << 12),
394 LnaPeG1En = (1 << 11),
395 LnaPeA1En = (1 << 10),
396 LnaPe1En = (LnaPeA1En | LnaPeG1En),
397 LnaPeG0En = (1 << 9),
398 LnaPeA0En = (1 << 8),
399 LnaPe0En = (LnaPeA0En | LnaPeG0En),
400 PaPeG1Pol = (1 << 7),
401 PaPeA1Pol = (1 << 6),
402 PaPeG0Pol = (1 << 5),
403 PaPeA0Pol = (1 << 4),
409 Tx5gBandSelN = (1 << 2),
410 Tx5gBandSelP = (1 << 1),
411 TxBandSel = (1 << 0),
418 DlyRftrDisShift = 16,
426 TxopThresCfg = 0x133c,
427 TxopRemThresShift = 24,
428 CfEndThresShift = 16,
431 TxopCtrlCfg = 0x1340,
435 LsigTxopEn = (1 << 6),
436 TxopTrunEnMimops = (1 << 4),
437 TxopTrunEnTxop = (1 << 3),
438 TxopTrunEnRate = (1 << 2),
439 TxopTrunEnAc = (1 << 1),
440 TxopTrunEnTimeout = (1 << 0),
442 RtsFbkEn = (1 << 24),
444 RtsRtyLimitShift = 0,
445 TxTimeoutCfg = 0x1348,
446 TxopTimeoutShift = 16,
447 RxAckTimeoutShift = 8,
448 MpduLifeTimeShift = 4,
450 TxAutofbEn = (1 << 30),
451 AggRtyModeTimer = (1 << 29),
452 NagRtyModeTimer = (1 << 28),
453 LongRtyThresShift = 16,
454 LongRtyLimitShift = 8,
455 ShortRtyLimitShift = 0,
459 TxCfackEn = (1 << 12),
462 RemoteUmfsEn = (1 << 9),
464 RemoteMfbLtShift = 0,
470 /* possible flags for registers *ProtCfg */
472 TxopAllowGf40 = (1 << 25),
473 TxopAllowGf20 = (1 << 24),
474 TxopAllowMm40 = (1 << 23),
475 TxopAllowMm20 = (1 << 22),
476 TxopAllowOfdm = (1 << 21),
477 TxopAllowCck = (1 << 20),
478 TxopAllowAll = (0x3f << 20),
479 ProtNavShort = (1 << 18),
480 ProtNavLong = (2 << 18),
481 ProtCtrlRtsCts = (1 << 16),
482 ProtCtrlCts = (2 << 16),
483 OfdmProtCfg = 0x1368,
484 Mm20ProtCfg = 0x136c,
485 Mm40ProtCfg = 0x1370,
486 Gf20ProtCfg = 0x1374,
487 Gf40ProtCfg = 0x1378,
489 /* possible flags for registers EXP_{CTS,ACK}_TIME */
490 ExpOfdmTimeShift = 16,
496 /* MAC RX configuration registers */
498 DropCtrlRsv = (1 << 16),
501 DropPspoll = (1 << 13),
505 DropCfend = (1 << 9),
506 DropCfack = (1 << 8),
510 DropVerErr = (1 << 4),
511 DropNotMybss = (1 << 3),
512 DropUcNome = (1 << 2),
513 DropPhyErr = (1 << 1),
514 DropCrcErr = (1 << 0),
516 CtrlPwrBit = (1 << 7),
517 BacAckPolicy = (1 << 6),
518 CckShortEn = (1 << 4),
519 Cts40mRefEn = (1 << 3),
520 Cts40mModeEn = (1 << 2),
521 BacAckpolicyEn = (1 << 1),
522 AutoRspEn = (1 << 0),
523 LegacyBasicRate = 0x1408,
524 HtBasicRate = 0x140c,
526 SifsCostCfg = 0x1414,
527 OfdmSifsCostShift = 8,
528 CckSifsCostShift = 0,
529 RxParserCfg = 0x1418,
533 /* MAC Security configuration registers */
540 /* MAC HCCA/PSMP configuration registers */
541 TxopHldrAddr0 = 0x1600,
542 TxopHldrAddr1 = 0x1604,
544 TxopEtm1En = (1 << 25),
545 TxopEtm0En = (1 << 24),
546 TxopEtmThresShift = 16,
547 TxopEtoEn = (1 << 8),
548 TxopEtoThresShift = 1,
549 PerRxRstEn = (1 << 0),
550 QosCfpollRaDw0 = 0x160c,
551 QosCfpollA1Dw1 = 0x1610,
552 QosCfpollQc = 0x1614,
556 /* MAC Statistics Counters */
566 TxqAckreq = (1 << 7),
573 /* RX WCID search table */
574 #define WcidEntry(wcid) (0x1800 + (wcid) * 8)
578 Rt2870FwBase = 0x3000,
581 /* Pair-wise key table */
582 #define Pkey(wcid) (0x4000 + (wcid) * 32)
585 #define Iveiv(wcid) (0x6000 + (wcid) * 8)
587 /* WCID attribute table */
588 #define WcidAttr(wcid) (0x6800 + (wcid) * 4)
590 /* possible flags for register WCID_ATTR */
603 /* Shared Key Table */
604 #define Skey(vap, kidx) (0x6c00 + (vap) * 128 + (kidx) * 32)
606 /* Shared Key Mode */
609 SkeyMode815 = 0x7004,
610 SkeyMode1623 = 0x7008,
611 SkeyMode2431 = 0x700c,
615 /* Shared Memory between MCU and host */
619 H2mMailboxCid = 0x7014,
620 H2mMailboxStatus = 0x701c,
621 H2mBbpagent = 0x7028,
622 #define BcnBase(vap) (0x7800 + (vap) * 512)
626 * RT2860 TX descriptor
627 * --------------------
628 * u32int sdp0 Segment Data Pointer 0
629 * u16int sdl1 Segment Data Length 1
630 * u16int sdl0 Segment Data Length 0
631 * u32int sdp1 Segment Data Pointer 1
639 TxLs1 = (1 << 14) /* SDP1 is the last segment */,
642 TxLs0 = (1 << 14) /* SDP0 is the last segment */,
645 TxQselMgmt = (0 << 1),
646 TxQselHcca = (1 << 1),
647 TxQselEdca = (2 << 1),
652 * TX Wireless Information
653 * -----------------------
658 * u8int wcid Wireless Client ID
666 TxMpduDsityShift = 5,
688 TxBawinsizeShift = 2,
696 * RT2860 RX descriptor
697 * --------------------
716 RxMicerr = (1 << 10),
730 * RX Wireless Information
731 * -----------------------
752 WIFIHDRSIZE = 2+2+3*6+2,
759 /* first DMA segment contains TXWI + 802.11 header + 32-bit padding */
760 TxwiDmaSz = Txwisize + WIFIHDRSIZE + 2
772 Rf2820 = 1 /* 2T3R */,
773 Rf2850 = 2 /* dual-band 2T3R */,
774 Rf2720 = 3 /* 1T2R */,
775 Rf2750 = 4 /* dual-band 1T2R */,
776 Rf3020 = 5 /* 1T1R */,
777 Rf2020 = 6 /* b/g */,
778 Rf3021 = 7 /* 1T2R */,
779 Rf3022 = 8 /* 2T2R */,
780 Rf3052 = 9 /* dual-band 2T2R */,
781 Rf3320 = 11 /* 1T1R */,
782 Rf3053 = 13 /* dual-band 3T3R */,
786 Rt3070RfBlock = (1 << 0),
787 Rt3070Rx0Pd = (1 << 2),
788 Rt3070Tx0Pd = (1 << 3),
789 Rt3070Rx1Pd = (1 << 4),
790 Rt3070Tx1Pd = (1 << 5),
791 Rt3070Rx2Pd = (1 << 6),
792 Rt3070Tx2Pd = (1 << 7),
793 Rt3070Tune = (1 << 0),
794 Rt3070TxLo2 = (1 << 3),
795 Rt3070TxLo1 = (1 << 3),
796 Rt3070RxLo1 = (1 << 3),
797 Rt3070RxLo2 = (1 << 3),
798 Rt3070RxCtb = (1 << 7),
799 Rt3070BbLoopback = (1 << 0),
801 Rt3593Vco = (1 << 0),
802 Rt3593Rescal = (1 << 7),
803 Rt3593Vcocal = (1 << 7),
804 Rt3593VcoIc = (1 << 6),
805 Rt3593LdoPllVcMask = 0x0e,
806 Rt3593LdoRfVcMask = 0xe0,
807 Rt3593CpIcMask = 0xe0,
809 Rt3593RxCtb = (1 << 5)
812 static const char* rfnames[] = {
827 /* USB commands, RT2870 only */
830 Rt2870WriteRegion1 = 6,
831 Rt2870ReadRegion1 = 7,
832 Rt2870EepromRead = 9,
836 EepromDelay = 1 /* minimum hold time (microsecond) */,
838 EepromVersion = 0x01,
842 EepromPciePslevel = 0x11,
844 EepromAntenna = 0x1a,
846 EepromCountry = 0x1c,
847 EepromFreqLeds = 0x1d,
852 EepromRssi12ghz = 0x23,
853 EepromRssi22ghz = 0x24,
854 EepromRssi15ghz = 0x25,
855 EepromRssi25ghz = 0x26,
856 EepromDeltapwr = 0x28,
857 EepromPwr2ghzBase1 = 0x29,
858 EepromPwr2ghzBase2 = 0x30,
859 EepromTssi12ghz = 0x37,
860 EepromTssi22ghz = 0x38,
861 EepromTssi32ghz = 0x39,
862 EepromTssi42ghz = 0x3a,
863 EepromTssi52ghz = 0x3b,
864 EepromPwr5ghzBase1 = 0x3c,
865 EepromPwr5ghzBase2 = 0x53,
866 EepromTssi15ghz = 0x6a,
867 EepromTssi25ghz = 0x6b,
868 EepromTssi35ghz = 0x6c,
869 EepromTssi45ghz = 0x6d,
870 EepromTssi55ghz = 0x6e,
872 EepromBbpBase = 0x78,
873 Rt3071EepromRfBase = 0x82,
883 /* ring and pool count */
890 typedef struct FWImage FWImage;
891 typedef struct TXQ TXQ;
892 typedef struct RXQ RXQ;
893 typedef struct Pool Pool;
895 typedef struct Ctlr Ctlr;
905 uint i; /* current */
907 u32int *d; /* descriptors */
922 uint i; /* current */
954 u8int txmixgain_2ghz;
955 u8int txmixgain_5ghz;
968 u32int txpow20mhz[5];
969 u32int txpow40mhz_2ghz[5];
970 u32int txpow40mhz_5ghz[5];
982 /* assigned node ids in hardware node table or -1 if unassigned */
986 /* current receiver settings */
987 uchar bssid[Eaddrlen];
999 /* controller flags */
1001 AdvancedPs = 1 << 0,
1005 static const struct rt2860_rate {
1008 /*enum ieee80211_phytype phy;*/
1012 } rt2860_rates[] = {
1013 { 2, 0,/* IEEE80211_T_DS,*/ 0, 314, 314 },
1014 { 4, 1,/* IEEE80211_T_DS,*/ 1, 258, 162 },
1015 { 11, 2,/* IEEE80211_T_DS,*/ 2, 223, 127 },
1016 { 22, 3,/* IEEE80211_T_DS,*/ 3, 213, 117 },
1017 { 12, 0,/* IEEE80211_T_OFDM,*/ 4, 60, 60 },
1018 { 18, 1,/* IEEE80211_T_OFDM,*/ 4, 52, 52 },
1019 { 24, 2,/* IEEE80211_T_OFDM,*/ 6, 48, 48 },
1020 { 36, 3,/* IEEE80211_T_OFDM,*/ 6, 44, 44 },
1021 { 48, 4,/* IEEE80211_T_OFDM,*/ 8, 44, 44 },
1022 { 72, 5,/* IEEE80211_T_OFDM,*/ 8, 40, 40 },
1023 { 96, 6,/* IEEE80211_T_OFDM,*/ 8, 40, 40 },
1024 { 108, 7,/* IEEE80211_T_OFDM,*/ 8, 40, 40 }
1028 * Default values for MAC registers; values taken from the reference driver.
1030 static const struct {
1033 } rt2860_def_mac[] = {
1034 { BcnOffset0, 0xf8f0e8e0 },
1035 { LegacyBasicRate, 0x0000013f },
1036 { HtBasicRate, 0x00008003 },
1037 { MacSysCtrl, 0x00000000 },
1038 { BkoffSlotCfg, 0x00000209 },
1039 { TxSwCfg0, 0x00000000 },
1040 { TxSwCfg1, 0x00080606 },
1041 { TxLinkCfg, 0x00001020 },
1042 { TxTimeoutCfg, 0x000a2090 },
1043 { LedCfg, 0x7f031e46 },
1044 { WmmAifsnCfg, 0x00002273 },
1045 { WmmCwminCfg, 0x00002344 },
1046 { WmmCwmaxCfg, 0x000034aa },
1047 { MaxPcnt, 0x1f3fbf9f },
1048 { TxRtyCfg, 0x47d01f0f },
1049 { AutoRspCfg, 0x00000013 },
1050 { CckProtCfg, 0x05740003 },
1051 { OfdmProtCfg, 0x05740003 },
1052 { Gf20ProtCfg, 0x01744004 },
1053 { Gf40ProtCfg, 0x03f44084 },
1054 { Mm20ProtCfg, 0x01744004 },
1055 { Mm40ProtCfg, 0x03f54084 },
1056 { TxopCtrlCfg, 0x0000583f },
1057 { TxopHldrEt, 0x00000002 },
1058 { TxRtsCfg, 0x00092b20 },
1059 { ExpAckTime, 0x002400ca },
1060 { XifsTimeCfg, 0x33a41010 },
1061 { PwrPinCfg, 0x00000003 },
1065 * Default values for BBP registers; values taken from the reference driver.
1067 static const struct {
1070 } rt2860_def_bbp[] = {
1089 * Default settings for RF registers; values derived from the reference driver.
1091 static const struct rfprog {
1093 u32int r1, r2, r3, r4;
1094 } rt2860_rf2850[] = {
1095 { 1, 0x100bb3, 0x1301e1, 0x05a014, 0x001402 },
1096 { 2, 0x100bb3, 0x1301e1, 0x05a014, 0x001407 },
1097 { 3, 0x100bb3, 0x1301e2, 0x05a014, 0x001402 },
1098 { 4, 0x100bb3, 0x1301e2, 0x05a014, 0x001407 },
1099 { 5, 0x100bb3, 0x1301e3, 0x05a014, 0x001402 },
1100 { 6, 0x100bb3, 0x1301e3, 0x05a014, 0x001407 },
1101 { 7, 0x100bb3, 0x1301e4, 0x05a014, 0x001402 },
1102 { 8, 0x100bb3, 0x1301e4, 0x05a014, 0x001407 },
1103 { 9, 0x100bb3, 0x1301e5, 0x05a014, 0x001402 },
1104 { 10, 0x100bb3, 0x1301e5, 0x05a014, 0x001407 },
1105 { 11, 0x100bb3, 0x1301e6, 0x05a014, 0x001402 },
1106 { 12, 0x100bb3, 0x1301e6, 0x05a014, 0x001407 },
1107 { 13, 0x100bb3, 0x1301e7, 0x05a014, 0x001402 },
1108 { 14, 0x100bb3, 0x1301e8, 0x05a014, 0x001404 },
1109 { 36, 0x100bb3, 0x130266, 0x056014, 0x001408 },
1110 { 38, 0x100bb3, 0x130267, 0x056014, 0x001404 },
1111 { 40, 0x100bb2, 0x1301a0, 0x056014, 0x001400 },
1112 { 44, 0x100bb2, 0x1301a0, 0x056014, 0x001408 },
1113 { 46, 0x100bb2, 0x1301a1, 0x056014, 0x001402 },
1114 { 48, 0x100bb2, 0x1301a1, 0x056014, 0x001406 },
1115 { 52, 0x100bb2, 0x1301a2, 0x056014, 0x001404 },
1116 { 54, 0x100bb2, 0x1301a2, 0x056014, 0x001408 },
1117 { 56, 0x100bb2, 0x1301a3, 0x056014, 0x001402 },
1118 { 60, 0x100bb2, 0x1301a4, 0x056014, 0x001400 },
1119 { 62, 0x100bb2, 0x1301a4, 0x056014, 0x001404 },
1120 { 64, 0x100bb2, 0x1301a4, 0x056014, 0x001408 },
1121 { 100, 0x100bb2, 0x1301ac, 0x05e014, 0x001400 },
1122 { 102, 0x100bb2, 0x1701ac, 0x15e014, 0x001404 },
1123 { 104, 0x100bb2, 0x1701ac, 0x15e014, 0x001408 },
1124 { 108, 0x100bb3, 0x17028c, 0x15e014, 0x001404 },
1125 { 110, 0x100bb3, 0x13028d, 0x05e014, 0x001400 },
1126 { 112, 0x100bb3, 0x13028d, 0x05e014, 0x001406 },
1127 { 116, 0x100bb3, 0x13028e, 0x05e014, 0x001408 },
1128 { 118, 0x100bb3, 0x13028f, 0x05e014, 0x001404 },
1129 { 120, 0x100bb1, 0x1300e0, 0x05e014, 0x001400 },
1130 { 124, 0x100bb1, 0x1300e0, 0x05e014, 0x001404 },
1131 { 126, 0x100bb1, 0x1300e0, 0x05e014, 0x001406 },
1132 { 128, 0x100bb1, 0x1300e0, 0x05e014, 0x001408 },
1133 { 132, 0x100bb1, 0x1300e1, 0x05e014, 0x001402 },
1134 { 134, 0x100bb1, 0x1300e1, 0x05e014, 0x001404 },
1135 { 136, 0x100bb1, 0x1300e1, 0x05e014, 0x001406 },
1136 { 140, 0x100bb1, 0x1300e2, 0x05e014, 0x001400 },
1137 { 149, 0x100bb1, 0x1300e2, 0x05e014, 0x001409 },
1138 { 151, 0x100bb1, 0x1300e3, 0x05e014, 0x001401 },
1139 { 153, 0x100bb1, 0x1300e3, 0x05e014, 0x001403 },
1140 { 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 },
1141 { 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 },
1142 { 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 },
1143 { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 },
1144 { 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 },
1145 { 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 },
1146 { 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 },
1147 { 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 },
1154 } rt3090_freqs[] = {
1210 static const struct {
1213 } rt3090_def_rf[] = {
1242 RalinkRT2890 = 0x0681,
1243 RalinkRT2790 = 0x0781,
1244 RalinkRT3090 = 0x3090,
1248 #define csr32r(c, r) (*((c)->nic+((r)/4)))
1249 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
1251 static int rbplant(Ctlr*, int);
1252 static void setchan(Ctlr*, uint);
1253 static void rt3090setchan(Ctlr*, uint);
1254 static void selchangroup(Ctlr*, int);
1255 static void setleds(Ctlr*, u16int);
1259 return *((u16int*)p);
1263 return *((u32int*)p);
1266 put32(uchar *p, uint v){
1270 put16(uchar *p, uint v){
1274 memwrite(Ctlr *ctlr, u32int off, uchar *data, uint size){
1275 memmove((uchar*)ctlr->nic + off, data, size);
1278 setregion(Ctlr *ctlr, u32int off, uint val, uint size){
1279 memset((uchar*)ctlr->nic + off, val, size);
1283 rt2860ctl(Ether *edev, void *buf, long n)
1289 return wifictl(ctlr->wifi, buf, n);
1294 rt2860ifstat(Ether *edev, void *buf, long n, ulong off)
1300 return wifistat(ctlr->wifi, buf, n, off);
1305 setoptions(Ether *edev)
1311 for(i = 0; i < edev->nopt; i++)
1312 wificfg(ctlr->wifi, edev->opt[i]);
1316 rxon(Ether *edev, Wnode *bss)
1326 ctlr->channel = bss->channel;
1327 memmove(ctlr->bssid, bss->bssid, Eaddrlen);
1328 ctlr->aid = bss->aid;
1330 if(ctlr->wifi->debug)
1331 print("new assoc!");
1332 ctlr->bssnodeid = -1;
1334 ctlr->bcastnodeid = -1;
1337 memmove(ctlr->bssid, edev->bcast, Eaddrlen);
1339 ctlr->bcastnodeid = -1;
1340 ctlr->bssnodeid = -1;
1343 setleds(ctlr, LedRadio | LedLink2ghz);
1345 setleds(ctlr, LedRadio);
1347 if(ctlr->wifi->debug)
1348 print("#l%d: rxon: bssid %E, aid %x, channel %d wcid %d\n",
1349 edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, ctlr->wcid);
1352 if(ctlr->mac_ver >= 0x3071)
1353 rt3090setchan(ctlr, ctlr->channel);
1355 setchan(ctlr, ctlr->channel);
1356 selchangroup(ctlr, 0);
1360 #define CCK(mcs) (mcs)
1361 #define OFDM(mcs) (1 << 3 | (mcs))
1362 csr32w(ctlr, LgFbkCfg0,
1363 OFDM(6) << 28 | /* 54->48 */
1364 OFDM(5) << 24 | /* 48->36 */
1365 OFDM(4) << 20 | /* 36->24 */
1366 OFDM(3) << 16 | /* 24->18 */
1367 OFDM(2) << 12 | /* 18->12 */
1368 OFDM(1) << 8 | /* 12-> 9 */
1369 OFDM(0) << 4 | /* 9-> 6 */
1370 OFDM(0)); /* 6-> 6 */
1372 csr32w(ctlr, LgFbkCfg1,
1373 CCK(2) << 12 | /* 11->5.5 */
1374 CCK(1) << 8 | /* 5.5-> 2 */
1375 CCK(0) << 4 | /* 2-> 1 */
1376 CCK(0)); /* 1-> 1 */
1380 tmp = csr32r(ctlr, BkoffSlotCfg);
1382 tmp |= (cap & (1<<10)) ? 9 : 20;
1383 csr32w(ctlr, BkoffSlotCfg, tmp);
1385 /* set TX preamble */
1386 tmp = csr32r(ctlr, AutoRspCfg);
1388 if(cap & (1<<5)) tmp |= CckShortEn;
1389 csr32w(ctlr, AutoRspCfg, tmp);
1391 /* set basic rates */
1392 csr32w(ctlr, LegacyBasicRate, 0x003); /* 11B */
1395 csr32w(ctlr, MacBssidDw0,
1396 ctlr->bssid[0] | ctlr->bssid[1] << 8 | ctlr->bssid[2] << 16 | ctlr->bssid[3] << 24);
1397 csr32w(ctlr, MacBssidDw1,
1398 ctlr->bssid[4] | ctlr->bssid[5] << 8);
1400 if(ctlr->bcastnodeid == -1){
1401 ctlr->bcastnodeid = 0xff;
1402 memwrite(ctlr, WcidEntry(ctlr->bcastnodeid), edev->bcast, Eaddrlen);
1404 if(ctlr->bssnodeid == -1 && bss != nil && ctlr->aid != 0){
1405 ctlr->bssnodeid = 0;
1406 memwrite(ctlr, WcidEntry(ctlr->bssnodeid), ctlr->bssid, Eaddrlen);
1411 rt2860promiscuous(void *arg, int on)
1418 if(ctlr->attached == 0)
1422 rxon(edev, ctlr->wifi->bss);
1427 rt2860multicast(void *, uchar*, int)
1433 static char name[] = "ral-rt2860";
1434 uchar dirbuf[sizeof(Dir)+100], *data;
1444 snprint(buf, sizeof buf, "/boot/%s", name);
1445 c = namec(buf, Aopen, OREAD, 0);
1448 snprint(buf, sizeof buf, "/lib/firmware/%s", name);
1449 c = namec(buf, Aopen, OREAD, 0);
1455 n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf);
1457 error("can't stat firmware");
1458 convM2D(dirbuf, n, &d, nil);
1459 fw = malloc(sizeof(*fw));
1460 fw->size = d.length;
1461 data = fw->data = smalloc(d.length);
1467 while(r < d.length){
1468 n = devtab[c->type]->read(c, data+r, d.length-r, (vlong)r);
1484 /* set "host program ram write selection" bit */
1485 csr32w(ctlr, SysCtrl, HstPmSel);
1486 /* write microcode image */
1487 memwrite(ctlr, FwBase, ctlr->fw->data, ctlr->fw->size);
1488 /* kick microcontroller unit */
1489 csr32w(ctlr, SysCtrl, 0);
1491 csr32w(ctlr, SysCtrl, McuReset);
1493 csr32w(ctlr, H2mBbpagent, 0);
1494 csr32w(ctlr, H2mMailbox, 0);
1496 /* wait until microcontroller is ready */
1498 for(ntries = 0; ntries < 1000; ntries++){
1499 if(csr32r(ctlr, SysCtrl) & McuReady)
1504 return "timeout waiting for MCU to initialize";
1509 * Send a command to the 8051 microcontroller unit.
1512 mcucmd(Ctlr *ctlr, u8int cmd, u16int arg, int wait)
1519 for(ntries = 0; ntries < 100; ntries++){
1520 if(!(csr32r(ctlr, H2mMailbox) & H2mBusy))
1527 cid = wait ? cmd : TokenNoIntr;
1528 csr32w(ctlr, H2mMailbox, H2mBusy | cid << 16 | arg);
1530 csr32w(ctlr, HostCmd, cmd);
1534 /* wait for the command to complete */
1535 for(ntries = 0; ntries < 200; ntries++){
1536 tmp = csr32r(ctlr, H2mMailboxCid);
1537 /* find the command slot */
1538 for(slot = 0; slot < 4; slot++, tmp >>= 8)
1539 if((tmp & 0xff) == cid)
1546 /* clear command and status */
1547 csr32w(ctlr, H2mMailboxStatus, 0xffffffff);
1548 csr32w(ctlr, H2mMailboxCid, 0xffffffff);
1551 /* get command status (1 means success) */
1552 tmp = csr32r(ctlr, H2mMailboxStatus);
1553 tmp = (tmp >> (slot * 8)) & 0xff;
1554 /* clear command and status */
1555 csr32w(ctlr, H2mMailboxStatus, 0xffffffff);
1556 csr32w(ctlr, H2mMailboxCid, 0xffffffff);
1557 return (tmp == 1) ? 0 : -1;
1562 * Reading and writing from/to the BBP is different from RT2560 and RT2661.
1563 * We access the BBP through the 8051 microcontroller unit which means that
1564 * the microcode must be loaded first.
1567 bbpwrite(Ctlr *ctlr, u8int reg, u8int val)
1571 for(ntries = 0; ntries < 100; ntries++){
1572 if(!(csr32r(ctlr, H2mBbpagent) & BbpCsrKick))
1577 print("could not write to BBP through MCU\n");
1581 csr32w(ctlr, H2mBbpagent, BbpRwParallel |
1582 BbpCsrKick | reg << 8 | val);
1585 mcucmd(ctlr, McuCmdBbp, 0, 0);
1590 bbpread(Ctlr *ctlr, u8int reg)
1595 for(ntries = 0; ntries < 100; ntries++){
1596 if(!(csr32r(ctlr, H2mBbpagent) & BbpCsrKick))
1601 print("could not read from BBP through MCU");
1605 csr32w(ctlr, H2mBbpagent, BbpRwParallel |
1606 BbpCsrKick | BbpCsrRead | reg << 8);
1609 mcucmd(ctlr, McuCmdBbp, 0, 0);
1612 for(ntries = 0; ntries < 100; ntries++){
1613 val = csr32r(ctlr, H2mBbpagent);
1614 if(!(val & BbpCsrKick))
1618 print("could not read from BBP through MCU\n");
1629 /* wait for BBP to wake up */
1630 for(ntries = 0; ntries < 20; ntries++){
1631 u8int bbp0 = bbpread(ctlr, 0);
1632 if(bbp0 != 0 && bbp0 != 0xff)
1636 err = "timeout waiting for BBP to wake up";
1640 /* initialize BBP registers to default values */
1641 for(i = 0; i < nelem(rt2860_def_bbp); i++){
1642 bbpwrite(ctlr, rt2860_def_bbp[i].reg,
1643 rt2860_def_bbp[i].val);
1646 /* fix BBP84 for RT2860E */
1647 if(ctlr->mac_ver == 0x2860 && ctlr->mac_rev != 0x0101)
1648 bbpwrite(ctlr, 84, 0x19);
1650 if(ctlr->mac_ver >= 0x3071){
1651 bbpwrite(ctlr, 79, 0x13);
1652 bbpwrite(ctlr, 80, 0x05);
1653 bbpwrite(ctlr, 81, 0x33);
1654 }else if(ctlr->mac_ver == 0x2860 && ctlr->mac_rev == 0x0100){
1655 bbpwrite(ctlr, 69, 0x16);
1656 bbpwrite(ctlr, 73, 0x12);
1664 setleds(Ctlr *ctlr, u16int which)
1666 mcucmd(ctlr, McuCmdLeds,
1667 which | (ctlr->leds & 0x7f), 0);
1678 /* enable Tx/Rx DMA engine */
1679 csr32w(ctlr, MacSysCtrl, MacTxEn);
1681 for(ntries = 0; ntries < 200; ntries++){
1682 tmp = csr32r(ctlr, WpdmaGloCfg);
1683 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
1688 err = "timeout waiting for DMA engine";
1694 tmp |= RxDmaEn | TxDmaEn |
1695 WpdmaBtSize64 << WpdmaBtSizeShift;
1696 csr32w(ctlr, WpdmaGloCfg, tmp);
1699 tmp = DropCrcErr | DropPhyErr;
1701 tmp |= DropUcNome | DropDupl |
1702 DropCts | DropBa | DropAck |
1703 DropVerErr | DropCtrlRsv |
1704 DropCfack | DropCfend;
1705 tmp |= DropRts | DropPspoll;
1707 csr32w(ctlr, RxFiltrCfg, tmp);
1709 csr32w(ctlr, MacSysCtrl, MacRxEn | MacTxEn);
1715 * Write to one of the 4 programmable 24-bit RF registers.
1718 rfwrite(Ctlr *ctlr, u8int reg, u32int val)
1723 for(ntries = 0; ntries < 100; ntries++){
1724 if(!(csr32r(ctlr, RfCsrCfg0) & RfRegCtrl))
1729 print("could not write to RF\n");
1733 /* RF registers are 24-bit on the RT2860 */
1734 tmp = RfRegCtrl | 24 << RfRegWidthShift |
1735 (val & 0x3fffff) << 2 | (reg & 3);
1736 csr32w(ctlr, RfCsrCfg0, tmp);
1740 rt3090rfread(Ctlr *ctlr, u8int reg)
1745 for(ntries = 0; ntries < 100; ntries++){
1746 if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
1751 print("could not read RF register\n");
1754 tmp = Rt3070RfKick | reg << 8;
1755 csr32w(ctlr, Rt3070RfCsrCfg, tmp);
1757 for(ntries = 0; ntries < 100; ntries++){
1758 tmp = csr32r(ctlr, Rt3070RfCsrCfg);
1759 if(!(tmp & Rt3070RfKick))
1764 print("could not read RF register\n");
1771 rt3090rfwrite(Ctlr *ctlr, u8int reg, u8int val)
1776 for(ntries = 0; ntries < 10; ntries++){
1777 if(!(csr32r(ctlr, Rt3070RfCsrCfg) & Rt3070RfKick))
1782 print("could not write to RF\n");
1786 tmp = Rt3070RfWrite | Rt3070RfKick | reg << 8 | val;
1787 csr32w(ctlr, Rt3070RfCsrCfg, tmp);
1791 selchangroup(Ctlr *ctlr, int group)
1796 bbpwrite(ctlr, 62, 0x37 - ctlr->lna[group]);
1797 bbpwrite(ctlr, 63, 0x37 - ctlr->lna[group]);
1798 bbpwrite(ctlr, 64, 0x37 - ctlr->lna[group]);
1799 bbpwrite(ctlr, 86, 0x00);
1802 if(ctlr->ext_2ghz_lna){
1803 bbpwrite(ctlr, 82, 0x62);
1804 bbpwrite(ctlr, 75, 0x46);
1806 bbpwrite(ctlr, 82, 0x84);
1807 bbpwrite(ctlr, 75, 0x50);
1810 if(ctlr->ext_5ghz_lna){
1811 bbpwrite(ctlr, 82, 0xf2);
1812 bbpwrite(ctlr, 75, 0x46);
1814 bbpwrite(ctlr, 82, 0xf2);
1815 bbpwrite(ctlr, 75, 0x50);
1819 tmp = csr32r(ctlr, TxBandCfg);
1820 tmp &= ~(Tx5gBandSelN | Tx5gBandSelP);
1821 tmp |= (group == 0) ? Tx5gBandSelN : Tx5gBandSelP;
1822 csr32w(ctlr, TxBandCfg, tmp);
1824 /* enable appropriate Power Amplifiers and Low Noise Amplifiers */
1825 tmp = RftrEn | TrswEn | LnaPe0En;
1826 if(ctlr->nrxchains > 1)
1828 if(ctlr->mac_ver == 0x3593 && ctlr->nrxchains > 2)
1829 tmp |= Rt3593LnaPe2En;
1830 if(group == 0){ /* 2GHz */
1832 if(ctlr->ntxchains > 1)
1834 if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains > 2)
1835 tmp |= Rt3593PaPeG2En;
1838 if(ctlr->ntxchains > 1)
1840 if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains > 2)
1841 tmp |= Rt3593PaPeA2En;
1843 csr32w(ctlr, TxPinCfg, tmp);
1845 if(ctlr->mac_ver == 0x3593){
1846 tmp = csr32r(ctlr, GpioCtrl);
1847 if(ctlr->flags & ConnPciE){
1856 tmp = (tmp & ~0x00001000) | 0x00000010;
1857 csr32w(ctlr, GpioCtrl, tmp);
1860 /* set initial AGC value */
1861 if(group == 0){ /* 2GHz band */
1862 if(ctlr->mac_ver >= 0x3071)
1863 agc = 0x1c + ctlr->lna[0] * 2;
1865 agc = 0x2e + ctlr->lna[0];
1866 }else{ /* 5GHz band */
1867 agc = 0x32 + (ctlr->lna[group] * 5) / 3;
1869 bbpwrite(ctlr, 66, agc);
1876 setchan(Ctlr *ctlr, uint chan)
1878 const struct rfprog *rfprog = rt2860_rf2850;
1880 s8int txpow1, txpow2;
1883 /* find the settings for this channel (we know it exists) */
1884 for(i = 0; rfprog[i].chan != chan; i++);
1887 if(ctlr->ntxchains == 1)
1888 r2 |= 1 << 12; /* 1T: disable Tx chain 2 */
1889 if(ctlr->nrxchains == 1)
1890 r2 |= 1 << 15 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */
1891 else if(ctlr->nrxchains == 2)
1892 r2 |= 1 << 4; /* 2R: disable Rx chain 3 */
1894 /* use Tx power values from EEPROM */
1895 txpow1 = ctlr->txpow1[i];
1896 txpow2 = ctlr->txpow2[i];
1899 txpow1 = txpow1 << 1 | 1;
1901 txpow1 = (7 + txpow1) << 1;
1903 txpow2 = txpow2 << 1 | 1;
1905 txpow2 = (7 + txpow2) << 1;
1907 r3 = rfprog[i].r3 | txpow1 << 7;
1908 r4 = rfprog[i].r4 | ctlr->freq << 13 | txpow2 << 4;
1910 rfwrite(ctlr, Rf1, rfprog[i].r1);
1911 rfwrite(ctlr, Rf2, r2);
1912 rfwrite(ctlr, Rf3, r3);
1913 rfwrite(ctlr, Rf4, r4);
1917 rfwrite(ctlr, Rf1, rfprog[i].r1);
1918 rfwrite(ctlr, Rf2, r2);
1919 rfwrite(ctlr, Rf3, r3 | 1);
1920 rfwrite(ctlr, Rf4, r4);
1924 rfwrite(ctlr, Rf1, rfprog[i].r1);
1925 rfwrite(ctlr, Rf2, r2);
1926 rfwrite(ctlr, Rf3, r3);
1927 rfwrite(ctlr, Rf4, r4);
1931 rt3090setchan(Ctlr *ctlr, uint chan)
1933 s8int txpow1, txpow2;
1937 assert(chan >= 1 && chan <= 14); /* RT3090 is 2GHz only */
1939 /* find the settings for this channel (we know it exists) */
1940 for(i = 0; rt2860_rf2850[i].chan != chan; i++);
1942 /* use Tx power values from EEPROM */
1943 txpow1 = ctlr->txpow1[i];
1944 txpow2 = ctlr->txpow2[i];
1946 rt3090rfwrite(ctlr, 2, rt3090_freqs[i].n);
1947 rf = rt3090rfread(ctlr, 3);
1948 rf = (rf & ~0x0f) | rt3090_freqs[i].k;
1949 rt3090rfwrite(ctlr, 3, rf);
1950 rf = rt3090rfread(ctlr, 6);
1951 rf = (rf & ~0x03) | rt3090_freqs[i].r;
1952 rt3090rfwrite(ctlr, 6, rf);
1955 rf = rt3090rfread(ctlr, 12);
1956 rf = (rf & ~0x1f) | txpow1;
1957 rt3090rfwrite(ctlr, 12, rf);
1960 rf = rt3090rfread(ctlr, 13);
1961 rf = (rf & ~0x1f) | txpow2;
1962 rt3090rfwrite(ctlr, 13, rf);
1964 rf = rt3090rfread(ctlr, 1);
1966 if(ctlr->ntxchains == 1)
1967 rf |= Rt3070Tx1Pd | Rt3070Tx2Pd;
1968 else if(ctlr->ntxchains == 2)
1970 if(ctlr->nrxchains == 1)
1971 rf |= Rt3070Rx1Pd | Rt3070Rx2Pd;
1972 else if(ctlr->nrxchains == 2)
1974 rt3090rfwrite(ctlr, 1, rf);
1977 rf = rt3090rfread(ctlr, 23);
1978 rf = (rf & ~0x7f) | ctlr->freq;
1979 rt3090rfwrite(ctlr, 23, rf);
1981 /* program RF filter */
1982 rf = rt3090rfread(ctlr, 24); /* Tx */
1983 rf = (rf & ~0x3f) | ctlr->rf24_20mhz;
1984 rt3090rfwrite(ctlr, 24, rf);
1985 rf = rt3090rfread(ctlr, 31); /* Rx */
1986 rf = (rf & ~0x3f) | ctlr->rf24_20mhz;
1987 rt3090rfwrite(ctlr, 31, rf);
1989 /* enable RF tuning */
1990 rf = rt3090rfread(ctlr, 7);
1991 rt3090rfwrite(ctlr, 7, rf | Rt3070Tune);
1995 rt3090filtercalib(Ctlr *ctlr, u8int init, u8int target, u8int *val)
1998 u8int bbp55_pb, bbp55_sb, delta;
2001 /* program filter */
2002 rf24 = rt3090rfread(ctlr, 24);
2003 rf24 = (rf24 & 0xc0) | init; /* initial filter value */
2004 rt3090rfwrite(ctlr, 24, rf24);
2006 /* enable baseband loopback mode */
2007 rf22 = rt3090rfread(ctlr, 22);
2008 rt3090rfwrite(ctlr, 22, rf22 | Rt3070BbLoopback);
2010 /* set power and frequency of passband test tone */
2011 bbpwrite(ctlr, 24, 0x00);
2012 for(ntries = 0, bbp55_pb = 0; ntries < 100; ntries++){
2013 /* transmit test tone */
2014 bbpwrite(ctlr, 25, 0x90);
2016 /* read received power */
2017 bbp55_pb = bbpread(ctlr, 55);
2024 /* set power and frequency of stopband test tone */
2025 bbpwrite(ctlr, 24, 0x06);
2026 for(ntries = 0; ntries < 100; ntries++){
2027 /* transmit test tone */
2028 bbpwrite(ctlr, 25, 0x90);
2030 /* read received power */
2031 bbp55_sb = bbpread(ctlr, 55);
2033 delta = bbp55_pb - bbp55_sb;
2037 /* reprogram filter */
2039 rt3090rfwrite(ctlr, 24, rf24);
2043 rf24--; /* backtrack */
2045 rt3090rfwrite(ctlr, 24, rf24);
2048 /* restore initial state */
2049 bbpwrite(ctlr, 24, 0x00);
2051 /* disable baseband loopback mode */
2052 rf22 = rt3090rfread(ctlr, 22);
2053 rt3090rfwrite(ctlr, 22, rf22 & ~Rt3070BbLoopback);
2059 rt3090setrxantenna(Ctlr *ctlr, int aux)
2064 tmp = csr32r(ctlr, PciEectrl);
2065 csr32w(ctlr, PciEectrl, tmp & ~EectrlC);
2066 tmp = csr32r(ctlr, GpioCtrl);
2067 csr32w(ctlr, GpioCtrl, (tmp & ~0x0808) | 0x08);
2069 tmp = csr32r(ctlr, PciEectrl);
2070 csr32w(ctlr, PciEectrl, tmp | EectrlC);
2071 tmp = csr32r(ctlr, GpioCtrl);
2072 csr32w(ctlr, GpioCtrl, tmp & ~0x0808);
2077 rt3090rfinit(Ctlr *ctlr)
2083 rf = rt3090rfread(ctlr, 30);
2084 /* toggle RF R30 bit 7 */
2085 rt3090rfwrite(ctlr, 30, rf | 0x80);
2087 rt3090rfwrite(ctlr, 30, rf & ~0x80);
2089 tmp = csr32r(ctlr, Rt3070LdoCfg0);
2091 if(ctlr->patch_dac && ctlr->mac_rev < 0x0211)
2092 tmp |= 0x0d000000; /* 1.35V */
2094 tmp |= 0x01000000; /* 1.2V */
2095 csr32w(ctlr, Rt3070LdoCfg0, tmp);
2097 /* patch LNA_PE_G1 */
2098 tmp = csr32r(ctlr, Rt3070GpioSwitch);
2099 csr32w(ctlr, Rt3070GpioSwitch, tmp & ~0x20);
2101 /* initialize RF registers to default value */
2102 for(i = 0; i < nelem(rt3090_def_rf); i++){
2103 rt3090rfwrite(ctlr, rt3090_def_rf[i].reg,
2104 rt3090_def_rf[i].val);
2107 /* select 20MHz bandwidth */
2108 rt3090rfwrite(ctlr, 31, 0x14);
2110 rf = rt3090rfread(ctlr, 6);
2111 rt3090rfwrite(ctlr, 6, rf | 0x40);
2113 if(ctlr->mac_ver != 0x3593){
2114 /* calibrate filter for 20MHz bandwidth */
2115 ctlr->rf24_20mhz = 0x1f; /* default value */
2116 rt3090filtercalib(ctlr, 0x07, 0x16, &ctlr->rf24_20mhz);
2118 /* select 40MHz bandwidth */
2119 bbp = bbpread(ctlr, 4);
2120 bbpwrite(ctlr, 4, (bbp & ~0x08) | 0x10);
2121 rf = rt3090rfread(ctlr, 31);
2122 rt3090rfwrite(ctlr, 31, rf | 0x20);
2124 /* calibrate filter for 40MHz bandwidth */
2125 ctlr->rf24_40mhz = 0x2f; /* default value */
2126 rt3090filtercalib(ctlr, 0x27, 0x19, &ctlr->rf24_40mhz);
2128 /* go back to 20MHz bandwidth */
2129 bbp = bbpread(ctlr, 4);
2130 bbpwrite(ctlr, 4, bbp & ~0x18);
2132 if(ctlr->mac_rev < 0x0211)
2133 rt3090rfwrite(ctlr, 27, 0x03);
2135 tmp = csr32r(ctlr, Rt3070Opt14);
2136 csr32w(ctlr, Rt3070Opt14, tmp | 1);
2138 if(ctlr->rf_rev == Rf3020)
2139 rt3090setrxantenna(ctlr, 0);
2141 bbp = bbpread(ctlr, 138);
2142 if(ctlr->mac_ver == 0x3593){
2143 if(ctlr->ntxchains == 1)
2144 bbp |= 0x60; /* turn off DAC1 and DAC2 */
2145 else if(ctlr->ntxchains == 2)
2146 bbp |= 0x40; /* turn off DAC2 */
2147 if(ctlr->nrxchains == 1)
2148 bbp &= ~0x06; /* turn off ADC1 and ADC2 */
2149 else if(ctlr->nrxchains == 2)
2150 bbp &= ~0x04; /* turn off ADC2 */
2152 if(ctlr->ntxchains == 1)
2153 bbp |= 0x20; /* turn off DAC1 */
2154 if(ctlr->nrxchains == 1)
2155 bbp &= ~0x02; /* turn off ADC1 */
2157 bbpwrite(ctlr, 138, bbp);
2159 rf = rt3090rfread(ctlr, 1);
2160 rf &= ~(Rt3070Rx0Pd | Rt3070Tx0Pd);
2161 rf |= Rt3070RfBlock | Rt3070Rx1Pd | Rt3070Tx1Pd;
2162 rt3090rfwrite(ctlr, 1, rf);
2164 rf = rt3090rfread(ctlr, 15);
2165 rt3090rfwrite(ctlr, 15, rf & ~Rt3070TxLo2);
2167 rf = rt3090rfread(ctlr, 17);
2169 if(ctlr->mac_rev >= 0x0211 && !ctlr->ext_2ghz_lna)
2170 rf |= 0x20; /* fix for long range Rx issue */
2171 if(ctlr->txmixgain_2ghz >= 2)
2172 rf = (rf & ~0x7) | ctlr->txmixgain_2ghz;
2173 rt3090rfwrite(ctlr, 17, rf);
2175 rf = rt3090rfread(ctlr, 20);
2176 rt3090rfwrite(ctlr, 20, rf & ~Rt3070RxLo1);
2178 rf = rt3090rfread(ctlr, 21);
2179 rt3090rfwrite(ctlr, 21, rf & ~Rt3070RxLo2);
2185 rt3090rfwakeup(Ctlr *ctlr)
2190 if(ctlr->mac_ver == 0x3593){
2192 rf = rt3090rfread(ctlr, 1);
2193 rt3090rfwrite(ctlr, 1, rf | Rt3593Vco);
2195 /* initiate VCO calibration */
2196 rf = rt3090rfread(ctlr, 3);
2197 rt3090rfwrite(ctlr, 3, rf | Rt3593Vcocal);
2199 /* enable VCO bias current control */
2200 rf = rt3090rfread(ctlr, 6);
2201 rt3090rfwrite(ctlr, 6, rf | Rt3593VcoIc);
2203 /* initiate res calibration */
2204 rf = rt3090rfread(ctlr, 2);
2205 rt3090rfwrite(ctlr, 2, rf | Rt3593Rescal);
2207 /* set reference current control to 0.33 mA */
2208 rf = rt3090rfread(ctlr, 22);
2209 rf &= ~Rt3593CpIcMask;
2210 rf |= 1 << Rt3593CpIcShift;
2211 rt3090rfwrite(ctlr, 22, rf);
2214 rf = rt3090rfread(ctlr, 46);
2215 rt3090rfwrite(ctlr, 46, rf | Rt3593RxCtb);
2217 rf = rt3090rfread(ctlr, 20);
2218 rf &= ~(Rt3593LdoRfVcMask | Rt3593LdoPllVcMask);
2219 rt3090rfwrite(ctlr, 20, rf);
2221 /* enable RF block */
2222 rf = rt3090rfread(ctlr, 1);
2223 rt3090rfwrite(ctlr, 1, rf | Rt3070RfBlock);
2225 /* enable VCO bias current control */
2226 rf = rt3090rfread(ctlr, 7);
2227 rt3090rfwrite(ctlr, 7, rf | 0x30);
2229 rf = rt3090rfread(ctlr, 9);
2230 rt3090rfwrite(ctlr, 9, rf | 0x0e);
2233 rf = rt3090rfread(ctlr, 21);
2234 rt3090rfwrite(ctlr, 21, rf | Rt3070RxCtb);
2236 /* fix Tx to Rx IQ glitch by raising RF voltage */
2237 rf = rt3090rfread(ctlr, 27);
2239 if(ctlr->mac_rev < 0x0211)
2241 rt3090rfwrite(ctlr, 27, rf);
2243 if(ctlr->patch_dac && ctlr->mac_rev < 0x0211){
2244 tmp = csr32r(ctlr, Rt3070LdoCfg0);
2245 tmp = (tmp & ~0x1f000000) | 0x0d000000;
2246 csr32w(ctlr, Rt3070LdoCfg0, tmp);
2251 rt3090rfsetup(Ctlr *ctlr)
2256 if(ctlr->mac_rev >= 0x0211){
2257 /* enable DC filter */
2258 bbpwrite(ctlr, 103, 0xc0);
2260 /* improve power consumption */
2261 bbp = bbpread(ctlr, 31);
2262 bbpwrite(ctlr, 31, bbp & ~0x03);
2265 csr32w(ctlr, TxSwCfg1, 0);
2266 if(ctlr->mac_rev < 0x0211){
2267 csr32w(ctlr, TxSwCfg2,
2268 ctlr->patch_dac ? 0x2c : 0x0f);
2270 csr32w(ctlr, TxSwCfg2, 0);
2272 /* initialize RF registers from ROM */
2273 for(i = 0; i < 10; i++){
2274 if(ctlr->rf[i].reg == 0 || ctlr->rf[i].reg == 0xff)
2276 rt3090rfwrite(ctlr, ctlr->rf[i].reg, ctlr->rf[i].val);
2281 updateprot(Ctlr *ctlr)
2285 tmp = RtsthEn | ProtNavShort | TxopAllowAll;
2286 /* setup protection frame rate (MCS code) */
2287 tmp |= /*(ic->ic_curmode == IEEE80211_MODE_11A) ?
2288 rt2860_rates[RT2860_RIDX_OFDM6].mcs :*/
2289 rt2860_rates[RidxCck11].mcs;
2291 /* CCK frames don't require protection */
2292 csr32w(ctlr, CckProtCfg, tmp);
2294 if(ic->ic_flags & IEEE80211_F_USEPROT){
2295 if(ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2296 tmp |= ProtCtrlRtsCts;
2297 else if(ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2300 csr32w(ctlr, OfdmProtCfg, tmp); */
2304 rt2860start(Ether *edev)
2308 int i, qid, ridx, ntries;
2313 csr32w(ctlr, PwrPinCfg, IoRaPe);
2316 tmp = csr32r(ctlr, WpdmaGloCfg);
2318 csr32w(ctlr, WpdmaGloCfg, tmp);
2320 /* PBF hardware reset */
2321 csr32w(ctlr, SysCtrl, 0xe1f);
2323 csr32w(ctlr, SysCtrl, 0xe00);
2325 if((err = boot(ctlr)) != nil){
2326 /*XXX: rt2860stop(ifp, 1);*/
2329 /* set MAC address */
2330 csr32w(ctlr, MacAddrDw0,
2331 edev->ea[0] | edev->ea[1] << 8 | edev->ea[2] << 16 | edev->ea[3] << 24);
2332 csr32w(ctlr, MacAddrDw1,
2333 edev->ea[4] | edev->ea[5] << 8 | 0xff << 16);
2335 /* init Tx power for all Tx rates (from EEPROM) */
2336 for(ridx = 0; ridx < 5; ridx++){
2337 if(ctlr->txpow20mhz[ridx] == 0xffffffff)
2339 csr32w(ctlr, TxPwrCfg(ridx), ctlr->txpow20mhz[ridx]);
2342 for(ntries = 0; ntries < 100; ntries++){
2343 tmp = csr32r(ctlr, WpdmaGloCfg);
2344 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
2349 err = "timeout waiting for DMA engine";
2350 /*rt2860_stop(ifp, 1);*/
2354 csr32w(ctlr, WpdmaGloCfg, tmp);
2356 /* reset Rx ring and all 6 Tx rings */
2357 csr32w(ctlr, WpdmaRstIdx, 0x1003f);
2359 /* PBF hardware reset */
2360 csr32w(ctlr, SysCtrl, 0xe1f);
2362 csr32w(ctlr, SysCtrl, 0xe00);
2364 csr32w(ctlr, PwrPinCfg, IoRaPe | IoRfPe);
2366 csr32w(ctlr, MacSysCtrl, BbpHrst | MacSrst);
2368 csr32w(ctlr, MacSysCtrl, 0);
2370 for(i = 0; i < nelem(rt2860_def_mac); i++)
2371 csr32w(ctlr, rt2860_def_mac[i].reg, rt2860_def_mac[i].val);
2372 if(ctlr->mac_ver >= 0x3071){
2373 /* set delay of PA_PE assertion to 1us (unit of 0.25us) */
2374 csr32w(ctlr, TxSwCfg0,
2375 4 << DlyPapeEnShift);
2378 if(!(csr32r(ctlr, PciCfg) & PciCfgPci)){
2379 ctlr->flags |= ConnPciE;
2380 /* PCIe has different clock cycle count than PCI */
2381 tmp = csr32r(ctlr, UsCycCnt);
2382 tmp = (tmp & ~0xff) | 0x7d;
2383 csr32w(ctlr, UsCycCnt, tmp);
2386 /* wait while MAC is busy */
2387 for(ntries = 0; ntries < 100; ntries++){
2388 if(!(csr32r(ctlr, MacStatusReg) &
2389 (RxStatusBusy | TxStatusBusy)))
2394 err = "timeout waiting for MAC";
2395 /*rt2860_stop(ifp, 1);*/
2399 /* clear Host to MCU mailbox */
2400 csr32w(ctlr, H2mBbpagent, 0);
2401 csr32w(ctlr, H2mMailbox, 0);
2403 mcucmd(ctlr, McuCmdRfreset, 0, 0);
2406 if((err = bbpinit(ctlr)) != nil){
2407 /*rt2860_stop(ifp, 1);*/
2410 /* clear RX WCID search table */
2411 setregion(ctlr, WcidEntry(0), 0, 512);
2412 /* clear pairwise key table */
2413 setregion(ctlr, Pkey(0), 0, 2048);
2414 /* clear IV/EIV table */
2415 setregion(ctlr, Iveiv(0), 0, 512);
2416 /* clear WCID attribute table */
2417 setregion(ctlr, WcidAttr(0), 0, 256);
2418 /* clear shared key table */
2419 setregion(ctlr, Skey(0, 0), 0, 8 * 32);
2420 /* clear shared key mode */
2421 setregion(ctlr, SkeyMode07, 0, 4);
2423 /* init Tx rings (4 EDCAs + HCCA + Mgt) */
2424 for(qid = 0; qid < 6; qid++){
2425 csr32w(ctlr, TxBasePtr(qid), PCIWADDR(ctlr->tx[qid].d));
2426 csr32w(ctlr, TxMaxCnt(qid), Ntx);
2427 csr32w(ctlr, TxCtxIdx(qid), 0);
2431 csr32w(ctlr, RxBasePtr, PCIWADDR(ctlr->rx.p));
2432 csr32w(ctlr, RxMaxCnt, Nrx);
2433 csr32w(ctlr, RxCalcIdx, Nrx - 1);
2435 /* setup maximum buffer sizes */
2436 csr32w(ctlr, MaxLenCfg, 1 << 12 |
2437 (Rbufsize - Rxwisize - 2));
2439 for(ntries = 0; ntries < 100; ntries++){
2440 tmp = csr32r(ctlr, WpdmaGloCfg);
2441 if((tmp & (TxDmaBusy | RxDmaBusy)) == 0)
2446 err = "timeout waiting for DMA engine";
2447 /*rt2860_stop(ifp, 1);*/
2451 csr32w(ctlr, WpdmaGloCfg, tmp);
2453 /* disable interrupts mitigation */
2454 csr32w(ctlr, DelayIntCfg, 0);
2456 /* write vendor-specific BBP values (from EEPROM) */
2457 for(i = 0; i < 8; i++){
2458 if(ctlr->bbp[i].reg == 0 || ctlr->bbp[i].reg == 0xff)
2460 bbpwrite(ctlr, ctlr->bbp[i].reg, ctlr->bbp[i].val);
2463 /* select Main antenna for 1T1R devices */
2464 if(ctlr->rf_rev == Rf2020 ||
2465 ctlr->rf_rev == Rf3020 ||
2466 ctlr->rf_rev == Rf3320)
2467 rt3090setrxantenna(ctlr, 0);
2469 /* send LEDs operating mode to microcontroller */
2470 mcucmd(ctlr, McuCmdLed1, ctlr->led[0], 0);
2471 mcucmd(ctlr, McuCmdLed2, ctlr->led[1], 0);
2472 mcucmd(ctlr, McuCmdLed3, ctlr->led[2], 0);
2474 if(ctlr->mac_ver >= 0x3071)
2477 mcucmd(ctlr, McuCmdSleep, 0x02ff, 1);
2478 mcucmd(ctlr, McuCmdWakeup, 0, 1);
2480 if(ctlr->mac_ver >= 0x3071)
2481 rt3090rfwakeup(ctlr);
2483 /* disable non-existing Rx chains */
2484 bbp3 = bbpread(ctlr, 3);
2485 bbp3 &= ~(1 << 3 | 1 << 4);
2486 if(ctlr->nrxchains == 2)
2488 else if(ctlr->nrxchains == 3)
2490 bbpwrite(ctlr, 3, bbp3);
2492 /* disable non-existing Tx chains */
2493 bbp1 = bbpread(ctlr, 1);
2494 if(ctlr->ntxchains == 1)
2495 bbp1 = (bbp1 & ~(1 << 3 | 1 << 4));
2496 else if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains == 2)
2497 bbp1 = (bbp1 & ~(1 << 4)) | 1 << 3;
2498 else if(ctlr->mac_ver == 0x3593 && ctlr->ntxchains == 3)
2499 bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4;
2500 bbpwrite(ctlr, 1, bbp1);
2502 if(ctlr->mac_ver >= 0x3071)
2503 rt3090rfsetup(ctlr);
2505 /* select default channel */
2506 if(ctlr->mac_ver >= 0x3071)
2507 rt3090setchan(ctlr, 3);
2511 /* reset RF from MCU */
2512 mcucmd(ctlr, McuCmdRfreset, 0, 0);
2514 /* set RTS threshold */
2515 tmp = csr32r(ctlr, TxRtsCfg);
2517 tmp |= 1 /* ic->ic_rtsthreshold */ << 8;
2518 csr32w(ctlr, TxRtsCfg, tmp);
2520 /* setup initial protection mode */
2523 /* turn radio LED on */
2524 setleds(ctlr, LedRadio);
2526 /* enable Tx/Rx DMA engine */
2527 if((err = txrxon(ctlr)) != 0){
2528 /*rt2860_stop(ifp, 1);*/
2532 /* clear pending interrupts */
2533 csr32w(ctlr, IntStatus, 0xffffffff);
2534 /* enable interrupts */
2535 csr32w(ctlr, IntMask, 0x3fffc);
2537 if(ctlr->flags & AdvancedPs)
2538 mcucmd(ctlr, McuCmdPslevel, ctlr->pslevel, 0);
2543 * Add `delta' (signed) to each 4-bit sub-word of a 32-bit word.
2544 * Used to adjust per-rate Tx power registers.
2547 b4inc(u32int b32, s8int delta)
2551 for(i = 0; i < 8; i++){
2558 b32 = b32 >> 4 | b4 << 28;
2564 transmit(Wifi *wifi, Wnode *wn, Block *b)
2570 int ridx, /*ctl_ridx,*/ hdrlen;
2581 if(ctlr->attached == 0 || ctlr->broken){
2586 if((wn->channel != ctlr->channel)
2587 || (!ctlr->prom && (wn->aid != ctlr->aid || memcmp(wn->bssid, ctlr->bssid, Eaddrlen) != 0)))
2591 /* association note has no data to transmit */
2597 qid = 0; /* for now */
2599 tx = &ctlr->tx[qid];
2601 nodeid = ctlr->bcastnodeid;
2602 w = (Wifipkt*)b->rp;
2603 hdrlen = wifihdrlen(w);
2605 p = pool->p + pool->i * TxwiDmaSz;
2606 if((w->a1[0] & 1) == 0){
2607 *(p+4) = TxAck; /* xflags */
2610 *(p+1) = TxTxopBackoff; /* txop */
2612 if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
2613 nodeid = ctlr->bssnodeid;
2614 ridx = 2; /* BUG: hardcode 11Mbit */
2618 /*ctl_ridx = rt2860_rates[ridx].ctl_ridx;*/
2619 mcs = rt2860_rates[ridx].mcs;
2621 /* setup TX Wireless Information */
2623 *(p+2) = PhyCck | mcs; /* phy */
2624 /* let HW generate seq numbers */
2625 *(p+4) |= TxNseq; /* xflags */
2626 put16(p + 6, BLEN(b) | (((mcs+1) & 0xf) << TxPidShift) ); /* length */
2628 /* put16((uchar*)&w->dur[0], rt2860_rates[ctl_ridx].lp_ack_dur); */
2630 *(p+5) = nodeid; /* wcid */
2632 /* copy packet header */
2633 memmove(p + Txwisize, b->rp, hdrlen);
2635 /* setup tx descriptor */
2636 /* first segment is TXWI + 802.11 header */
2637 p = (uchar*)tx->d + Tdscsize * tx->i;
2638 put32(p, PCIWADDR(pool->p + pool->i * TxwiDmaSz)); /* sdp0 */
2639 put16(p + 6, Txwisize + hdrlen); /* sdl0 */
2640 *(p + 15) = TxQselEdca; /* flags */
2642 /* allocate output buffer */
2644 tx->b[tx->i] = outb = iallocb(BLEN(b) + 256);
2646 print("outb = nil\n");
2649 outb->rp = (uchar*)ROUND((uintptr)outb->base, 256);
2650 memset(outb->rp, 0, BLEN(b));
2651 memmove(outb->rp, b->rp, BLEN(b));
2652 outb->wp = outb->rp + BLEN(b);
2655 /* setup payload segments */
2656 put32(p + 8, PCIWADDR(outb->rp)); /* sdp1 */
2657 put16(p + 4, BLEN(outb) | TxLs1); /* sdl1 */
2659 p = pool->p + pool->i * TxwiDmaSz;
2660 w = (Wifipkt*)(p + Txwisize);
2661 if(ctlr->wifi->debug){
2662 print("transmit: %E->%E,%E nodeid=%x txq[%d]=%d size=%zd\n", w->a2, w->a1, w->a3, nodeid, qid, ctlr->tx[qid].i, BLEN(outb));
2665 tx->i = (tx->i + 1) % Ntx;
2666 pool->i = (pool->i + 1) % Ntxpool;
2671 csr32w(ctlr, TxCtxIdx(qid), ctlr->tx[qid].i);
2678 rt2860attach(Ether *edev)
2687 print("#l%d: %s\n", edev->ctlrno, up->errstr);
2693 if(ctlr->attached == 0){
2694 if(ctlr->wifi == nil)
2695 ctlr->wifi = wifiattach(edev, transmit);
2697 if(ctlr->fw == nil){
2698 fw = readfirmware();
2701 if((err = rt2860start(edev)) != nil){
2705 ctlr->bcastnodeid = -1;
2706 ctlr->bssnodeid = -1;
2728 print("rx->b == nil!");
2731 hw = csr32r(ctlr, FsDrxIdx) & 0xfff;
2739 p = (uchar*)rx->p + Rdscsize * rx->i;
2740 sdl0 = get16(p + 4 /* sdp0 */ + 2 /* sdl1 */);
2741 if(!(sdl0 & RxDdone)){
2742 print("rxd ddone bit not set\n");
2743 break; /* should not happen */
2745 flags = get32(p + 12);
2746 if(flags & (RxCrcerr | RxIcverr)){
2747 /* print("crc | icv err\n"); */
2757 if(ctlr->wifi == nil)
2759 if(rbplant(ctlr, rx->i) < 0){
2760 print("can't plant");
2763 ctlr->wcid = *b->rp;
2764 len = get16(b->rp + 2 /* wcid, keyidx */) & 0xfff;
2765 b->rp = d + Rxwisize;
2766 b->wp = b->rp + len;
2767 w = (Wifipkt*)b->rp;
2768 hdrlen = wifihdrlen(w);
2769 /* HW may insert 2 padding bytes after 802.11 header */
2770 if(flags & RxL2pad){
2771 memmove(b->rp + 2, b->rp, hdrlen);
2774 w = (Wifipkt*)b->rp;
2775 if(ctlr->wifi->debug)
2776 print("receive: %E->%E,%E wcid 0x%x \n", w->a2, w->a1, w->a3, ctlr->wcid);
2777 wifiiq(ctlr->wifi, b);
2779 put16(p + 4 /* sdp0 */ + 2 /* sdl1 */, sdl0 & ~RxDdone);
2780 rx->i = (rx->i + 1) % Nrx;
2783 /* tell HW what we have processed */
2784 csr32w(ctlr, RxCalcIdx, (rx->i - 1) % Nrx);
2793 while((stat = csr32r(ctlr, TxStatFifo)) & TxqVld){
2794 wcid = (stat >> TxqWcidShift) & 0xff;
2795 /* if no ACK was requested, no feedback is available */
2796 if(!(stat & TxqAckreq) || wcid == 0xff){
2803 rt2860tx(Ctlr *ctlr, u8int q)
2810 hw = csr32r(ctlr, TxDtxIdx(q));
2812 uchar *p = (uchar*)tx->d + Rdscsize * tx->n;
2816 freeb(tx->b[tx->n]);
2819 sdl0 = get16(p + 4 /* sdp0 */ + 2 /* sdl1 */);
2820 if(!(sdl0 & TxDdone)){
2821 print("txd ddone bit not set\n");
2822 break; /* should not happen */
2824 memset((uchar*)ctlr->pool.p + TxwiDmaSz * tx->n, 0, TxwiDmaSz);
2825 memset((uchar*)tx->d + Tdscsize * tx->n, 0, Tdscsize);
2826 // put16(p + 4 /* sdp0 */ + 2 /* sdl1 */, sdl0 & ~TxDdone);
2827 tx->n = (tx->n + 1) % Ntx;
2833 rt2860interrupt(Ureg*, void *arg)
2844 debug = ctlr->wifi->debug;
2846 r = csr32r(ctlr, IntStatus);
2847 if(r == 0xffffffff){
2856 /* acknowledge interrupts */
2857 csr32w(ctlr, IntStatus, r);
2859 if(r & TxRxCoherent){
2861 /* DMA finds data coherent event when checking the DDONE bit */
2863 print("txrx coherent intr\n");
2865 /* restart DMA engine */
2866 tmp = csr32r(ctlr, WpdmaGloCfg);
2867 tmp &= ~(TxWbDdone | RxDmaEn | TxDmaEn);
2868 csr32w(ctlr, WpdmaGloCfg, tmp);
2900 eepromctl(Ctlr *ctlr, u32int val)
2902 csr32w(ctlr, PciEectrl, val);
2904 microdelay(EepromDelay);
2908 * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46,
2912 eeread2(Ctlr *ctlr, u16int addr)
2918 /* clock C once before the first command */
2921 eepromctl(ctlr, EectrlS);
2922 eepromctl(ctlr, EectrlS | EectrlC);
2923 eepromctl(ctlr, EectrlS);
2925 /* write start bit (1) */
2926 eepromctl(ctlr, EectrlS | EectrlD);
2927 eepromctl(ctlr, EectrlS | EectrlD | EectrlC);
2929 /* write READ opcode (10) */
2930 eepromctl(ctlr, EectrlS | EectrlD);
2931 eepromctl(ctlr, EectrlS | EectrlD | EectrlC);
2932 eepromctl(ctlr, EectrlS);
2933 eepromctl(ctlr, EectrlS | EectrlC);
2935 /* write address (A5-A0 or A7-A0) */
2936 n = ((csr32r(ctlr, PciEectrl) & 0x30) == 0) ? 5 : 7;
2938 eepromctl(ctlr, EectrlS |
2939 (((addr >> n) & 1) << EectrlShiftD));
2940 eepromctl(ctlr, EectrlS |
2941 (((addr >> n) & 1) << EectrlShiftD) | EectrlC);
2944 eepromctl(ctlr, EectrlS);
2946 /* read data Q15-Q0 */
2948 for(n = 15; n >= 0; n--){
2949 eepromctl(ctlr, EectrlS | EectrlC);
2950 tmp = csr32r(ctlr, PciEectrl);
2951 val |= ((tmp & EectrlQ) >> EectrlShiftQ) << n;
2952 eepromctl(ctlr, EectrlS);
2957 /* clear Chip Select and clock C */
2958 eepromctl(ctlr, EectrlS);
2960 eepromctl(ctlr, EectrlC);
2965 /* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
2967 efuseread2(Ctlr *ctlr, u16int addr)
2975 * Read one 16-byte block into registers EFUSE_DATA[0-3]:
2981 tmp = csr32r(ctlr, Rt3070EfuseCtrl);
2982 tmp &= ~(Rt3070EfsromModeMask | Rt3070EfsromAinMask);
2983 tmp |= (addr & ~0xf) << Rt3070EfsromAinShift | Rt3070EfsromKick;
2984 csr32w(ctlr, Rt3070EfuseCtrl, tmp);
2985 for(ntries = 0; ntries < 500; ntries++){
2986 tmp = csr32r(ctlr, Rt3070EfuseCtrl);
2987 if(!(tmp & Rt3070EfsromKick))
2994 if((tmp & Rt3070EfuseAoutMask) == Rt3070EfuseAoutMask)
2995 return 0xffff; /* address not found */
2997 /* determine to which 32-bit register our 16-bit word belongs */
2998 reg = Rt3070EfuseData3 - (addr & 0xc);
2999 tmp = csr32r(ctlr, reg);
3001 return (addr & 2) ? tmp >> 16 : tmp & 0xffff;
3005 eepromread(Ether *edev)
3007 s8int delta_2ghz, delta_5ghz;
3011 u16int (*rom_read)(Ctlr*, u16int);
3014 enum { DefLna = 10 };
3017 /* check whether the ROM is eFUSE ROM or EEPROM */
3019 if(ctlr->mac_ver >= 0x3071){
3020 tmp = csr32r(ctlr, Rt3070EfuseCtrl);
3021 if(tmp & Rt3070SelEfuse)
3022 rom_read = efuseread2;
3025 /* read MAC address */
3026 val = rom_read(ctlr, EepromMac01);
3027 edev->ea[0] = val & 0xff;
3028 edev->ea[1] = val >> 8;
3029 val = rom_read(ctlr, EepromMac23);
3030 edev->ea[2] = val & 0xff;
3031 edev->ea[3] = val >> 8;
3032 val = rom_read(ctlr, EepromMac45);
3033 edev->ea[4] = val & 0xff;
3034 edev->ea[5] = val >> 8;
3036 /* read vendor BBP settings */
3037 for(i = 0; i < 8; i++){
3038 val = rom_read(ctlr, EepromBbpBase + i);
3039 ctlr->bbp[i].val = val & 0xff;
3040 ctlr->bbp[i].reg = val >> 8;
3043 if(ctlr->mac_ver >= 0x3071){
3044 /* read vendor RF settings */
3045 for(i = 0; i < 10; i++){
3046 val = rom_read(ctlr, Rt3071EepromRfBase + i);
3047 ctlr->rf[i].val = val & 0xff;
3048 ctlr->rf[i].reg = val >> 8;
3052 /* read RF frequency offset from EEPROM */
3053 val = rom_read(ctlr, EepromFreqLeds);
3054 ctlr->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0;
3055 if((val >> 8) != 0xff){
3056 /* read LEDs operating mode */
3057 ctlr->leds = val >> 8;
3058 ctlr->led[0] = rom_read(ctlr, EepromLed1);
3059 ctlr->led[1] = rom_read(ctlr, EepromLed2);
3060 ctlr->led[2] = rom_read(ctlr, EepromLed3);
3062 /* broken EEPROM, use default settings */
3064 ctlr->led[0] = 0x5555;
3065 ctlr->led[1] = 0x2221;
3066 ctlr->led[2] = 0xa9f8;
3068 /* read RF information */
3069 val = rom_read(ctlr, EepromAntenna);
3071 if(ctlr->mac_ver == 0x3593){
3072 /* default to RF3053 3T3R */
3073 ctlr->rf_rev = Rf3053;
3074 ctlr->ntxchains = 3;
3075 ctlr->nrxchains = 3;
3076 }else if(ctlr->mac_ver >= 0x3071){
3077 /* default to RF3020 1T1R */
3078 ctlr->rf_rev = Rf3020;
3079 ctlr->ntxchains = 1;
3080 ctlr->nrxchains = 1;
3082 /* default to RF2820 1T2R */
3083 ctlr->rf_rev = Rf2820;
3084 ctlr->ntxchains = 1;
3085 ctlr->nrxchains = 2;
3088 ctlr->rf_rev = (val >> 8) & 0xf;
3089 ctlr->ntxchains = (val >> 4) & 0xf;
3090 ctlr->nrxchains = val & 0xf;
3093 /* check if RF supports automatic Tx access gain control */
3094 val = rom_read(ctlr, EepromConfig);
3095 /* check if driver should patch the DAC issue */
3096 if((val >> 8) != 0xff)
3097 ctlr->patch_dac = (val >> 15) & 1;
3098 if((val & 0xff) != 0xff){
3099 ctlr->ext_5ghz_lna = (val >> 3) & 1;
3100 ctlr->ext_2ghz_lna = (val >> 2) & 1;
3101 /* check if RF supports automatic Tx access gain control */
3102 ctlr->calib_2ghz = ctlr->calib_5ghz = 0; /* XXX (val >> 1) & 1 */;
3103 /* check if we have a hardware radio switch */
3104 ctlr->rfswitch = val & 1;
3106 if(ctlr->flags & AdvancedPs){
3107 /* read PCIe power save level */
3108 val = rom_read(ctlr, EepromPciePslevel);
3109 if((val & 0xff) != 0xff){
3110 ctlr->pslevel = val & 0x3;
3111 val = rom_read(ctlr, EepromRev);
3112 if((val & 0xff80) != 0x9280)
3113 ctlr->pslevel = MIN(ctlr->pslevel, 1);
3117 /* read power settings for 2GHz channels */
3118 for(i = 0; i < 14; i += 2){
3119 val = rom_read(ctlr,
3120 EepromPwr2ghzBase1 + i / 2);
3121 ctlr->txpow1[i + 0] = (s8int)(val & 0xff);
3122 ctlr->txpow1[i + 1] = (s8int)(val >> 8);
3124 val = rom_read(ctlr,
3125 EepromPwr2ghzBase2 + i / 2);
3126 ctlr->txpow2[i + 0] = (s8int)(val & 0xff);
3127 ctlr->txpow2[i + 1] = (s8int)(val >> 8);
3129 /* fix broken Tx power entries */
3131 for(i = 0; i < 14; i++){
3132 if(ctlr->txpow1[i] < 0 || ctlr->txpow1[i] > 31)
3133 ctlr->txpow1[i] = 5;
3134 if(ctlr->txpow2[i] < 0 || ctlr->txpow2[i] > 31)
3135 ctlr->txpow2[i] = 5;
3137 /* read power settings for 5GHz channels */
3138 for(i = 0; i < 40; i += 2){
3139 val = rom_read(ctlr,
3140 EepromPwr5ghzBase1 + i / 2);
3141 ctlr->txpow1[i + 14] = (s8int)(val & 0xff);
3142 ctlr->txpow1[i + 15] = (s8int)(val >> 8);
3144 val = rom_read(ctlr,
3145 EepromPwr5ghzBase2 + i / 2);
3146 ctlr->txpow2[i + 14] = (s8int)(val & 0xff);
3147 ctlr->txpow2[i + 15] = (s8int)(val >> 8);
3150 /* fix broken Tx power entries */
3151 for(i = 0; i < 40; i++){
3152 if(ctlr->txpow1[14 + i] < -7 || ctlr->txpow1[14 + i] > 15)
3153 ctlr->txpow1[14 + i] = 5;
3154 if(ctlr->txpow2[14 + i] < -7 || ctlr->txpow2[14 + i] > 15)
3155 ctlr->txpow2[14 + i] = 5;
3158 /* read Tx power compensation for each Tx rate */
3159 val = rom_read(ctlr, EepromDeltapwr);
3160 delta_2ghz = delta_5ghz = 0;
3161 if((val & 0xff) != 0xff && (val & 0x80)){
3162 delta_2ghz = val & 0xf;
3163 if(!(val & 0x40)) /* negative number */
3164 delta_2ghz = -delta_2ghz;
3167 if((val & 0xff) != 0xff && (val & 0x80)){
3168 delta_5ghz = val & 0xf;
3169 if(!(val & 0x40)) /* negative number */
3170 delta_5ghz = -delta_5ghz;
3173 for(ridx = 0; ridx < 5; ridx++){
3176 val = rom_read(ctlr, EepromRpwr + ridx * 2);
3178 val = rom_read(ctlr, EepromRpwr + ridx * 2 + 1);
3179 reg |= (u32int)val << 16;
3181 ctlr->txpow20mhz[ridx] = reg;
3182 ctlr->txpow40mhz_2ghz[ridx] = b4inc(reg, delta_2ghz);
3183 ctlr->txpow40mhz_5ghz[ridx] = b4inc(reg, delta_5ghz);
3186 /* read factory-calibrated samples for temperature compensation */
3187 val = rom_read(ctlr, EepromTssi12ghz);
3188 ctlr->tssi_2ghz[0] = val & 0xff; /* [-4] */
3189 ctlr->tssi_2ghz[1] = val >> 8; /* [-3] */
3190 val = rom_read(ctlr, EepromTssi22ghz);
3191 ctlr->tssi_2ghz[2] = val & 0xff; /* [-2] */
3192 ctlr->tssi_2ghz[3] = val >> 8; /* [-1] */
3193 val = rom_read(ctlr, EepromTssi32ghz);
3194 ctlr->tssi_2ghz[4] = val & 0xff; /* [+0] */
3195 ctlr->tssi_2ghz[5] = val >> 8; /* [+1] */
3196 val = rom_read(ctlr, EepromTssi42ghz);
3197 ctlr->tssi_2ghz[6] = val & 0xff; /* [+2] */
3198 ctlr->tssi_2ghz[7] = val >> 8; /* [+3] */
3199 val = rom_read(ctlr, EepromTssi52ghz);
3200 ctlr->tssi_2ghz[8] = val & 0xff; /* [+4] */
3201 ctlr->step_2ghz = val >> 8;
3202 /* check that ref value is correct, otherwise disable calibration */
3203 if(ctlr->tssi_2ghz[4] == 0xff)
3204 ctlr->calib_2ghz = 0;
3206 val = rom_read(ctlr, EepromTssi15ghz);
3207 ctlr->tssi_5ghz[0] = val & 0xff; /* [-4] */
3208 ctlr->tssi_5ghz[1] = val >> 8; /* [-3] */
3209 val = rom_read(ctlr, EepromTssi25ghz);
3210 ctlr->tssi_5ghz[2] = val & 0xff; /* [-2] */
3211 ctlr->tssi_5ghz[3] = val >> 8; /* [-1] */
3212 val = rom_read(ctlr, EepromTssi35ghz);
3213 ctlr->tssi_5ghz[4] = val & 0xff; /* [+0] */
3214 ctlr->tssi_5ghz[5] = val >> 8; /* [+1] */
3215 val = rom_read(ctlr, EepromTssi45ghz);
3216 ctlr->tssi_5ghz[6] = val & 0xff; /* [+2] */
3217 ctlr->tssi_5ghz[7] = val >> 8; /* [+3] */
3218 val = rom_read(ctlr, EepromTssi55ghz);
3219 ctlr->tssi_5ghz[8] = val & 0xff; /* [+4] */
3220 ctlr->step_5ghz = val >> 8;
3221 /* check that ref value is correct, otherwise disable calibration */
3222 if(ctlr->tssi_5ghz[4] == 0xff)
3223 ctlr->calib_5ghz = 0;
3225 /* read RSSI offsets and LNA gains from EEPROM */
3226 val = rom_read(ctlr, EepromRssi12ghz);
3227 ctlr->rssi_2ghz[0] = val & 0xff; /* Ant A */
3228 ctlr->rssi_2ghz[1] = val >> 8; /* Ant B */
3229 val = rom_read(ctlr, EepromRssi22ghz);
3230 if(ctlr->mac_ver >= 0x3071){
3232 * On RT3090 chips (limited to 2 Rx chains), this ROM
3233 * field contains the Tx mixer gain for the 2GHz band.
3235 if((val & 0xff) != 0xff)
3236 ctlr->txmixgain_2ghz = val & 0x7;
3238 ctlr->rssi_2ghz[2] = val & 0xff; /* Ant C */
3239 ctlr->lna[2] = val >> 8; /* channel group 2 */
3241 val = rom_read(ctlr, EepromRssi15ghz);
3242 ctlr->rssi_5ghz[0] = val & 0xff; /* Ant A */
3243 ctlr->rssi_5ghz[1] = val >> 8; /* Ant B */
3244 val = rom_read(ctlr, EepromRssi25ghz);
3245 ctlr->rssi_5ghz[2] = val & 0xff; /* Ant C */
3246 ctlr->lna[3] = val >> 8; /* channel group 3 */
3248 val = rom_read(ctlr, EepromLna);
3249 if(ctlr->mac_ver >= 0x3071)
3250 ctlr->lna[0] = DefLna;
3251 else /* channel group 0 */
3252 ctlr->lna[0] = val & 0xff;
3253 ctlr->lna[1] = val >> 8; /* channel group 1 */
3255 /* fix broken 5GHz LNA entries */
3256 if(ctlr->lna[2] == 0 || ctlr->lna[2] == 0xff){
3257 ctlr->lna[2] = ctlr->lna[1];
3259 if(ctlr->lna[3] == 0 || ctlr->lna[3] == 0xff){
3260 ctlr->lna[3] = ctlr->lna[1];
3263 /* fix broken RSSI offset entries */
3264 for(ant = 0; ant < 3; ant++){
3265 if(ctlr->rssi_2ghz[ant] < -10 || ctlr->rssi_2ghz[ant] > 10){
3266 ctlr->rssi_2ghz[ant] = 0;
3268 if(ctlr->rssi_5ghz[ant] < -10 || ctlr->rssi_5ghz[ant] > 10){
3269 ctlr->rssi_5ghz[ant] = 0;
3277 getrfname(u8int rev)
3279 if((rev == 0) || (rev >= nelem(rfnames)))
3281 if(rfnames[rev][0] == '\0')
3283 return rfnames[rev];
3287 rbplant(Ctlr *ctlr, int i)
3292 b = iallocb(Rbufsize + 256);
3295 b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, 256);
3296 memset(b->rp, 0, Rbufsize);
3298 p = (uchar*)&ctlr->rx.p[i * 4]; /* sdp0 */
3299 memset(p, 0, Rdscsize);
3300 put32(p, PCIWADDR(b->rp));
3301 p = (uchar*)&ctlr->rx.p[i * 4 + 1]; /* sdl0 */
3303 put16(p, Rbufsize);;
3309 allocrx(Ctlr *ctlr, RXQ *rx)
3314 rx->b = malloc(sizeof(Block*) * Nrx);
3315 if(rx->p == nil) /* Rx descriptors */
3316 rx->p = mallocalign(Nrx * Rdscsize, 16, 0, 0);
3317 if(rx->b == nil || rx->p == nil)
3318 return "no memory for rx ring";
3319 memset(rx->p, 0, Nrx * Rdscsize);
3320 for(i=0; i<Nrx; i++){
3321 if(rx->b[i] != nil){
3325 if(rbplant(ctlr, i) < 0)
3326 return "no memory for rx descriptors";
3333 freerx(Ctlr *, RXQ *rx)
3337 for(i = 0; i < Nrx; i++){
3338 if(rx->b[i] != nil){
3351 alloctx(Ctlr *, TXQ *tx)
3354 tx->b = malloc(sizeof(Block*) * Ntx);
3355 if(tx->d == nil) /* Tx descriptors */
3356 tx->d = mallocalign(Ntx * Tdscsize, 16, 0, 0);
3357 if(tx->b == nil || tx->d == nil)
3358 return "no memory for tx ring";
3359 memset(tx->d, 0, Ntx * Tdscsize);
3360 memset(tx->b, 0, Ntx * sizeof(Block*));
3366 freetx(Ctlr *, TXQ *tx)
3375 alloctxpool(Ctlr *ctlr)
3381 pool->p = mallocalign(Ntxpool * TxwiDmaSz, 4096, 0, 0);
3383 return "no memory for pool";
3384 memset(pool->p, 0, Ntxpool * TxwiDmaSz);
3390 initring(Ctlr *ctlr)
3396 * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings.
3398 for(qid = 0; qid < 6; qid++){
3399 if((err = alloctx(ctlr, &ctlr->tx[qid])) != nil)
3402 if((err = allocrx(ctlr, &ctlr->rx)) != nil)
3405 if((err = alloctxpool(ctlr)) != nil)
3407 /* mgmt ring is broken on RT2860C, use EDCA AC VO ring instead */
3409 ctlr->mgtqid = (ctlr->mac_ver == 0x2860 && ctlr->mac_rev == 0x0100) ?
3413 fail2: freerx(ctlr, &ctlr->rx);
3415 fail1: while(--qid >= 0)
3416 freetx(ctlr, &ctlr->tx[qid]);
3421 rt2860init(Ether *edev)
3430 /* wait for NIC to initialize */
3431 for(ntries = 0; ntries < 100; ntries++){
3432 tmp = csr32r(ctlr, AsicVerId);
3433 if(tmp != 0 && tmp != 0xffffffff)
3438 print("timeout waiting for NIC to initialize");
3441 ctlr->mac_ver = tmp >> 16;
3442 ctlr->mac_rev = tmp & 0xffff;
3444 if(ctlr->mac_ver != 0x2860){
3445 switch(ctlr->pdev->did){
3452 ctlr->flags = AdvancedPs;
3456 /* retrieve RF rev. no and various other things from EEPROM */
3459 print("MAC/BBP RT%X (rev 0x%04X), RF %s (MIMO %dT%dR)\n",
3460 ctlr->mac_ver, ctlr->mac_rev,
3461 getrfname(ctlr->rf_rev), ctlr->ntxchains, ctlr->nrxchains);
3462 if((err = initring(ctlr)) != nil){
3463 print("error: %s", err);
3470 static Ctlr *rt2860head, *rt2860tail;
3478 while(pdev = pcimatch(pdev, 0, 0)){
3482 if(pdev->ccrb != 2 || pdev->ccru != 0x80)
3484 if(pdev->vid != 0x1814) /* Ralink */
3498 ctlr = malloc(sizeof(Ctlr));
3500 print("rt2860: unable to alloc Ctlr\n");
3503 ctlr->port = pdev->mem[0].bar & ~0x0F;
3504 mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
3506 print("rt2860: can't map %8.8luX\n", pdev->mem[0].bar);
3513 if(rt2860head != nil)
3514 rt2860tail->link = ctlr;
3522 rt2860pnp(Ether* edev)
3526 if(rt2860head == nil)
3529 for(ctlr = rt2860head; ctlr != nil; ctlr = ctlr->link){
3532 if(edev->port == 0 || edev->port == ctlr->port){
3542 edev->port = ctlr->port;
3543 edev->irq = ctlr->pdev->intl;
3544 edev->tbdf = ctlr->pdev->tbdf;
3546 edev->attach = rt2860attach;
3547 edev->ifstat = rt2860ifstat;
3548 edev->ctl = rt2860ctl;
3549 edev->promiscuous = rt2860promiscuous;
3550 edev->multicast = rt2860multicast;
3553 if(rt2860init(edev) < 0){
3558 intrenable(edev->irq, rt2860interrupt, edev, edev->tbdf, edev->name);
3564 etherrt2860link(void)
3566 addethercard("rt2860", rt2860pnp);