From: stsp Date: Sat, 24 May 2014 10:10:17 +0000 (+0000) Subject: Support for newer run(4) hardware ported from FreeBSD's run(4) driver. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=d80de052046cde9af0660f13a5ec5d06ea37fe0c;p=openbsd Support for newer run(4) hardware ported from FreeBSD's run(4) driver. Committing over MAC/BBP RT5390 (rev 0x0502), RF RT5370 (MIMO 1T1R). Tested by myself, matthieu@, juanfra@ Diff glanced over by kettenis@ --- diff --git a/sys/dev/ic/rt2860reg.h b/sys/dev/ic/rt2860reg.h index 2d38db24155..2cc9ec38f45 100644 --- a/sys/dev/ic/rt2860reg.h +++ b/sys/dev/ic/rt2860reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860reg.h,v 1.31 2013/11/26 20:33:16 deraadt Exp $ */ +/* $OpenBSD: rt2860reg.h,v 1.32 2014/05/24 10:10:17 stsp Exp $ */ /*- * Copyright (c) 2007 @@ -80,6 +80,9 @@ #define RT3070_LDO_CFG0 0x05d4 #define RT3070_GPIO_SWITCH 0x05dc +/* RT5592 registers */ +#define RT5592_DEBUG_INDEX 0x05e8 + /* MAC registers */ #define RT2860_ASIC_VER_ID 0x1000 #define RT2860_MAC_SYS_CTRL 0x1004 @@ -204,6 +207,7 @@ #define RT2860_H2M_MAILBOX 0x7010 #define RT2860_H2M_MAILBOX_CID 0x7014 #define RT2860_H2M_MAILBOX_STATUS 0x701c +#define RT2860_H2M_INTSRC 0x7024 #define RT2860_H2M_BBPAGENT 0x7028 #define RT2860_BCN_BASE(vap) (0x7800 + (vap) * 512) @@ -385,6 +389,9 @@ #define RT3070_EFSROM_MODE_MASK 0x000000c0 #define RT3070_EFUSE_AOUT_MASK 0x0000003f +/* possible flag for register DEBUG_INDEX */ +#define RT5592_SEL_XTAL (1U << 31) + /* possible flags for register MAC_SYS_CTRL */ #define RT2860_RX_TS_EN (1 << 7) #define RT2860_WLAN_HALT_EN (1 << 6) @@ -696,6 +703,7 @@ /* possible flags for RT3020 RF register 1 */ #define RT3070_RF_BLOCK (1 << 0) +#define RT3070_PLL_PD (1 << 1) #define RT3070_RX0_PD (1 << 2) #define RT3070_TX0_PD (1 << 3) #define RT3070_RX1_PD (1 << 4) @@ -734,6 +742,9 @@ /* possible flags for RT3053 RF register 6 */ #define RT3593_VCO_IC (1 << 6) +/* possible flags for RT3053 RF register 18 */ +#define RT3593_AUTOTUNE_BYPASS (1 << 6) + /* possible flags for RT3053 RF register 20 */ #define RT3593_LDO_PLL_VC_MASK 0x0e #define RT3593_LDO_RF_VC_MASK 0xe0 @@ -742,9 +753,28 @@ #define RT3593_CP_IC_MASK 0xe0 #define RT3593_CP_IC_SHIFT 5 +/* possible flags for RT5390 RF register 38. */ +#define RT5390_RX_LO1 (1 << 5) + +/* possible flags for RT5390 RF register 39. */ +#define RT5390_RX_LO2 (1 << 7) + /* possible flags for RT3053 RF register 46 */ #define RT3593_RX_CTB (1 << 5) +/* possible flags for RT3053 RF register 50 */ +#define RT3593_TX_LO2 (1 << 4) + +/* possible flags for RT3053 RF register 51 */ +#define RT3593_TX_LO1 (1 << 4) + +/* Possible flags for RT5390 BBP register 4. */ +#define RT5390_MAC_IF_CTRL (1 << 6) + +/* possible flags for RT5390 BBP register 105. */ +#define RT5390_MLD (1 << 2) +#define RT5390_EN_SIG_MODULATION (1 << 3) + #define RT3090_DEF_LNA 10 /* RT2860 TX descriptor */ @@ -891,6 +921,9 @@ struct rt2860_rxwi { #define RT3070_RF_3052 9 /* dual-band 2T2R */ #define RT3070_RF_3320 11 /* 1T1R */ #define RT3070_RF_3053 13 /* dual-band 3T3R */ +#define RT5592_RF_5592 0x000f /* dual-band 2T2R */ +#define RT5390_RF_5370 0x5370 /* 1T1R */ +#define RT5390_RF_5372 0x5372 /* 2T2R */ /* USB commands for RT2870 only */ #define RT2870_RESET 1 @@ -938,6 +971,47 @@ struct rt2860_rxwi { #define RT2860_EEPROM_BBP_BASE 0x78 #define RT3071_EEPROM_RF_BASE 0x82 +/* EEPROM registers for RT3593. */ +#define RT3593_EEPROM_FREQ_LEDS 0x21 +#define RT3593_EEPROM_FREQ 0x22 +#define RT3593_EEPROM_LED1 0x22 +#define RT3593_EEPROM_LED2 0x23 +#define RT3593_EEPROM_LED3 0x24 +#define RT3593_EEPROM_LNA 0x26 +#define RT3593_EEPROM_LNA_5GHZ 0x27 +#define RT3593_EEPROM_RSSI1_2GHZ 0x28 +#define RT3593_EEPROM_RSSI2_2GHZ 0x29 +#define RT3593_EEPROM_RSSI1_5GHZ 0x2a +#define RT3593_EEPROM_RSSI2_5GHZ 0x2b +#define RT3593_EEPROM_PWR2GHZ_BASE1 0x30 +#define RT3593_EEPROM_PWR2GHZ_BASE2 0x37 +#define RT3593_EEPROM_PWR2GHZ_BASE3 0x3e +#define RT3593_EEPROM_PWR5GHZ_BASE1 0x4b +#define RT3593_EEPROM_PWR5GHZ_BASE2 0x65 +#define RT3593_EEPROM_PWR5GHZ_BASE3 0x7f + +/* + * EEPROM IQ calibration. + */ +#define RT5390_EEPROM_IQ_GAIN_CAL_TX0_2GHZ 0x130 +#define RT5390_EEPROM_IQ_PHASE_CAL_TX0_2GHZ 0x131 +#define RT5390_EEPROM_IQ_GAIN_CAL_TX1_2GHZ 0x133 +#define RT5390_EEPROM_IQ_PHASE_CAL_TX1_2GHZ 0x134 +#define RT5390_EEPROM_RF_IQ_COMPENSATION_CTL 0x13c +#define RT5390_EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CTL 0x13d +#define RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5GHZ 0x144 +#define RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5GHZ 0x145 +#define RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5GHZ 0x146 +#define RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5GHZ 0x147 +#define RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5GHZ 0x148 +#define RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5GHZ 0x149 +#define RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5GHZ 0x14a +#define RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5GHZ 0x14b +#define RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5GHZ 0x14c +#define RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5GHZ 0x14d +#define RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5GHZ 0x14e +#define RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5GHZ 0x14f + #define RT2860_RIDX_CCK1 0 #define RT2860_RIDX_CCK11 3 #define RT2860_RIDX_OFDM6 4 @@ -1084,6 +1158,62 @@ static const struct rt2860_rate { { 105, 0x05 }, \ { 106, 0x35 } +#define RT5390_DEF_BBP \ + { 31, 0x08 }, \ + { 65, 0x2c }, \ + { 66, 0x38 }, \ + { 68, 0x0b }, \ + { 69, 0x0d }, \ + { 70, 0x06 }, \ + { 73, 0x13 }, \ + { 75, 0x46 }, \ + { 76, 0x28 }, \ + { 77, 0x59 }, \ + { 81, 0x37 }, \ + { 82, 0x62 }, \ + { 83, 0x7a }, \ + { 84, 0x9a }, \ + { 86, 0x38 }, \ + { 91, 0x04 }, \ + { 92, 0x02 }, \ + { 103, 0xc0 }, \ + { 104, 0x92 }, \ + { 105, 0x3c }, \ + { 106, 0x03 }, \ + { 128, 0x12 } + +#define RT5592_DEF_BBP \ + { 20, 0x06 }, \ + { 31, 0x08 }, \ + { 65, 0x2c }, \ + { 66, 0x38 }, \ + { 68, 0xdd }, \ + { 69, 0x1a }, \ + { 70, 0x05 }, \ + { 73, 0x13 }, \ + { 74, 0x0f }, \ + { 75, 0x4f }, \ + { 76, 0x28 }, \ + { 77, 0x59 }, \ + { 81, 0x37 }, \ + { 82, 0x62 }, \ + { 83, 0x6a }, \ + { 84, 0x9a }, \ + { 86, 0x38 }, \ + { 88, 0x90 }, \ + { 91, 0x04 }, \ + { 92, 0x02 }, \ + { 95, 0x9a }, \ + { 98, 0x12 }, \ + { 103, 0xc0 }, \ + { 104, 0x92 }, \ + { 105, 0x3c }, \ + { 106, 0x35 }, \ + { 128, 0x12 }, \ + { 134, 0xd0 }, \ + { 135, 0xf6 }, \ + { 137, 0x0f } + /* * Default settings for RF registers; values derived from the reference driver. */ @@ -1197,6 +1327,116 @@ static const struct rt2860_rate { { 0x61, 0, 7 }, \ { 0x61, 0, 9 } +#define RT5592_RF5592_20MHZ \ + { 0x1e2, 4, 10, 3 }, \ + { 0x1e3, 4, 10, 3 }, \ + { 0x1e4, 4, 10, 3 }, \ + { 0x1e5, 4, 10, 3 }, \ + { 0x1e6, 4, 10, 3 }, \ + { 0x1e7, 4, 10, 3 }, \ + { 0x1e8, 4, 10, 3 }, \ + { 0x1e9, 4, 10, 3 }, \ + { 0x1ea, 4, 10, 3 }, \ + { 0x1eb, 4, 10, 3 }, \ + { 0x1ec, 4, 10, 3 }, \ + { 0x1ed, 4, 10, 3 }, \ + { 0x1ee, 4, 10, 3 }, \ + { 0x1f0, 8, 10, 3 }, \ + { 0xac, 8, 12, 1 }, \ + { 0xad, 0, 12, 1 }, \ + { 0xad, 4, 12, 1 }, \ + { 0xae, 0, 12, 1 }, \ + { 0xae, 4, 12, 1 }, \ + { 0xae, 8, 12, 1 }, \ + { 0xaf, 4, 12, 1 }, \ + { 0xaf, 8, 12, 1 }, \ + { 0xb0, 0, 12, 1 }, \ + { 0xb0, 8, 12, 1 }, \ + { 0xb1, 0, 12, 1 }, \ + { 0xb1, 4, 12, 1 }, \ + { 0xb7, 4, 12, 1 }, \ + { 0xb7, 8, 12, 1 }, \ + { 0xb8, 0, 12, 1 }, \ + { 0xb8, 8, 12, 1 }, \ + { 0xb9, 0, 12, 1 }, \ + { 0xb9, 4, 12, 1 }, \ + { 0xba, 0, 12, 1 }, \ + { 0xba, 4, 12, 1 }, \ + { 0xba, 8, 12, 1 }, \ + { 0xbb, 4, 12, 1 }, \ + { 0xbb, 8, 12, 1 }, \ + { 0xbc, 0, 12, 1 }, \ + { 0xbc, 8, 12, 1 }, \ + { 0xbd, 0, 12, 1 }, \ + { 0xbd, 4, 12, 1 }, \ + { 0xbe, 0, 12, 1 }, \ + { 0xbf, 6, 12, 1 }, \ + { 0xbf, 10, 12, 1 }, \ + { 0xc0, 2, 12, 1 }, \ + { 0xc0, 10, 12, 1 }, \ + { 0xc1, 2, 12, 1 }, \ + { 0xc1, 6, 12, 1 }, \ + { 0xc2, 2, 12, 1 }, \ + { 0xa4, 0, 12, 1 }, \ + { 0xa4, 4, 12, 1 }, \ + { 0xa5, 8, 12, 1 }, \ + { 0xa6, 0, 12, 1 } + +#define RT5592_RF5592_40MHZ \ + { 0xf1, 2, 10, 3 }, \ + { 0xf1, 7, 10, 3 }, \ + { 0xf2, 2, 10, 3 }, \ + { 0xf2, 7, 10, 3 }, \ + { 0xf3, 2, 10, 3 }, \ + { 0xf3, 7, 10, 3 }, \ + { 0xf4, 2, 10, 3 }, \ + { 0xf4, 7, 10, 3 }, \ + { 0xf5, 2, 10, 3 }, \ + { 0xf5, 7, 10, 3 }, \ + { 0xf6, 2, 10, 3 }, \ + { 0xf6, 7, 10, 3 }, \ + { 0xf7, 2, 10, 3 }, \ + { 0xf8, 4, 10, 3 }, \ + { 0x56, 4, 12, 1 }, \ + { 0x56, 6, 12, 1 }, \ + { 0x56, 8, 12, 1 }, \ + { 0x57, 0, 12, 1 }, \ + { 0x57, 2, 12, 1 }, \ + { 0x57, 4, 12, 1 }, \ + { 0x57, 8, 12, 1 }, \ + { 0x57, 10, 12, 1 }, \ + { 0x58, 0, 12, 1 }, \ + { 0x58, 4, 12, 1 }, \ + { 0x58, 6, 12, 1 }, \ + { 0x58, 8, 12, 1 }, \ + { 0x5b, 8, 12, 1 }, \ + { 0x5b, 10, 12, 1 }, \ + { 0x5c, 0, 12, 1 }, \ + { 0x5c, 4, 12, 1 }, \ + { 0x5c, 6, 12, 1 }, \ + { 0x5c, 8, 12, 1 }, \ + { 0x5d, 0, 12, 1 }, \ + { 0x5d, 2, 12, 1 }, \ + { 0x5d, 4, 12, 1 }, \ + { 0x5d, 8, 12, 1 }, \ + { 0x5d, 10, 12, 1 }, \ + { 0x5e, 0, 12, 1 }, \ + { 0x5e, 4, 12, 1 }, \ + { 0x5e, 6, 12, 1 }, \ + { 0x5e, 8, 12, 1 }, \ + { 0x5f, 0, 12, 1 }, \ + { 0x5f, 9, 12, 1 }, \ + { 0x5f, 11, 12, 1 }, \ + { 0x60, 1, 12, 1 }, \ + { 0x60, 5, 12, 1 }, \ + { 0x60, 7, 12, 1 }, \ + { 0x60, 9, 12, 1 }, \ + { 0x61, 1, 12, 1 }, \ + { 0x52, 0, 12, 1 }, \ + { 0x52, 4, 12, 1 }, \ + { 0x52, 8, 12, 1 }, \ + { 0x53, 0, 12, 1 } + #define RT3070_DEF_RF \ { 4, 0x40 }, \ { 5, 0x03 }, \ @@ -1250,3 +1490,278 @@ static const struct rt2860_rate { { 29, 0x9b }, \ { 30, 0x09 }, \ { 31, 0x10 } + +#define RT3593_DEF_RF \ + { 1, 0x03 }, \ + { 3, 0x80 }, \ + { 5, 0x00 }, \ + { 6, 0x40 }, \ + { 8, 0xf1 }, \ + { 9, 0x02 }, \ + { 10, 0xd3 }, \ + { 11, 0x40 }, \ + { 12, 0x4e }, \ + { 13, 0x12 }, \ + { 18, 0x40 }, \ + { 22, 0x20 }, \ + { 30, 0x10 }, \ + { 31, 0x80 }, \ + { 32, 0x78 }, \ + { 33, 0x3b }, \ + { 34, 0x3c }, \ + { 35, 0xe0 }, \ + { 38, 0x86 }, \ + { 39, 0x23 }, \ + { 44, 0xd3 }, \ + { 45, 0xbb }, \ + { 46, 0x60 }, \ + { 49, 0x81 }, \ + { 50, 0x86 }, \ + { 51, 0x75 }, \ + { 52, 0x45 }, \ + { 53, 0x18 }, \ + { 54, 0x18 }, \ + { 55, 0x18 }, \ + { 56, 0xdb }, \ + { 57, 0x6e } + +#define RT5390_DEF_RF \ + { 1, 0x0f }, \ + { 2, 0x80 }, \ + { 3, 0x88 }, \ + { 5, 0x10 }, \ + { 6, 0xa0 }, \ + { 7, 0x00 }, \ + { 10, 0x53 }, \ + { 11, 0x4a }, \ + { 12, 0x46 }, \ + { 13, 0x9f }, \ + { 14, 0x00 }, \ + { 15, 0x00 }, \ + { 16, 0x00 }, \ + { 18, 0x03 }, \ + { 19, 0x00 }, \ + { 20, 0x00 }, \ + { 21, 0x00 }, \ + { 22, 0x20 }, \ + { 23, 0x00 }, \ + { 24, 0x00 }, \ + { 25, 0xc0 }, \ + { 26, 0x00 }, \ + { 27, 0x09 }, \ + { 28, 0x00 }, \ + { 29, 0x10 }, \ + { 30, 0x10 }, \ + { 31, 0x80 }, \ + { 32, 0x80 }, \ + { 33, 0x00 }, \ + { 34, 0x07 }, \ + { 35, 0x12 }, \ + { 36, 0x00 }, \ + { 37, 0x08 }, \ + { 38, 0x85 }, \ + { 39, 0x1b }, \ + { 40, 0x0b }, \ + { 41, 0xbb }, \ + { 42, 0xd2 }, \ + { 43, 0x9a }, \ + { 44, 0x0e }, \ + { 45, 0xa2 }, \ + { 46, 0x7b }, \ + { 47, 0x00 }, \ + { 48, 0x10 }, \ + { 49, 0x94 }, \ + { 52, 0x38 }, \ + { 53, 0x84 }, \ + { 54, 0x78 }, \ + { 55, 0x44 }, \ + { 56, 0x22 }, \ + { 57, 0x80 }, \ + { 58, 0x7f }, \ + { 59, 0x8f }, \ + { 60, 0x45 }, \ + { 61, 0xdd }, \ + { 62, 0x00 }, \ + { 63, 0x00 } + +#define RT5392_DEF_RF \ + { 1, 0x17 }, \ + { 3, 0x88 }, \ + { 5, 0x10 }, \ + { 6, 0xe0 }, \ + { 7, 0x00 }, \ + { 10, 0x53 }, \ + { 11, 0x4a }, \ + { 12, 0x46 }, \ + { 13, 0x9f }, \ + { 14, 0x00 }, \ + { 15, 0x00 }, \ + { 16, 0x00 }, \ + { 18, 0x03 }, \ + { 19, 0x4d }, \ + { 20, 0x00 }, \ + { 21, 0x8d }, \ + { 22, 0x20 }, \ + { 23, 0x0b }, \ + { 24, 0x44 }, \ + { 25, 0x80 }, \ + { 26, 0x82 }, \ + { 27, 0x09 }, \ + { 28, 0x00 }, \ + { 29, 0x10 }, \ + { 30, 0x10 }, \ + { 31, 0x80 }, \ + { 32, 0x20 }, \ + { 33, 0xc0 }, \ + { 34, 0x07 }, \ + { 35, 0x12 }, \ + { 36, 0x00 }, \ + { 37, 0x08 }, \ + { 38, 0x89 }, \ + { 39, 0x1b }, \ + { 40, 0x0f }, \ + { 41, 0xbb }, \ + { 42, 0xd5 }, \ + { 43, 0x9b }, \ + { 44, 0x0e }, \ + { 45, 0xa2 }, \ + { 46, 0x73 }, \ + { 47, 0x0c }, \ + { 48, 0x10 }, \ + { 49, 0x94 }, \ + { 50, 0x94 }, \ + { 51, 0x3a }, \ + { 52, 0x48 }, \ + { 53, 0x44 }, \ + { 54, 0x38 }, \ + { 55, 0x43 }, \ + { 56, 0xa1 }, \ + { 57, 0x00 }, \ + { 58, 0x39 }, \ + { 59, 0x07 }, \ + { 60, 0x45 }, \ + { 61, 0x91 }, \ + { 62, 0x39 }, \ + { 63, 0x07 } + +#define RT5592_DEF_RF \ + { 1, 0x3f }, \ + { 3, 0x08 }, \ + { 5, 0x10 }, \ + { 6, 0xe4 }, \ + { 7, 0x00 }, \ + { 14, 0x00 }, \ + { 15, 0x00 }, \ + { 16, 0x00 }, \ + { 18, 0x03 }, \ + { 19, 0x4d }, \ + { 20, 0x10 }, \ + { 21, 0x8d }, \ + { 26, 0x82 }, \ + { 28, 0x00 }, \ + { 29, 0x10 }, \ + { 33, 0xc0 }, \ + { 34, 0x07 }, \ + { 35, 0x12 }, \ + { 47, 0x0c }, \ + { 53, 0x22 }, \ + { 63, 0x07 } + +#define RT5592_2GHZ_DEF_RF \ + { 10, 0x90 }, \ + { 11, 0x4a }, \ + { 12, 0x52 }, \ + { 13, 0x42 }, \ + { 22, 0x40 }, \ + { 24, 0x4a }, \ + { 25, 0x80 }, \ + { 27, 0x42 }, \ + { 36, 0x80 }, \ + { 37, 0x08 }, \ + { 38, 0x89 }, \ + { 39, 0x1b }, \ + { 40, 0x0d }, \ + { 41, 0x9b }, \ + { 42, 0xd5 }, \ + { 43, 0x72 }, \ + { 44, 0x0e }, \ + { 45, 0xa2 }, \ + { 46, 0x6b }, \ + { 48, 0x10 }, \ + { 51, 0x3e }, \ + { 52, 0x48 }, \ + { 54, 0x38 }, \ + { 56, 0xa1 }, \ + { 57, 0x00 }, \ + { 58, 0x39 }, \ + { 60, 0x45 }, \ + { 61, 0x91 }, \ + { 62, 0x39 } + +#define RT5592_5GHZ_DEF_RF \ + { 10, 0x97 }, \ + { 11, 0x40 }, \ + { 25, 0xbf }, \ + { 27, 0x42 }, \ + { 36, 0x00 }, \ + { 37, 0x04 }, \ + { 38, 0x85 }, \ + { 40, 0x42 }, \ + { 41, 0xbb }, \ + { 42, 0xd7 }, \ + { 45, 0x41 }, \ + { 48, 0x00 }, \ + { 57, 0x77 }, \ + { 60, 0x05 }, \ + { 61, 0x01 } + +#define RT5592_CHAN_5GHZ \ + { 36, 64, 12, 0x2e }, \ + { 100, 165, 12, 0x0e }, \ + { 36, 64, 13, 0x22 }, \ + { 100, 165, 13, 0x42 }, \ + { 36, 64, 22, 0x60 }, \ + { 100, 165, 22, 0x40 }, \ + { 36, 64, 23, 0x7f }, \ + { 100, 153, 23, 0x3c }, \ + { 155, 165, 23, 0x38 }, \ + { 36, 50, 24, 0x09 }, \ + { 52, 64, 24, 0x07 }, \ + { 100, 153, 24, 0x06 }, \ + { 155, 165, 24, 0x05 }, \ + { 36, 64, 39, 0x1c }, \ + { 100, 138, 39, 0x1a }, \ + { 140, 165, 39, 0x18 }, \ + { 36, 64, 43, 0x5b }, \ + { 100, 138, 43, 0x3b }, \ + { 140, 165, 43, 0x1b }, \ + { 36, 64, 44, 0x40 }, \ + { 100, 138, 44, 0x20 }, \ + { 140, 165, 44, 0x10 }, \ + { 36, 64, 46, 0x00 }, \ + { 100, 138, 46, 0x18 }, \ + { 140, 165, 46, 0x08 }, \ + { 36, 64, 51, 0xfe }, \ + { 100, 124, 51, 0xfc }, \ + { 126, 165, 51, 0xec }, \ + { 36, 64, 52, 0x0c }, \ + { 100, 138, 52, 0x06 }, \ + { 140, 165, 52, 0x06 }, \ + { 36, 64, 54, 0xf8 }, \ + { 100, 165, 54, 0xeb }, \ + { 36, 50, 55, 0x06 }, \ + { 52, 64, 55, 0x04 }, \ + { 100, 138, 55, 0x01 }, \ + { 140, 165, 55, 0x00 }, \ + { 36, 50, 56, 0xd3 }, \ + { 52, 128, 56, 0xbb }, \ + { 130, 165, 56, 0xab }, \ + { 36, 64, 58, 0x15 }, \ + { 100, 116, 58, 0x1d }, \ + { 118, 165, 58, 0x15 }, \ + { 36, 64, 59, 0x7f }, \ + { 100, 138, 59, 0x3f }, \ + { 140, 165, 59, 0x7c }, \ + { 36, 64, 62, 0x15 }, \ + { 100, 116, 62, 0x1d }, \ + { 118, 165, 62, 0x15 } diff --git a/sys/dev/usb/if_run.c b/sys/dev/usb/if_run.c index 4a3ee8966e7..bac0fef593f 100644 --- a/sys/dev/usb/if_run.c +++ b/sys/dev/usb/if_run.c @@ -1,7 +1,8 @@ -/* $OpenBSD: if_run.c,v 1.97 2014/03/19 10:09:19 mpi Exp $ */ +/* $OpenBSD: if_run.c,v 1.98 2014/05/24 10:10:17 stsp Exp $ */ /*- * Copyright (c) 2008-2010 Damien Bergamini + * Copyright (c) 2013-2014 Kevin Lo * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,7 +18,7 @@ */ /*- - * Ralink Technology RT2700U/RT2800U/RT3000U chipset driver. + * Ralink Technology RT2700U/RT2800U/RT3000U/RT3900E chipset driver. * http://www.ralinktech.com/ */ @@ -115,6 +116,7 @@ static const struct usb_devno run_devs[] = { USB_ID(ASUS, RT3070_1), USB_ID(ASUS, USBN13), USB_ID(ASUS, USBN53), + USB_ID(ASUS, USBN66), USB_ID(ASUS2, USBN11), USB_ID(AZUREWAVE, RT2870_1), USB_ID(AZUREWAVE, RT2870_2), @@ -123,6 +125,7 @@ static const struct usb_devno run_devs[] = { USB_ID(AZUREWAVE, RT3070_3), USB_ID(AZUREWAVE, RT3070_4), USB_ID(AZUREWAVE, RT3070_5), + USB_ID(BELKIN, F9L1103), USB_ID(BELKIN, F5D8053V3), USB_ID(BELKIN, F5D8055), USB_ID(BELKIN, F5D8055V2), @@ -155,6 +158,9 @@ static const struct usb_devno run_devs[] = { USB_ID(COREGA, RT3070), USB_ID(CYBERTAN, RT2870), USB_ID(DLINK, DWA127), + USB_ID(DLINK, DWA140B3), + USB_ID(DLINK, DWA160B2), + USB_ID(DLINK, DWA162), USB_ID(DLINK, RT2870), USB_ID(DLINK, RT3072), USB_ID(DLINK2, DWA130), @@ -253,7 +259,10 @@ static const struct usb_devno run_devs[] = { USB_ID(RALINK, RT3072), USB_ID(RALINK, RT3370), USB_ID(RALINK, RT3572), + USB_ID(RALINK, RT3573), + USB_ID(RALINK, RT5370), USB_ID(RALINK, RT8070), + USB_ID(SAMSUNG, WIS09ABGN), USB_ID(SAMSUNG2, RT2870_1), USB_ID(SENAO, RT2870_1), USB_ID(SENAO, RT2870_2), @@ -266,6 +275,14 @@ static const struct usb_devno run_devs[] = { USB_ID(SENAO, RT3072_3), USB_ID(SENAO, RT3072_4), USB_ID(SENAO, RT3072_5), + USB_ID(SITECOMEU, WL302), + USB_ID(SITECOMEU, WL315), + USB_ID(SITECOMEU, WL321), + USB_ID(SITECOMEU, RT3070_3), + USB_ID(SITECOMEU, WL302), + USB_ID(SITECOMEU, WL344), + USB_ID(SITECOMEU, WL329), + USB_ID(SITECOMEU, WL345), USB_ID(SITECOMEU, RT2870_1), USB_ID(SITECOMEU, RT2870_2), USB_ID(SITECOMEU, RT2870_3), @@ -273,6 +290,7 @@ static const struct usb_devno run_devs[] = { USB_ID(SITECOMEU, RT3072_3), USB_ID(SITECOMEU, RT3072_4), USB_ID(SITECOMEU, RT3072_5), + USB_ID(SITECOMEU, RT3072_6), USB_ID(SITECOMEU, WL302), USB_ID(SITECOMEU, WL315), USB_ID(SITECOMEU, WL321), @@ -326,15 +344,18 @@ int run_write(struct run_softc *, uint16_t, uint32_t); int run_write_region_1(struct run_softc *, uint16_t, const uint8_t *, int); int run_set_region_4(struct run_softc *, uint16_t, uint32_t, int); +int run_efuse_read(struct run_softc *, uint16_t, uint16_t *); int run_efuse_read_2(struct run_softc *, uint16_t, uint16_t *); int run_eeprom_read_2(struct run_softc *, uint16_t, uint16_t *); -int run_rt2870_rf_write(struct run_softc *, uint8_t, uint32_t); +int run_rt2870_rf_write(struct run_softc *, uint32_t); int run_rt3070_rf_read(struct run_softc *, uint8_t, uint8_t *); int run_rt3070_rf_write(struct run_softc *, uint8_t, uint8_t); int run_bbp_read(struct run_softc *, uint8_t, uint8_t *); int run_bbp_write(struct run_softc *, uint8_t, uint8_t); int run_mcu_cmd(struct run_softc *, uint8_t, uint16_t); const char * run_get_rf(int); +void run_get_txpower(struct run_softc *); +void run_rt3593_get_txpower(struct run_softc *); int run_read_eeprom(struct run_softc *); struct ieee80211_node *run_node_alloc(struct ieee80211com *); int run_media_change(struct ifnet *); @@ -364,12 +385,16 @@ int run_tx(struct run_softc *, struct mbuf *, void run_start(struct ifnet *); void run_watchdog(struct ifnet *); int run_ioctl(struct ifnet *, u_long, caddr_t); +void run_iq_calib(struct run_softc *, u_int); void run_select_chan_group(struct run_softc *, int); void run_set_agc(struct run_softc *, uint8_t); void run_set_rx_antenna(struct run_softc *, int); void run_rt2870_set_chan(struct run_softc *, u_int); void run_rt3070_set_chan(struct run_softc *, u_int); void run_rt3572_set_chan(struct run_softc *, u_int); +void run_rt3593_set_chan(struct run_softc *, u_int); +void run_rt5390_set_chan(struct run_softc *, u_int); +void run_rt5592_set_chan(struct run_softc *, u_int); int run_set_chan(struct run_softc *, struct ieee80211_channel *); void run_enable_tsf_sync(struct run_softc *); void run_enable_mrr(struct run_softc *); @@ -383,12 +408,18 @@ void run_updateslot_cb(struct run_softc *, void *); #if NBPFILTER > 0 int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t); #endif +void run_rt5390_bbp_init(struct run_softc *); int run_bbp_init(struct run_softc *); int run_rt3070_rf_init(struct run_softc *); +void run_rt3593_rf_init(struct run_softc *); +void run_rt5390_rf_init(struct run_softc *); int run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t, uint8_t *); void run_rt3070_rf_setup(struct run_softc *); +void run_rt3593_rf_setup(struct run_softc *); +void run_rt5390_rf_setup(struct run_softc *); int run_txrx_enable(struct run_softc *); +void run_adjust_freq_offset(struct run_softc *); int run_init(struct ifnet *); void run_stop(struct ifnet *, int); @@ -413,6 +444,25 @@ static const struct { uint8_t val; } rt2860_def_bbp[] = { RT2860_DEF_BBP +},rt5390_def_bbp[] = { + RT5390_DEF_BBP +},rt5592_def_bbp[] = { + RT5592_DEF_BBP +}; + +/* + * Default values for BBP register R196 for RT5592. + */ +static const uint8_t rt5592_bbp_r196[] = { + 0xe0, 0x1f, 0x38, 0x32, 0x08, 0x28, 0x19, 0x0a, 0xff, 0x00, + 0x16, 0x10, 0x10, 0x0b, 0x36, 0x2c, 0x26, 0x24, 0x42, 0x36, + 0x30, 0x2d, 0x4c, 0x46, 0x3d, 0x40, 0x3e, 0x42, 0x3d, 0x40, + 0x3c, 0x34, 0x2c, 0x2f, 0x3c, 0x35, 0x2e, 0x2a, 0x49, 0x41, + 0x36, 0x31, 0x30, 0x30, 0x0e, 0x0d, 0x28, 0x21, 0x1c, 0x16, + 0x50, 0x4a, 0x43, 0x40, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7d, 0x14, 0x32, 0x2c, 0x36, 0x4c, 0x43, 0x2c, + 0x2e, 0x36, 0x30, 0x6e }; static const struct rfprog { @@ -428,13 +478,43 @@ struct { RT3070_RF3052 }; +static const struct rt5592_freqs { + uint16_t n; + uint8_t k, m, r; +} rt5592_freqs_20mhz[] = { + RT5592_RF5592_20MHZ +},rt5592_freqs_40mhz[] = { + RT5592_RF5592_40MHZ +}; + static const struct { uint8_t reg; uint8_t val; -} rt3070_def_rf[] = { +} rt3070_def_rf[] = { RT3070_DEF_RF -}, rt3572_def_rf[] = { +},rt3572_def_rf[] = { RT3572_DEF_RF +},rt3593_def_rf[] = { + RT3593_DEF_RF +},rt5390_def_rf[] = { + RT5390_DEF_RF +},rt5392_def_rf[] = { + RT5392_DEF_RF +},rt5592_def_rf[] = { + RT5592_DEF_RF +},rt5592_2ghz_def_rf[] = { + RT5592_2GHZ_DEF_RF +},rt5592_5ghz_def_rf[] = { + RT5592_5GHZ_DEF_RF +}; + +static const struct { + u_int firstchan; + u_int lastchan; + uint8_t reg; + uint8_t val; +} rt5592_chan_5ghz[] = { + RT5592_CHAN_5GHZ }; int @@ -549,7 +629,9 @@ run_attach(struct device *parent, struct device *self, void *aux) if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850 || - sc->rf_rev == RT3070_RF_3052) { + sc->rf_rev == RT3070_RF_3052 || + sc->rf_rev == RT3070_RF_3053 || + sc->rf_rev == RT5592_RF_5592) { /* set supported .11a rates */ ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a; @@ -795,7 +877,9 @@ run_load_microcode(struct run_softc *sc) return error; usbd_delay_ms(sc->sc_udev, 10); + run_write(sc, RT2860_H2M_BBPAGENT, 0); run_write(sc, RT2860_H2M_MAILBOX, 0); + run_write(sc, RT2860_H2M_INTSRC, 0); if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0)) != 0) return error; @@ -915,7 +999,52 @@ run_set_region_4(struct run_softc *sc, uint16_t reg, uint32_t val, int count) return error; } -/* Read 16-bit from eFUSE ROM (RT3070 only.) */ +/* Read 16-bit from eFUSE ROM. */ +int +run_efuse_read(struct run_softc *sc, uint16_t addr, uint16_t *val) +{ + uint32_t tmp; + uint16_t reg; + int error, ntries; + + if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0) + return error; + + /*- + * Read one 16-byte block into registers EFUSE_DATA[0-3]: + * DATA0: F E D C + * DATA1: B A 9 8 + * DATA2: 7 6 5 4 + * DATA3: 3 2 1 0 + */ + tmp &= ~(RT3070_EFSROM_MODE_MASK | RT3070_EFSROM_AIN_MASK); + tmp |= (addr & ~0xf) << RT3070_EFSROM_AIN_SHIFT | RT3070_EFSROM_KICK; + run_write(sc, RT3070_EFUSE_CTRL, tmp); + for (ntries = 0; ntries < 100; ntries++) { + if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0) + return error; + if (!(tmp & RT3070_EFSROM_KICK)) + break; + DELAY(2); + } + if (ntries == 100) + return ETIMEDOUT; + + if ((tmp & RT3070_EFUSE_AOUT_MASK) == RT3070_EFUSE_AOUT_MASK) { + *val = 0xffff; /* address not found */ + return 0; + } + /* determine to which 32-bit register our 16-bit word belongs */ + reg = RT3070_EFUSE_DATA3 - (addr & 0xc); + if ((error = run_read(sc, reg, &tmp)) != 0) + return error; + + tmp >>= (8 * (addr & 0x3)); + *val = (addr & 1) ? tmp >> 16 : tmp & 0xffff; + return 0; +} + +/* Read 16-bit from eFUSE ROM for RT3xxx. */ int run_efuse_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val) { @@ -989,7 +1118,7 @@ run_srom_read(struct run_softc *sc, uint16_t addr, uint16_t *val) } int -run_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val) +run_rt2870_rf_write(struct run_softc *sc, uint32_t val) { uint32_t tmp; int error, ntries; @@ -1003,10 +1132,7 @@ run_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val) if (ntries == 10) return ETIMEDOUT; - /* RF registers are 24-bit on the RT2860 */ - tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT | - (val & 0x3fffff) << 2 | (reg & 3); - return run_write(sc, RT2860_RF_CSR_CFG0, tmp); + return run_write(sc, RT2860_RF_CSR_CFG0, val); } int @@ -1169,10 +1295,133 @@ run_get_rf(int rev) case RT3070_RF_3021: return "RT3021"; case RT3070_RF_3022: return "RT3022"; case RT3070_RF_3052: return "RT3052"; + case RT3070_RF_3053: return "RT3053"; + case RT5592_RF_5592: return "RT5592"; + case RT5390_RF_5370: return "RT5370"; + case RT5390_RF_5372: return "RT5372"; } return "unknown"; } +void +run_rt3593_get_txpower(struct run_softc *sc) +{ + uint16_t addr, val; + int i; + + /* Read power settings for 2GHz channels. */ + for (i = 0; i < 14; i += 2) { + addr = (sc->ntxchains == 3) ? RT3593_EEPROM_PWR2GHZ_BASE1 : + RT2860_EEPROM_PWR2GHZ_BASE1; + run_srom_read(sc, addr + i / 2, &val); + sc->txpow1[i + 0] = (int8_t)(val & 0xff); + sc->txpow1[i + 1] = (int8_t)(val >> 8); + + addr = (sc->ntxchains == 3) ? RT3593_EEPROM_PWR2GHZ_BASE2 : + RT2860_EEPROM_PWR2GHZ_BASE2; + run_srom_read(sc, addr + i / 2, &val); + sc->txpow2[i + 0] = (int8_t)(val & 0xff); + sc->txpow2[i + 1] = (int8_t)(val >> 8); + + if (sc->ntxchains == 3) { + run_srom_read(sc, RT3593_EEPROM_PWR2GHZ_BASE3 + i / 2, + &val); + sc->txpow3[i + 0] = (int8_t)(val & 0xff); + sc->txpow3[i + 1] = (int8_t)(val >> 8); + } + } + /* Fix broken Tx power entries. */ + for (i = 0; i < 14; i++) { + if (sc->txpow1[i] > 31) + sc->txpow1[i] = 5; + if (sc->txpow2[i] > 31) + sc->txpow2[i] = 5; + if (sc->ntxchains == 3) { + if (sc->txpow3[i] > 31) + sc->txpow3[i] = 5; + } + } + /* Read power settings for 5GHz channels. */ + for (i = 0; i < 40; i += 2) { + run_srom_read(sc, RT3593_EEPROM_PWR5GHZ_BASE1 + i / 2, &val); + sc->txpow1[i + 14] = (int8_t)(val & 0xff); + sc->txpow1[i + 15] = (int8_t)(val >> 8); + + run_srom_read(sc, RT3593_EEPROM_PWR5GHZ_BASE2 + i / 2, &val); + sc->txpow2[i + 14] = (int8_t)(val & 0xff); + sc->txpow2[i + 15] = (int8_t)(val >> 8); + + if (sc->ntxchains == 3) { + run_srom_read(sc, RT3593_EEPROM_PWR5GHZ_BASE3 + i / 2, + &val); + sc->txpow3[i + 14] = (int8_t)(val & 0xff); + sc->txpow3[i + 15] = (int8_t)(val >> 8); + } + } +} + +void +run_get_txpower(struct run_softc *sc) +{ + uint16_t val; + int i; + + /* Read power settings for 2GHz channels. */ + for (i = 0; i < 14; i += 2) { + run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2, &val); + sc->txpow1[i + 0] = (int8_t)(val & 0xff); + sc->txpow1[i + 1] = (int8_t)(val >> 8); + + if (sc->mac_ver != 0x5390) { + run_srom_read(sc, + RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val); + sc->txpow2[i + 0] = (int8_t)(val & 0xff); + sc->txpow2[i + 1] = (int8_t)(val >> 8); + } + } + /* Fix broken Tx power entries. */ + for (i = 0; i < 14; i++) { + if (sc->mac_ver >= 0x5390) { + if (sc->txpow1[i] < 0 || sc->txpow1[i] > 27) + sc->txpow1[i] = 5; + } else { + if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) + sc->txpow1[i] = 5; + } + if (sc->mac_ver > 0x5390) { + if (sc->txpow2[i] < 0 || sc->txpow2[i] > 27) + sc->txpow2[i] = 5; + } else if (sc->mac_ver < 0x5390) { + if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) + sc->txpow2[i] = 5; + } + DPRINTF(("chan %d: power1=%d, power2=%d\n", + rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i])); + } + /* Read power settings for 5GHz channels. */ + for (i = 0; i < 40; i += 2) { + run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val); + sc->txpow1[i + 14] = (int8_t)(val & 0xff); + sc->txpow1[i + 15] = (int8_t)(val >> 8); + + run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2, &val); + sc->txpow2[i + 14] = (int8_t)(val & 0xff); + sc->txpow2[i + 15] = (int8_t)(val >> 8); + } + /* Fix broken Tx power entries. */ + for (i = 0; i < 40; i++ ) { + if (sc->mac_ver != 0x5592) { + if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15) + sc->txpow1[14 + i] = 5; + if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15) + sc->txpow2[14 + i] = 5; + } + DPRINTF(("chan %d: power1=%d, power2=%d\n", + rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i], + sc->txpow2[14 + i])); + } +} + int run_read_eeprom(struct run_softc *sc) { @@ -1187,7 +1436,7 @@ run_read_eeprom(struct run_softc *sc) if (sc->mac_ver >= 0x3070) { run_read(sc, RT3070_EFUSE_CTRL, &tmp); DPRINTF(("EFUSE_CTRL=0x%08x\n", tmp)); - if (tmp & RT3070_SEL_EFUSE) + if (tmp & RT3070_SEL_EFUSE || sc->mac_ver == 0x3593) sc->sc_srom_read = run_efuse_read_2; } @@ -1206,34 +1455,44 @@ run_read_eeprom(struct run_softc *sc) ic->ic_myaddr[4] = val & 0xff; ic->ic_myaddr[5] = val >> 8; - /* read vendor BBP settings */ - for (i = 0; i < 10; i++) { - run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val); - sc->bbp[i].val = val & 0xff; - sc->bbp[i].reg = val >> 8; - DPRINTF(("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val)); - } - if (sc->mac_ver >= 0x3071) { - /* read vendor RF settings */ + if (sc->mac_ver < 0x3593) { + /* read vendor BBP settings */ for (i = 0; i < 10; i++) { - run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val); - sc->rf[i].val = val & 0xff; - sc->rf[i].reg = val >> 8; - DPRINTF(("RF%d=0x%02x\n", sc->rf[i].reg, - sc->rf[i].val)); + run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val); + sc->bbp[i].val = val & 0xff; + sc->bbp[i].reg = val >> 8; + DPRINTF(("BBP%d=0x%02x\n", sc->bbp[i].reg, + sc->bbp[i].val)); + } + if (sc->mac_ver >= 0x3071) { + /* read vendor RF settings */ + for (i = 0; i < 10; i++) { + run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, + &val); + sc->rf[i].val = val & 0xff; + sc->rf[i].reg = val >> 8; + DPRINTF(("RF%d=0x%02x\n", sc->rf[i].reg, + sc->rf[i].val)); + } } } /* read RF frequency offset from EEPROM */ - run_srom_read(sc, RT2860_EEPROM_FREQ_LEDS, &val); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_FREQ_LEDS : + RT3593_EEPROM_FREQ, &val); sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0; DPRINTF(("EEPROM freq offset %d\n", sc->freq & 0xff)); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_FREQ_LEDS : + RT3593_EEPROM_FREQ_LEDS, &val); if ((val >> 8) != 0xff) { /* read LEDs operating mode */ sc->leds = val >> 8; - run_srom_read(sc, RT2860_EEPROM_LED1, &sc->led[0]); - run_srom_read(sc, RT2860_EEPROM_LED2, &sc->led[1]); - run_srom_read(sc, RT2860_EEPROM_LED3, &sc->led[2]); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_LED1 : + RT3593_EEPROM_LED1, &sc->led[0]); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_LED2 : + RT3593_EEPROM_LED2, &sc->led[1]); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_LED3 : + RT3593_EEPROM_LED3, &sc->led[2]); } else { /* broken EEPROM, use default settings */ sc->leds = 0x01; @@ -1245,7 +1504,10 @@ run_read_eeprom(struct run_softc *sc) sc->leds, sc->led[0], sc->led[1], sc->led[2])); /* read RF information */ - run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); + if (sc->mac_ver == 0x5390 || sc->mac_ver == 0x5392) + run_srom_read(sc, 0x00, &val); + else + run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); if (val == 0xffff) { DPRINTF(("invalid EEPROM antenna info, using default\n")); if (sc->mac_ver == 0x3572) { @@ -1265,13 +1527,18 @@ run_read_eeprom(struct run_softc *sc) sc->nrxchains = 2; } } else { - sc->rf_rev = (val >> 8) & 0xf; + if (sc->mac_ver == 0x5390 || sc->mac_ver == 0x5392) { + sc->rf_rev = val; + run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); + } else + sc->rf_rev = (val >> 8) & 0xf; sc->ntxchains = (val >> 4) & 0xf; sc->nrxchains = val & 0xf; } DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n", sc->rf_rev, sc->ntxchains, sc->nrxchains)); + /* check if RF supports automatic Tx access gain control */ run_srom_read(sc, RT2860_EEPROM_CONFIG, &val); DPRINTF(("EEPROM CFG 0x%04x\n", val)); /* check if driver should patch the DAC issue */ @@ -1286,45 +1553,11 @@ run_read_eeprom(struct run_softc *sc) sc->rfswitch = val & 1; } - /* read power settings for 2GHz channels */ - for (i = 0; i < 14; i += 2) { - run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2, &val); - sc->txpow1[i + 0] = (int8_t)(val & 0xff); - sc->txpow1[i + 1] = (int8_t)(val >> 8); - - run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val); - sc->txpow2[i + 0] = (int8_t)(val & 0xff); - sc->txpow2[i + 1] = (int8_t)(val >> 8); - } - /* fix broken Tx power entries */ - for (i = 0; i < 14; i++) { - if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) - sc->txpow1[i] = 5; - if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) - sc->txpow2[i] = 5; - DPRINTF(("chan %d: power1=%d, power2=%d\n", - rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i])); - } - /* read power settings for 5GHz channels */ - for (i = 0; i < 40; i += 2) { - run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val); - sc->txpow1[i + 14] = (int8_t)(val & 0xff); - sc->txpow1[i + 15] = (int8_t)(val >> 8); - - run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2, &val); - sc->txpow2[i + 14] = (int8_t)(val & 0xff); - sc->txpow2[i + 15] = (int8_t)(val >> 8); - } - /* fix broken Tx power entries */ - for (i = 0; i < 40; i++) { - if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15) - sc->txpow1[14 + i] = 5; - if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15) - sc->txpow2[14 + i] = 5; - DPRINTF(("chan %d: power1=%d, power2=%d\n", - rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i], - sc->txpow2[14 + i])); - } + /* Read Tx power settings. */ + if (sc->mac_ver == 0x3593) + run_rt3593_get_txpower(sc); + else + run_get_txpower(sc); /* read Tx power compensation for each Tx rate */ run_srom_read(sc, RT2860_EEPROM_DELTAPWR, &val); @@ -1361,26 +1594,37 @@ run_read_eeprom(struct run_softc *sc) } /* read RSSI offsets and LNA gains from EEPROM */ - run_srom_read(sc, RT2860_EEPROM_RSSI1_2GHZ, &val); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_RSSI1_2GHZ : + RT3593_EEPROM_RSSI1_2GHZ, &val); sc->rssi_2ghz[0] = val & 0xff; /* Ant A */ sc->rssi_2ghz[1] = val >> 8; /* Ant B */ - run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_RSSI2_2GHZ : + RT3593_EEPROM_RSSI2_2GHZ, &val); if (sc->mac_ver >= 0x3070) { - /* - * On RT3070 chips (limited to 2 Rx chains), this ROM - * field contains the Tx mixer gain for the 2GHz band. - */ - if ((val & 0xff) != 0xff) - sc->txmixgain_2ghz = val & 0x7; + if (sc->mac_ver == 0x3593) { + sc->txmixgain_2ghz = 0; + sc->rssi_2ghz[2] = val & 0xff; /* Ant C */ + } else { + /* + * On RT3070 chips (limited to 2 Rx chains), this ROM + * field contains the Tx mixer gain for the 2GHz band. + */ + if ((val & 0xff) != 0xff) + sc->txmixgain_2ghz = val & 0x7; + } DPRINTF(("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz)); } else sc->rssi_2ghz[2] = val & 0xff; /* Ant C */ + if (sc->mac_ver == 0x3593) + run_srom_read(sc, RT3593_EEPROM_LNA_5GHZ, &val); sc->lna[2] = val >> 8; /* channel group 2 */ - run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_RSSI1_5GHZ : + RT3593_EEPROM_RSSI1_5GHZ, &val); sc->rssi_5ghz[0] = val & 0xff; /* Ant A */ sc->rssi_5ghz[1] = val >> 8; /* Ant B */ - run_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ, &val); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_RSSI2_5GHZ : + RT3593_EEPROM_RSSI2_5GHZ, &val); if (sc->mac_ver == 0x3572) { /* * On RT3572 chips (limited to 2 Rx chains), this ROM @@ -1391,9 +1635,14 @@ run_read_eeprom(struct run_softc *sc) DPRINTF(("tx mixer gain=%u (5GHz)\n", sc->txmixgain_5ghz)); } else sc->rssi_5ghz[2] = val & 0xff; /* Ant C */ + if (sc->mac_ver == 0x3593) { + sc->txmixgain_5ghz = 0; + run_srom_read(sc, RT3593_EEPROM_LNA_5GHZ, &val); + } sc->lna[3] = val >> 8; /* channel group 3 */ - run_srom_read(sc, RT2860_EEPROM_LNA, &val); + run_srom_read(sc, (sc->mac_ver != 0x3593) ? RT2860_EEPROM_LNA : + RT3593_EEPROM_LNA, &val); sc->lna[0] = val & 0xff; /* channel group 0 */ sc->lna[1] = val >> 8; /* channel group 1 */ @@ -1930,10 +2179,16 @@ run_rx_frame(struct run_softc *sc, uint8_t *buf, int dmalen) struct mbuf *m; uint32_t flags; uint16_t len, phy; + uint16_t rxwisize; uint8_t ant, rssi; int s; rxwi = (struct rt2860_rxwi *)buf; + rxwisize = sizeof(struct rt2860_rxwi); + if (sc->mac_ver == 0x5592) + rxwisize += sizeof(uint64_t); + else if (sc->mac_ver == 0x3593) + rxwisize += sizeof(uint32_t); len = letoh16(rxwi->len) & 0xfff; if (__predict_false(len > dmalen)) { DPRINTF(("bad RXWI length %u > %u\n", len, dmalen)); @@ -1956,7 +2211,7 @@ run_rx_frame(struct run_softc *sc, uint8_t *buf, int dmalen) return; } - wh = (struct ieee80211_frame *)(rxwi + 1); + wh = (struct ieee80211_frame *)(buf + rxwisize); rxi.rxi_flags = 0; if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED; @@ -2406,6 +2661,92 @@ run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) return error; } +void +run_iq_calib(struct run_softc *sc, u_int chan) +{ + uint16_t val; + + /* Tx0 IQ gain. */ + run_bbp_write(sc, 158, 0x2c); + if (chan <= 14) + run_efuse_read(sc, RT5390_EEPROM_IQ_GAIN_CAL_TX0_2GHZ, &val); + else if (chan <= 64) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5GHZ, &val); + } else if (chan <= 138) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5GHZ, &val); + } else if (chan <= 165) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5GHZ, + &val); + } else + val = 0; + run_bbp_write(sc, 159, val); + + /* Tx0 IQ phase. */ + run_bbp_write(sc, 158, 0x2d); + if (chan <= 14) { + run_efuse_read(sc, RT5390_EEPROM_IQ_PHASE_CAL_TX0_2GHZ, &val); + } else if (chan <= 64) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5GHZ, &val); + } else if (chan <= 138) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5GHZ, &val); + } else if (chan <= 165) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5GHZ, &val); + } else + val = 0; + run_bbp_write(sc, 159, val); + + /* Tx1 IQ gain. */ + run_bbp_write(sc, 158, 0x4a); + if (chan <= 14) { + run_efuse_read(sc, RT5390_EEPROM_IQ_GAIN_CAL_TX1_2GHZ, &val); + } else if (chan <= 64) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5GHZ, &val); + } else if (chan <= 138) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5GHZ, &val); + } else if (chan <= 165) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5GHZ, &val); + } else + val = 0; + run_bbp_write(sc, 159, val); + + /* Tx1 IQ phase. */ + run_bbp_write(sc, 158, 0x4b); + if (chan <= 14) { + run_efuse_read(sc, RT5390_EEPROM_IQ_PHASE_CAL_TX1_2GHZ, &val); + } else if (chan <= 64) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5GHZ, &val); + } else if (chan <= 138) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5GHZ, &val); + } else if (chan <= 165) { + run_efuse_read(sc, + RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5GHZ, &val); + } else + val = 0; + run_bbp_write(sc, 159, val); + + /* RF IQ compensation control. */ + run_bbp_write(sc, 158, 0x04); + run_efuse_read(sc, RT5390_EEPROM_RF_IQ_COMPENSATION_CTL, &val); + run_bbp_write(sc, 159, val); + + /* RF IQ imbalance compensation control. */ + run_bbp_write(sc, 158, 0x03); + run_efuse_read(sc, + RT5390_EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CTL, &val); + run_bbp_write(sc, 159, val); +} + void run_select_chan_group(struct run_softc *sc, int group) { @@ -2415,21 +2756,73 @@ run_select_chan_group(struct run_softc *sc, int group) run_bbp_write(sc, 62, 0x37 - sc->lna[group]); run_bbp_write(sc, 63, 0x37 - sc->lna[group]); run_bbp_write(sc, 64, 0x37 - sc->lna[group]); - run_bbp_write(sc, 86, 0x00); + if (sc->mac_ver < 0x3572) + run_bbp_write(sc, 86, 0x00); + + if (sc->mac_ver == 0x3593) { + run_bbp_write(sc, 77, 0x98); + run_bbp_write(sc, 83, (group == 0) ? 0x8a : 0x9a); + } if (group == 0) { if (sc->ext_2ghz_lna) { - run_bbp_write(sc, 82, 0x62); - run_bbp_write(sc, 75, 0x46); + if (sc->mac_ver >= 0x5390) + run_bbp_write(sc, 75, 0x52); + else { + run_bbp_write(sc, 82, 0x62); + run_bbp_write(sc, 75, 0x46); + } } else { - run_bbp_write(sc, 82, 0x84); - run_bbp_write(sc, 75, 0x50); + if (sc->mac_ver == 0x5592) { + run_bbp_write(sc, 79, 0x1c); + run_bbp_write(sc, 80, 0x0e); + run_bbp_write(sc, 81, 0x3a); + run_bbp_write(sc, 82, 0x62); + + run_bbp_write(sc, 195, 0x80); + run_bbp_write(sc, 196, 0xe0); + run_bbp_write(sc, 195, 0x81); + run_bbp_write(sc, 196, 0x1f); + run_bbp_write(sc, 195, 0x82); + run_bbp_write(sc, 196, 0x38); + run_bbp_write(sc, 195, 0x83); + run_bbp_write(sc, 196, 0x32); + run_bbp_write(sc, 195, 0x85); + run_bbp_write(sc, 196, 0x28); + run_bbp_write(sc, 195, 0x86); + run_bbp_write(sc, 196, 0x19); + } else if (sc->mac_ver >= 0x5390) + run_bbp_write(sc, 75, 0x50); + else { + run_bbp_write(sc, 82, + (sc->mac_ver == 0x3593) ? 0x62 : 0x84); + run_bbp_write(sc, 75, 0x50); + } } } else { - if (sc->mac_ver == 0x3572) + if (sc->mac_ver == 0x5592) { + run_bbp_write(sc, 79, 0x18); + run_bbp_write(sc, 80, 0x08); + run_bbp_write(sc, 81, 0x38); + run_bbp_write(sc, 82, 0x92); + + run_bbp_write(sc, 195, 0x80); + run_bbp_write(sc, 196, 0xf0); + run_bbp_write(sc, 195, 0x81); + run_bbp_write(sc, 196, 0x1e); + run_bbp_write(sc, 195, 0x82); + run_bbp_write(sc, 196, 0x28); + run_bbp_write(sc, 195, 0x83); + run_bbp_write(sc, 196, 0x20); + run_bbp_write(sc, 195, 0x85); + run_bbp_write(sc, 196, 0x7f); + run_bbp_write(sc, 195, 0x86); + run_bbp_write(sc, 196, 0x7f); + } else if (sc->mac_ver == 0x3572) run_bbp_write(sc, 82, 0x94); else - run_bbp_write(sc, 82, 0xf2); + run_bbp_write(sc, 82, + (sc->mac_ver == 0x3593) ? 0x82 : 0xf2); if (sc->ext_5ghz_lna) run_bbp_write(sc, 75, 0x46); else @@ -2443,12 +2836,18 @@ run_select_chan_group(struct run_softc *sc, int group) /* enable appropriate Power Amplifiers and Low Noise Amplifiers */ tmp = RT2860_RFTR_EN | RT2860_TRSW_EN | RT2860_LNA_PE0_EN; + if (sc->mac_ver == 0x3593) + tmp |= 1 << 29 | 1 << 28; if (sc->nrxchains > 1) tmp |= RT2860_LNA_PE1_EN; if (group == 0) { /* 2GHz */ tmp |= RT2860_PA_PE_G0_EN; if (sc->ntxchains > 1) tmp |= RT2860_PA_PE_G1_EN; + if (sc->mac_ver == 0x3593) { + if (sc->ntxchains > 2) + tmp |= 1 << 25; + } } else { /* 5GHz */ tmp |= RT2860_PA_PE_A0_EN; if (sc->ntxchains > 1) @@ -2461,6 +2860,20 @@ run_select_chan_group(struct run_softc *sc, int group) } else run_write(sc, RT2860_TX_PIN_CFG, tmp); + if (sc->mac_ver == 0x5592) { + run_bbp_write(sc, 195, 0x8d); + run_bbp_write(sc, 196, 0x1a); + } + + if (sc->mac_ver == 0x3593) { + run_read(sc, RT2860_GPIO_CTRL, &tmp); + tmp &= ~0x01010000; + if (group == 0) + tmp |= 0x00010000; + tmp = (tmp & ~0x00009090) | 0x00000090; + run_write(sc, RT2860_GPIO_CTRL, tmp); + } + /* set initial AGC value */ if (group == 0) { /* 2GHz band */ if (sc->mac_ver >= 0x3070) @@ -2468,7 +2881,9 @@ run_select_chan_group(struct run_softc *sc, int group) else agc = 0x2e + sc->lna[0]; } else { /* 5GHz band */ - if (sc->mac_ver == 0x3572) + if (sc->mac_ver == 0x5592) + agc = 0x24 + sc->lna[group] * 2; + else if (sc->mac_ver == 0x3572 || sc->mac_ver == 0x3593) agc = 0x22 + (sc->lna[group] * 5) / 3; else agc = 0x32 + (sc->lna[group] * 5) / 3; @@ -2489,46 +2904,61 @@ run_rt2870_set_chan(struct run_softc *sc, u_int chan) r2 = rfprog[i].r2; if (sc->ntxchains == 1) - r2 |= 1 << 12; /* 1T: disable Tx chain 2 */ + r2 |= 1 << 14; /* 1T: disable Tx chain 2 */ if (sc->nrxchains == 1) - r2 |= 1 << 15 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ + r2 |= 1 << 17 | 1 << 6; /* 1R: disable Rx chains 2 & 3 */ else if (sc->nrxchains == 2) - r2 |= 1 << 4; /* 2R: disable Rx chain 3 */ + r2 |= 1 << 6; /* 2R: disable Rx chain 3 */ /* use Tx power values from EEPROM */ txpow1 = sc->txpow1[i]; txpow2 = sc->txpow2[i]; + + /* Initialize RF R3 and R4. */ + r3 = rfprog[i].r3 & 0xffffc1ff; + r4 = (rfprog[i].r4 & ~(0x001f87c0)) | (sc->freq << 15); if (chan > 14) { - if (txpow1 >= 0) - txpow1 = txpow1 << 1 | 1; - else - txpow1 = (7 + txpow1) << 1; - if (txpow2 >= 0) - txpow2 = txpow2 << 1 | 1; - else - txpow2 = (7 + txpow2) << 1; - } - r3 = rfprog[i].r3 | txpow1 << 7; - r4 = rfprog[i].r4 | sc->freq << 13 | txpow2 << 4; + if (txpow1 >= 0) { + txpow1 = (txpow1 > 0xf) ? (0xf) : (txpow1); + r3 |= (txpow1 << 10) | (1 << 9); + } else { + txpow1 += 7; + + /* txpow1 is not possible larger than 15. */ + r3 |= (txpow1 << 10); + } + if (txpow2 >= 0) { + txpow2 = (txpow2 > 0xf) ? (0xf) : (txpow2); + r4 |= (txpow2 << 7) | (1 << 6); + } else { + txpow2 += 7; + r4 |= (txpow2 << 7); + } + } else { + /* Set Tx0 power. */ + r3 |= (txpow1 << 9); - run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1); - run_rt2870_rf_write(sc, RT2860_RF2, r2); - run_rt2870_rf_write(sc, RT2860_RF3, r3); - run_rt2870_rf_write(sc, RT2860_RF4, r4); + /* Set frequency offset and Tx1 power. */ + r4 |= (txpow2 << 6); + } + run_rt2870_rf_write(sc, rfprog[i].r1); + run_rt2870_rf_write(sc, r2); + run_rt2870_rf_write(sc, r3 & ~(1 << 2)); + run_rt2870_rf_write(sc, r4); DELAY(200); - run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1); - run_rt2870_rf_write(sc, RT2860_RF2, r2); - run_rt2870_rf_write(sc, RT2860_RF3, r3 | 1); - run_rt2870_rf_write(sc, RT2860_RF4, r4); + run_rt2870_rf_write(sc, rfprog[i].r1); + run_rt2870_rf_write(sc, r2); + run_rt2870_rf_write(sc, r3 | (1 << 2)); + run_rt2870_rf_write(sc, r4); DELAY(200); - run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1); - run_rt2870_rf_write(sc, RT2860_RF2, r2); - run_rt2870_rf_write(sc, RT2860_RF3, r3); - run_rt2870_rf_write(sc, RT2860_RF4, r4); + run_rt2870_rf_write(sc, rfprog[i].r1); + run_rt2870_rf_write(sc, r2); + run_rt2870_rf_write(sc, r3 & ~(1 << 2)); + run_rt2870_rf_write(sc, r4); } void @@ -2538,8 +2968,6 @@ run_rt3070_set_chan(struct run_softc *sc, u_int chan) uint8_t rf; int i; - KASSERT(chan >= 1 && chan <= 14); /* RT3070 is 2GHz only */ - /* find the settings for this channel (we know it exists) */ for (i = 0; rt2860_rf2850[i].chan != chan; i++); @@ -2548,7 +2976,12 @@ run_rt3070_set_chan(struct run_softc *sc, u_int chan) txpow2 = sc->txpow2[i]; run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n); - run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k); + + /* RT3370/RT3390: RF R3 [7:4] is not reserved bits. */ + run_rt3070_rf_read(sc, 3, &rf); + rf = (rf & ~0x0f) | rt3070_freqs[i].k; + run_rt3070_rf_write(sc, 3, rf); + run_rt3070_rf_read(sc, 6, &rf); rf = (rf & ~0x03) | rt3070_freqs[i].r; run_rt3070_rf_write(sc, 6, rf); @@ -2744,57 +3177,484 @@ run_rt3572_set_chan(struct run_softc *sc, u_int chan) } void -run_set_agc(struct run_softc *sc, uint8_t agc) +run_rt3593_set_chan(struct run_softc *sc, u_int chan) { - uint8_t bbp; + int8_t txpow1, txpow2, txpow3; + uint8_t h20mhz, rf; + int i; - if (sc->mac_ver == 0x3572) { - run_bbp_read(sc, 27, &bbp); - bbp &= ~(0x3 << 5); - run_bbp_write(sc, 27, bbp | 0 << 5); /* select Rx0 */ - run_bbp_write(sc, 66, agc); - run_bbp_write(sc, 27, bbp | 1 << 5); /* select Rx1 */ - run_bbp_write(sc, 66, agc); - } else - run_bbp_write(sc, 66, agc); -} + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++); -void -run_set_rx_antenna(struct run_softc *sc, int aux) -{ - uint32_t tmp; + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + txpow3 = (sc->ntxchains == 3) ? sc->txpow3[i] : 0; - run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, !aux); - run_read(sc, RT2860_GPIO_CTRL, &tmp); - tmp &= ~0x0808; - if (aux) - tmp |= 0x08; - run_write(sc, RT2860_GPIO_CTRL, tmp); -} + if (chan <= 14) { + run_bbp_write(sc, 25, sc->bbp25); + run_bbp_write(sc, 26, sc->bbp26); + } else { + /* Enable IQ phase correction. */ + run_bbp_write(sc, 25, 0x09); + run_bbp_write(sc, 26, 0xff); + } -int -run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) -{ - struct ieee80211com *ic = &sc->sc_ic; - u_int chan, group; + run_rt3070_rf_write(sc, 8, rt3070_freqs[i].n); + run_rt3070_rf_write(sc, 9, rt3070_freqs[i].k & 0x0f); + run_rt3070_rf_read(sc, 11, &rf); + rf = (rf & ~0x03) | (rt3070_freqs[i].r & 0x03); + run_rt3070_rf_write(sc, 11, rf); - chan = ieee80211_chan2ieee(ic, c); - if (chan == 0 || chan == IEEE80211_CHAN_ANY) - return EINVAL; + /* Set pll_idoh. */ + run_rt3070_rf_read(sc, 11, &rf); + rf &= ~0x4c; + rf |= (chan <= 14) ? 0x44 : 0x48; + run_rt3070_rf_write(sc, 11, rf); - if (sc->mac_ver == 0x3572) - run_rt3572_set_chan(sc, chan); - else if (sc->mac_ver >= 0x3070) - run_rt3070_set_chan(sc, chan); + if (chan <= 14) + rf = txpow1 & 0x1f; else - run_rt2870_set_chan(sc, chan); + rf = 0x40 | ((txpow1 & 0x18) << 1) | (txpow1 & 0x07); + run_rt3070_rf_write(sc, 53, rf); - /* determine channel group */ if (chan <= 14) - group = 0; - else if (chan <= 64) - group = 1; - else if (chan <= 128) + rf = txpow2 & 0x1f; + else + rf = 0x40 | ((txpow2 & 0x18) << 1) | (txpow2 & 0x07); + run_rt3070_rf_write(sc, 55, rf); + + if (chan <= 14) + rf = txpow3 & 0x1f; + else + rf = 0x40 | ((txpow3 & 0x18) << 1) | (txpow3 & 0x07); + run_rt3070_rf_write(sc, 54, rf); + + rf = RT3070_RF_BLOCK | RT3070_PLL_PD; + if (sc->ntxchains == 3) + rf |= RT3070_TX0_PD | RT3070_TX1_PD | RT3070_TX2_PD; + else + rf |= RT3070_TX0_PD | RT3070_TX1_PD; + rf |= RT3070_RX0_PD | RT3070_RX1_PD | RT3070_RX2_PD; + run_rt3070_rf_write(sc, 1, rf); + + run_adjust_freq_offset(sc); + + run_rt3070_rf_write(sc, 31, (chan <= 14) ? 0xa0 : 0x80); + + h20mhz = (sc->rf24_20mhz & 0x20) >> 5; + run_rt3070_rf_read(sc, 30, &rf); + rf = (rf & ~0x06) | (h20mhz << 1) | (h20mhz << 2); + run_rt3070_rf_write(sc, 30, rf); + + run_rt3070_rf_read(sc, 36, &rf); + if (chan <= 14) + rf |= 0x80; + else + rf &= ~0x80; + run_rt3070_rf_write(sc, 36, rf); + + /* Set vcolo_bs. */ + run_rt3070_rf_write(sc, 34, (chan <= 14) ? 0x3c : 0x20); + /* Set pfd_delay. */ + run_rt3070_rf_write(sc, 12, (chan <= 14) ? 0x1a : 0x12); + + /* Set vco bias current control. */ + run_rt3070_rf_read(sc, 6, &rf); + rf &= ~0xc0; + if (chan <= 14) + rf |= 0x40; + else if (chan <= 128) + rf |= 0x80; + else + rf |= 0x40; + run_rt3070_rf_write(sc, 6, rf); + + run_rt3070_rf_read(sc, 30, &rf); + rf = (rf & ~0x18) | 0x10; + run_rt3070_rf_write(sc, 30, rf); + + run_rt3070_rf_write(sc, 10, (chan <= 14) ? 0xd3 : 0xd8); + run_rt3070_rf_write(sc, 13, (chan <= 14) ? 0x12 : 0x23); + + run_rt3070_rf_read(sc, 51, &rf); + rf = (rf & ~0x03) | 0x01; + run_rt3070_rf_write(sc, 51, rf); + /* Set tx_mx1_cc. */ + run_rt3070_rf_read(sc, 51, &rf); + rf &= ~0x1c; + rf |= (chan <= 14) ? 0x14 : 0x10; + run_rt3070_rf_write(sc, 51, rf); + /* Set tx_mx1_ic. */ + run_rt3070_rf_read(sc, 51, &rf); + rf &= ~0xe0; + rf |= (chan <= 14) ? 0x60 : 0x40; + run_rt3070_rf_write(sc, 51, rf); + /* Set tx_lo1_ic. */ + run_rt3070_rf_read(sc, 49, &rf); + rf &= ~0x1c; + rf |= (chan <= 14) ? 0x0c : 0x08; + run_rt3070_rf_write(sc, 49, rf); + /* Set tx_lo1_en. */ + run_rt3070_rf_read(sc, 50, &rf); + run_rt3070_rf_write(sc, 50, rf & ~0x20); + /* Set drv_cc. */ + run_rt3070_rf_read(sc, 57, &rf); + rf &= ~0xfc; + rf |= (chan <= 14) ? 0x6c : 0x3c; + run_rt3070_rf_write(sc, 57, rf); + /* Set rx_mix1_ic, rxa_lnactr, lna_vc, lna_inbias_en and lna_en. */ + run_rt3070_rf_write(sc, 44, (chan <= 14) ? 0x93 : 0x9b); + /* Set drv_gnd_a, tx_vga_cc_a and tx_mx2_gain. */ + run_rt3070_rf_write(sc, 52, (chan <= 14) ? 0x45 : 0x05); + /* Enable VCO calibration. */ + run_rt3070_rf_read(sc, 3, &rf); + rf &= ~RT3593_VCOCAL; + rf |= (chan <= 14) ? RT3593_VCOCAL : 0xbe; + run_rt3070_rf_write(sc, 3, rf); + + if (chan <= 14) + rf = 0x23; + else if (chan <= 64) + rf = 0x36; + else if (chan <= 128) + rf = 0x32; + else + rf = 0x30; + run_rt3070_rf_write(sc, 39, rf); + if (chan <= 14) + rf = 0xbb; + else if (chan <= 64) + rf = 0xeb; + else if (chan <= 128) + rf = 0xb3; + else + rf = 0x9b; + run_rt3070_rf_write(sc, 45, rf); + + /* Set FEQ/AEQ control. */ + run_bbp_write(sc, 105, 0x34); +} + +void +run_rt5390_set_chan(struct run_softc *sc, u_int chan) +{ + int8_t txpow1, txpow2; + uint8_t rf; + int i; + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++); + + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + + run_rt3070_rf_write(sc, 8, rt3070_freqs[i].n); + run_rt3070_rf_write(sc, 9, rt3070_freqs[i].k & 0x0f); + run_rt3070_rf_read(sc, 11, &rf); + rf = (rf & ~0x03) | (rt3070_freqs[i].r & 0x03); + run_rt3070_rf_write(sc, 11, rf); + + run_rt3070_rf_read(sc, 49, &rf); + rf = (rf & ~0x3f) | (txpow1 & 0x3f); + /* The valid range of the RF R49 is 0x00 to 0x27. */ + if ((rf & 0x3f) > 0x27) + rf = (rf & ~0x3f) | 0x27; + run_rt3070_rf_write(sc, 49, rf); + + if (sc->mac_ver == 0x5392) { + run_rt3070_rf_read(sc, 50, &rf); + rf = (rf & ~0x3f) | (txpow2 & 0x3f); + /* The valid range of the RF R50 is 0x00 to 0x27. */ + if ((rf & 0x3f) > 0x27) + rf = (rf & ~0x3f) | 0x27; + run_rt3070_rf_write(sc, 50, rf); + } + + run_rt3070_rf_read(sc, 1, &rf); + rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD; + if (sc->mac_ver == 0x5392) + rf |= RT3070_RX1_PD | RT3070_TX1_PD; + run_rt3070_rf_write(sc, 1, rf); + + if (sc->mac_ver != 0x5392) { + run_rt3070_rf_read(sc, 2, &rf); + rf |= 0x80; + run_rt3070_rf_write(sc, 2, rf); + DELAY(10); + rf &= 0x7f; + run_rt3070_rf_write(sc, 2, rf); + } + + run_adjust_freq_offset(sc); + + if (sc->mac_ver == 0x5392) { + /* Fix for RT5392C. */ + if (sc->mac_rev >= 0x0223) { + if (chan <= 4) + rf = 0x0f; + else if (chan >= 5 && chan <= 7) + rf = 0x0e; + else + rf = 0x0d; + run_rt3070_rf_write(sc, 23, rf); + + if (chan <= 4) + rf = 0x0c; + else if (chan == 5) + rf = 0x0b; + else if (chan >= 6 && chan <= 7) + rf = 0x0a; + else if (chan >= 8 && chan <= 10) + rf = 0x09; + else + rf = 0x08; + run_rt3070_rf_write(sc, 59, rf); + } else { + if (chan <= 11) + rf = 0x0f; + else + rf = 0x0b; + run_rt3070_rf_write(sc, 59, rf); + } + } else { + /* Fix for RT5390F. */ + if (sc->mac_rev >= 0x0502) { + if (chan <= 11) + rf = 0x43; + else + rf = 0x23; + run_rt3070_rf_write(sc, 55, rf); + + if (chan <= 11) + rf = 0x0f; + else if (chan == 12) + rf = 0x0d; + else + rf = 0x0b; + run_rt3070_rf_write(sc, 59, rf); + } else { + run_rt3070_rf_write(sc, 55, 0x44); + run_rt3070_rf_write(sc, 59, 0x8f); + } + } + + /* Enable VCO calibration. */ + run_rt3070_rf_read(sc, 3, &rf); + rf |= RT3593_VCOCAL; + run_rt3070_rf_write(sc, 3, rf); +} + +void +run_rt5592_set_chan(struct run_softc *sc, u_int chan) +{ + const struct rt5592_freqs *freqs; + uint32_t tmp; + uint8_t reg, rf, txpow_bound; + int8_t txpow1, txpow2; + int i; + + run_read(sc, RT5592_DEBUG_INDEX, &tmp); + freqs = (tmp & RT5592_SEL_XTAL) ? + rt5592_freqs_40mhz : rt5592_freqs_20mhz; + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++, freqs++); + + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + + run_read(sc, RT3070_LDO_CFG0, &tmp); + tmp &= ~0x1c000000; + if (chan > 14) + tmp |= 0x14000000; + run_write(sc, RT3070_LDO_CFG0, tmp); + + /* N setting. */ + run_rt3070_rf_write(sc, 8, freqs->n & 0xff); + run_rt3070_rf_read(sc, 9, &rf); + rf &= ~(1 << 4); + rf |= ((freqs->n & 0x0100) >> 8) << 4; + run_rt3070_rf_write(sc, 9, rf); + + /* K setting. */ + run_rt3070_rf_read(sc, 9, &rf); + rf &= ~0x0f; + rf |= (freqs->k & 0x0f); + run_rt3070_rf_write(sc, 9, rf); + + /* Mode setting. */ + run_rt3070_rf_read(sc, 11, &rf); + rf &= ~0x0c; + rf |= ((freqs->m - 0x8) & 0x3) << 2; + run_rt3070_rf_write(sc, 11, rf); + run_rt3070_rf_read(sc, 9, &rf); + rf &= ~(1 << 7); + rf |= (((freqs->m - 0x8) & 0x4) >> 2) << 7; + run_rt3070_rf_write(sc, 9, rf); + + /* R setting. */ + run_rt3070_rf_read(sc, 11, &rf); + rf &= ~0x03; + rf |= (freqs->r - 0x1); + run_rt3070_rf_write(sc, 11, rf); + + if (chan <= 14) { + /* Initialize RF registers for 2GHZ. */ + for (i = 0; i < nitems(rt5592_2ghz_def_rf); i++) { + run_rt3070_rf_write(sc, rt5592_2ghz_def_rf[i].reg, + rt5592_2ghz_def_rf[i].val); + } + + rf = (chan <= 10) ? 0x07 : 0x06; + run_rt3070_rf_write(sc, 23, rf); + run_rt3070_rf_write(sc, 59, rf); + + run_rt3070_rf_write(sc, 55, 0x43); + + /* + * RF R49/R50 Tx power ALC code. + * G-band bit<7:6>=1:0, bit<5:0> range from 0x0 ~ 0x27. + */ + reg = 2; + txpow_bound = 0x27; + } else { + /* Initialize RF registers for 5GHZ. */ + for (i = 0; i < nitems(rt5592_5ghz_def_rf); i++) { + run_rt3070_rf_write(sc, rt5592_5ghz_def_rf[i].reg, + rt5592_5ghz_def_rf[i].val); + } + for (i = 0; i < nitems(rt5592_chan_5ghz); i++) { + if (chan >= rt5592_chan_5ghz[i].firstchan && + chan <= rt5592_chan_5ghz[i].lastchan) { + run_rt3070_rf_write(sc, rt5592_chan_5ghz[i].reg, + rt5592_chan_5ghz[i].val); + } + } + + /* + * RF R49/R50 Tx power ALC code. + * A-band bit<7:6>=1:1, bit<5:0> range from 0x0 ~ 0x2b. + */ + reg = 3; + txpow_bound = 0x2b; + } + + /* RF R49 ch0 Tx power ALC code. */ + run_rt3070_rf_read(sc, 49, &rf); + rf &= ~0xc0; + rf |= (reg << 6); + rf = (rf & ~0x3f) | (txpow1 & 0x3f); + if ((rf & 0x3f) > txpow_bound) + rf = (rf & ~0x3f) | txpow_bound; + run_rt3070_rf_write(sc, 49, rf); + + /* RF R50 ch1 Tx power ALC code. */ + run_rt3070_rf_read(sc, 50, &rf); + rf &= ~(1 << 7 | 1 << 6); + rf |= (reg << 6); + rf = (rf & ~0x3f) | (txpow2 & 0x3f); + if ((rf & 0x3f) > txpow_bound) + rf = (rf & ~0x3f) | txpow_bound; + run_rt3070_rf_write(sc, 50, rf); + + /* Enable RF_BLOCK, PLL_PD, RX0_PD, and TX0_PD. */ + run_rt3070_rf_read(sc, 1, &rf); + rf |= (RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD); + if (sc->ntxchains > 1) + rf |= RT3070_TX1_PD; + if (sc->nrxchains > 1) + rf |= RT3070_RX1_PD; + run_rt3070_rf_write(sc, 1, rf); + + run_rt3070_rf_write(sc, 6, 0xe4); + + run_rt3070_rf_write(sc, 30, 0x10); + run_rt3070_rf_write(sc, 31, 0x80); + run_rt3070_rf_write(sc, 32, 0x80); + + run_adjust_freq_offset(sc); + + /* Enable VCO calibration. */ + run_rt3070_rf_read(sc, 3, &rf); + rf |= RT3593_VCOCAL; + run_rt3070_rf_write(sc, 3, rf); +} + +void +run_set_agc(struct run_softc *sc, uint8_t agc) +{ + uint8_t bbp; + + if (sc->mac_ver == 0x3572) { + run_bbp_read(sc, 27, &bbp); + bbp &= ~(0x3 << 5); + run_bbp_write(sc, 27, bbp | 0 << 5); /* select Rx0 */ + run_bbp_write(sc, 66, agc); + run_bbp_write(sc, 27, bbp | 1 << 5); /* select Rx1 */ + run_bbp_write(sc, 66, agc); + } else + run_bbp_write(sc, 66, agc); +} + +void +run_set_rx_antenna(struct run_softc *sc, int aux) +{ + uint32_t tmp; + uint8_t bbp152; + + if (aux) { + if (sc->rf_rev == RT5390_RF_5370) { + run_bbp_read(sc, 152, &bbp152); + run_bbp_write(sc, 152, bbp152 & ~0x80); + } else { + run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0); + run_read(sc, RT2860_GPIO_CTRL, &tmp); + run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08); + } + } else { + if (sc->rf_rev == RT5390_RF_5370) { + run_bbp_read(sc, 152, &bbp152); + run_bbp_write(sc, 152, bbp152 | 0x80); + } else { + run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1); + run_read(sc, RT2860_GPIO_CTRL, &tmp); + run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808); + } + } +} + +int +run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) +{ + struct ieee80211com *ic = &sc->sc_ic; + u_int chan, group; + + chan = ieee80211_chan2ieee(ic, c); + if (chan == 0 || chan == IEEE80211_CHAN_ANY) + return EINVAL; + + if (sc->mac_ver == 0x5592) + run_rt5592_set_chan(sc, chan); + else if (sc->mac_ver >= 0x5390) + run_rt5390_set_chan(sc, chan); + else if (sc->mac_ver == 0x3593) + run_rt3593_set_chan(sc, chan); + else if (sc->mac_ver == 0x3572) + run_rt3572_set_chan(sc, chan); + else if (sc->mac_ver >= 0x3070) + run_rt3070_set_chan(sc, chan); + else + run_rt2870_set_chan(sc, chan); + + /* determine channel group */ + if (chan <= 14) + group = 0; + else if (chan <= 64) + group = 1; + else if (chan <= 128) group = 2; else group = 3; @@ -2803,6 +3663,11 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) run_select_chan_group(sc, group); DELAY(1000); + + /* Perform IQ calibration. */ + if (sc->mac_ver >= 0x5392) + run_iq_calib(sc, chan); + return 0; } @@ -2942,6 +3807,64 @@ run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain) } #endif +void +run_rt5390_bbp_init(struct run_softc *sc) +{ + int i; + uint8_t bbp; + + /* Apply maximum likelihood detection for 2 stream case. */ + run_bbp_read(sc, 105, &bbp); + if (sc->nrxchains > 1) + run_bbp_write(sc, 105, bbp | RT5390_MLD); + + /* Avoid data lost and CRC error. */ + run_bbp_read(sc, 4, &bbp); + run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL); + + if (sc->mac_ver == 0x5592) { + for (i = 0; i < nitems(rt5592_def_bbp); i++) { + run_bbp_write(sc, rt5592_def_bbp[i].reg, + rt5592_def_bbp[i].val); + } + for (i = 0; i < nitems(rt5592_bbp_r196); i++) { + run_bbp_write(sc, 195, i + 0x80); + run_bbp_write(sc, 196, rt5592_bbp_r196[i]); + } + } else { + for (i = 0; i < nitems(rt5390_def_bbp); i++) { + run_bbp_write(sc, rt5390_def_bbp[i].reg, + rt5390_def_bbp[i].val); + } + } + if (sc->mac_ver == 0x5392) { + run_bbp_write(sc, 88, 0x90); + run_bbp_write(sc, 95, 0x9a); + run_bbp_write(sc, 98, 0x12); + run_bbp_write(sc, 106, 0x12); + run_bbp_write(sc, 134, 0xd0); + run_bbp_write(sc, 135, 0xf6); + run_bbp_write(sc, 148, 0x84); + } + + run_bbp_read(sc, 152, &bbp); + run_bbp_write(sc, 152, bbp | 0x80); + + /* Fix BBP254 for RT5592C. */ + if (sc->mac_ver == 0x5592 && sc->mac_rev >= 0x0221) { + run_bbp_read(sc, 254, &bbp); + run_bbp_write(sc, 254, bbp | 0x80); + } + + /* Disable hardware antenna diversity. */ + if (sc->mac_ver == 0x5390) + run_bbp_write(sc, 154, 0); + + /* Initialize Rx CCK/OFDM frequency offset report. */ + run_bbp_write(sc, 142, 1); + run_bbp_write(sc, 143, 57); +} + int run_bbp_init(struct run_softc *sc) { @@ -2959,16 +3882,29 @@ run_bbp_init(struct run_softc *sc) return ETIMEDOUT; /* initialize BBP registers to default values */ - for (i = 0; i < nitems(rt2860_def_bbp); i++) { - run_bbp_write(sc, rt2860_def_bbp[i].reg, - rt2860_def_bbp[i].val); + if (sc->mac_ver >= 0x5390) + run_rt5390_bbp_init(sc); + else { + for (i = 0; i < nitems(rt2860_def_bbp); i++) { + run_bbp_write(sc, rt2860_def_bbp[i].reg, + rt2860_def_bbp[i].val); + } + } + + if (sc->mac_ver == 0x3593) { + run_bbp_write(sc, 79, 0x13); + run_bbp_write(sc, 80, 0x05); + run_bbp_write(sc, 81, 0x33); + run_bbp_write(sc, 86, 0x46); + run_bbp_write(sc, 137, 0x0f); } /* fix BBP84 for RT2860E */ if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) run_bbp_write(sc, 84, 0x19); - if (sc->mac_ver >= 0x3070) { + if (sc->mac_ver >= 0x3070 && (sc->mac_ver != 0x3593 && + sc->mac_ver != 0x5592)) { run_bbp_write(sc, 79, 0x13); run_bbp_write(sc, 80, 0x05); run_bbp_write(sc, 81, 0x33); @@ -2983,7 +3919,7 @@ int run_rt3070_rf_init(struct run_softc *sc) { uint32_t tmp; - uint8_t rf, target, bbp4; + uint8_t bbp4, mingain, rf, target; int i; run_rt3070_rf_read(sc, 30, &rf); @@ -3004,20 +3940,15 @@ run_rt3070_rf_init(struct run_softc *sc) rt3070_def_rf[i].val); } } - if (sc->mac_ver == 0x3572) { - run_rt3070_rf_read(sc, 6, &rf); - run_rt3070_rf_write(sc, 6, rf | 0x40); - - /* increase voltage from 1.2V to 1.35V */ + if (sc->mac_ver == 0x3070 && sc->mac_rev < 0x0201) { + /* + * Change voltage from 1.2V to 1.35V for RT3070. + * The DAC issue (RT3070_LDO_CFG0) has been fixed + * in RT3070(F). + */ run_read(sc, RT3070_LDO_CFG0, &tmp); - tmp = (tmp & ~0x1f000000) | 0x0d000000; + tmp = (tmp & ~0x0f000000) | 0x0d000000; run_write(sc, RT3070_LDO_CFG0, tmp); - if (sc->mac_rev >= 0x0211 || !sc->patch_dac) { - /* decrease voltage back to 1.2V */ - DELAY(1000); - tmp = (tmp & ~0x1f000000) | 0x01000000; - run_write(sc, RT3070_LDO_CFG0, tmp); - } } else if (sc->mac_ver == 0x3071) { run_rt3070_rf_read(sc, 6, &rf); @@ -3036,11 +3967,20 @@ run_rt3070_rf_init(struct run_softc *sc) run_read(sc, RT3070_GPIO_SWITCH, &tmp); run_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20); - } else if (sc->mac_ver == 0x3070) { + } else if (sc->mac_ver == 0x3572) { + run_rt3070_rf_read(sc, 6, &rf); + run_rt3070_rf_write(sc, 6, rf | 0x40); /* increase voltage from 1.2V to 1.35V */ run_read(sc, RT3070_LDO_CFG0, &tmp); - tmp = (tmp & ~0x0f000000) | 0x0d000000; + tmp = (tmp & ~0x1f000000) | 0x0d000000; run_write(sc, RT3070_LDO_CFG0, tmp); + + if (sc->mac_rev < 0x0211 || !sc->patch_dac) { + DELAY(1); /* wait for 1msec */ + /* decrease voltage back to 1.2V */ + tmp = (tmp & ~0x1f000000) | 0x01000000; + run_write(sc, RT3070_LDO_CFG0, tmp); + } } /* select 20MHz bandwidth */ @@ -3054,7 +3994,7 @@ run_rt3070_rf_init(struct run_softc *sc) /* select 40MHz bandwidth */ run_bbp_read(sc, 4, &bbp4); - run_bbp_write(sc, 4, (bbp4 & ~0x08) | 0x10); + run_bbp_write(sc, 4, (bbp4 & ~0x18) | 0x10); run_rt3070_rf_read(sc, 31, &rf); run_rt3070_rf_write(sc, 31, rf | 0x20); @@ -3072,7 +4012,7 @@ run_rt3070_rf_init(struct run_softc *sc) run_bbp_read(sc, 25, &sc->bbp25); run_bbp_read(sc, 26, &sc->bbp26); - } else if (sc->mac_rev < 0x0211) + } else if (sc->mac_rev < 0x0201 || sc->mac_rev < 0x0211) run_rt3070_rf_write(sc, 27, 0x03); run_read(sc, RT3070_OPT_14, &tmp); @@ -3085,7 +4025,8 @@ run_rt3070_rf_init(struct run_softc *sc) (sc->mac_ver == 0x3071 && sc->mac_rev >= 0x0211)) && !sc->ext_2ghz_lna) rf |= 0x20; /* fix for long range Rx issue */ - if (sc->txmixgain_2ghz >= 1) + mingain = (sc->mac_ver == 0x3070) ? 1 : 2; + if (sc->txmixgain_2ghz >= mingain) rf = (rf & ~0x7) | sc->txmixgain_2ghz; run_rt3070_rf_write(sc, 17, rf); } @@ -3115,6 +4056,119 @@ run_rt3070_rf_init(struct run_softc *sc) return 0; } +void +run_rt3593_rf_init(struct run_softc *sc) +{ + uint32_t tmp; + uint8_t rf; + int i; + + /* Disable the GPIO bits 4 and 7 for LNA PE control. */ + run_read(sc, RT3070_GPIO_SWITCH, &tmp); + tmp &= ~(1 << 4 | 1 << 7); + run_write(sc, RT3070_GPIO_SWITCH, tmp); + + /* Initialize RF registers to default value. */ + for (i = 0; i < nitems(rt3593_def_rf); i++) { + run_rt3070_rf_write(sc, rt3593_def_rf[i].reg, + rt3593_def_rf[i].val); + } + + /* Toggle RF R2 to initiate calibration. */ + run_rt3070_rf_write(sc, 2, RT3593_RESCAL); + + /* Initialize RF frequency offset. */ + run_adjust_freq_offset(sc); + + run_rt3070_rf_read(sc, 18, &rf); + run_rt3070_rf_write(sc, 18, rf | RT3593_AUTOTUNE_BYPASS); + + /* + * Increase voltage from 1.2V to 1.35V, wait for 1 msec to + * decrease voltage back to 1.2V. + */ + run_read(sc, RT3070_LDO_CFG0, &tmp); + tmp = (tmp & ~0x1f000000) | 0x0d000000; + run_write(sc, RT3070_LDO_CFG0, tmp); + DELAY(1); + tmp = (tmp & ~0x1f000000) | 0x01000000; + run_write(sc, RT3070_LDO_CFG0, tmp); + + sc->rf24_20mhz = 0x1f; + sc->rf24_40mhz = 0x2f; + + /* Save default BBP registers 25 and 26 values. */ + run_bbp_read(sc, 25, &sc->bbp25); + run_bbp_read(sc, 26, &sc->bbp26); + + run_read(sc, RT3070_OPT_14, &tmp); + run_write(sc, RT3070_OPT_14, tmp | 1); +} + +void +run_rt5390_rf_init(struct run_softc *sc) +{ + uint32_t tmp; + uint8_t rf; + int i; + + /* Toggle RF R2 to initiate calibration. */ + if (sc->mac_ver == 0x5390) { + run_rt3070_rf_read(sc, 2, &rf); + run_rt3070_rf_write(sc, 2, rf | RT3593_RESCAL); + DELAY(10); + run_rt3070_rf_write(sc, 2, rf & ~RT3593_RESCAL); + } else { + run_rt3070_rf_write(sc, 2, RT3593_RESCAL); + DELAY(10); + } + + /* Initialize RF registers to default value. */ + if (sc->mac_ver == 0x5592) { + for (i = 0; i < nitems(rt5592_def_rf); i++) { + run_rt3070_rf_write(sc, rt5592_def_rf[i].reg, + rt5592_def_rf[i].val); + } + /* Initialize RF frequency offset. */ + run_adjust_freq_offset(sc); + } else if (sc->mac_ver == 0x5392) { + for (i = 0; i < nitems(rt5392_def_rf); i++) { + run_rt3070_rf_write(sc, rt5392_def_rf[i].reg, + rt5392_def_rf[i].val); + } + if (sc->mac_rev >= 0x0223) { + run_rt3070_rf_write(sc, 23, 0x0f); + run_rt3070_rf_write(sc, 24, 0x3e); + run_rt3070_rf_write(sc, 51, 0x32); + run_rt3070_rf_write(sc, 53, 0x22); + run_rt3070_rf_write(sc, 56, 0xc1); + run_rt3070_rf_write(sc, 59, 0x0f); + } + } else { + for (i = 0; i < nitems(rt5390_def_rf); i++) { + run_rt3070_rf_write(sc, rt5390_def_rf[i].reg, + rt5390_def_rf[i].val); + } + if (sc->mac_rev >= 0x0502) { + run_rt3070_rf_write(sc, 6, 0xe0); + run_rt3070_rf_write(sc, 25, 0x80); + run_rt3070_rf_write(sc, 46, 0x73); + run_rt3070_rf_write(sc, 53, 0x00); + run_rt3070_rf_write(sc, 56, 0x42); + run_rt3070_rf_write(sc, 61, 0xd1); + } + } + + sc->rf24_20mhz = 0x1f; /* default value */ + sc->rf24_40mhz = (sc->mac_ver == 0x5592) ? 0 : 0x2f; + + if (sc->mac_rev < 0x0211) + run_rt3070_rf_write(sc, 27, 0x3); + + run_read(sc, RT3070_OPT_14, &tmp); + run_write(sc, RT3070_OPT_14, tmp | 1); +} + int run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target, uint8_t *val) @@ -3210,9 +4264,14 @@ run_rt3070_rf_setup(struct run_softc *sc) } else if (sc->mac_ver == 0x3071) { /* enable DC filter */ - if (sc->mac_rev >= 0x0201) + if (sc->mac_rev >= 0x0211) { run_bbp_write(sc, 103, 0xc0); + /* improve power consumption */ + run_bbp_read(sc, 31, &bbp); + run_bbp_write(sc, 31, bbp & ~0x03); + } + run_bbp_read(sc, 138, &bbp); if (sc->ntxchains == 1) bbp |= 0x20; /* turn off DAC1 */ @@ -3220,12 +4279,6 @@ run_rt3070_rf_setup(struct run_softc *sc) bbp &= ~0x02; /* turn off ADC1 */ run_bbp_write(sc, 138, bbp); - if (sc->mac_rev >= 0x0211) { - /* improve power consumption */ - run_bbp_read(sc, 31, &bbp); - run_bbp_write(sc, 31, bbp & ~0x03); - } - run_write(sc, RT2860_TX_SW_CFG1, 0); if (sc->mac_rev < 0x0211) { run_write(sc, RT2860_TX_SW_CFG2, @@ -3243,7 +4296,7 @@ run_rt3070_rf_setup(struct run_softc *sc) run_bbp_write(sc, 31, bbp & ~0x03); } - if (sc->mac_rev < 0x0211) { + if (sc->mac_rev < 0x0201) { run_write(sc, RT2860_TX_SW_CFG1, 0); run_write(sc, RT2860_TX_SW_CFG2, 0x2c); } else @@ -3260,6 +4313,123 @@ run_rt3070_rf_setup(struct run_softc *sc) } } +void +run_rt3593_rf_setup(struct run_softc *sc) +{ + uint8_t bbp, rf; + + if (sc->mac_rev >= 0x0211) { + /* Enable DC filter. */ + run_bbp_write(sc, 103, 0xc0); + } + run_write(sc, RT2860_TX_SW_CFG1, 0); + if (sc->mac_rev < 0x0211) { + run_write(sc, RT2860_TX_SW_CFG2, + sc->patch_dac ? 0x2c : 0x0f); + } else + run_write(sc, RT2860_TX_SW_CFG2, 0); + + run_rt3070_rf_read(sc, 50, &rf); + run_rt3070_rf_write(sc, 50, rf & ~RT3593_TX_LO2); + + run_rt3070_rf_read(sc, 51, &rf); + rf = (rf & ~(RT3593_TX_LO1 | 0x0c)) | + ((sc->txmixgain_2ghz & 0x07) << 2); + run_rt3070_rf_write(sc, 51, rf); + + run_rt3070_rf_read(sc, 38, &rf); + run_rt3070_rf_write(sc, 38, rf & ~RT5390_RX_LO1); + + run_rt3070_rf_read(sc, 39, &rf); + run_rt3070_rf_write(sc, 39, rf & ~RT5390_RX_LO2); + + run_rt3070_rf_read(sc, 1, &rf); + run_rt3070_rf_write(sc, 1, rf & ~(RT3070_RF_BLOCK | RT3070_PLL_PD)); + + run_rt3070_rf_read(sc, 30, &rf); + rf = (rf & ~0x18) | 0x10; + run_rt3070_rf_write(sc, 30, rf); + + /* Apply maximum likelihood detection for 2 stream case. */ + run_bbp_read(sc, 105, &bbp); + if (sc->nrxchains > 1) + run_bbp_write(sc, 105, bbp | RT5390_MLD); + + /* Avoid data lost and CRC error. */ + run_bbp_read(sc, 4, &bbp); + run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL); + + run_bbp_write(sc, 92, 0x02); + run_bbp_write(sc, 82, 0x82); + run_bbp_write(sc, 106, 0x05); + run_bbp_write(sc, 104, 0x92); + run_bbp_write(sc, 88, 0x90); + run_bbp_write(sc, 148, 0xc8); + run_bbp_write(sc, 47, 0x48); + run_bbp_write(sc, 120, 0x50); + + run_bbp_write(sc, 163, 0x9d); + + /* SNR mapping. */ + run_bbp_write(sc, 142, 0x06); + run_bbp_write(sc, 143, 0xa0); + run_bbp_write(sc, 142, 0x07); + run_bbp_write(sc, 143, 0xa1); + run_bbp_write(sc, 142, 0x08); + run_bbp_write(sc, 143, 0xa2); + + run_bbp_write(sc, 31, 0x08); + run_bbp_write(sc, 68, 0x0b); + run_bbp_write(sc, 105, 0x04); +} + +void +run_rt5390_rf_setup(struct run_softc *sc) +{ + uint8_t bbp, rf; + + if (sc->mac_rev >= 0x0211) { + /* Enable DC filter. */ + run_bbp_write(sc, 103, 0xc0); + + if (sc->mac_ver != 0x5592) { + /* Improve power consumption. */ + run_bbp_read(sc, 31, &bbp); + run_bbp_write(sc, 31, bbp & ~0x03); + } + } + + run_bbp_read(sc, 138, &bbp); + if (sc->ntxchains == 1) + bbp |= 0x20; /* turn off DAC1 */ + if (sc->nrxchains == 1) + bbp &= ~0x02; /* turn off ADC1 */ + run_bbp_write(sc, 138, bbp); + + run_rt3070_rf_read(sc, 38, &rf); + run_rt3070_rf_write(sc, 38, rf & ~RT5390_RX_LO1); + + run_rt3070_rf_read(sc, 39, &rf); + run_rt3070_rf_write(sc, 39, rf & ~RT5390_RX_LO2); + + /* Avoid data lost and CRC error. */ + run_bbp_read(sc, 4, &bbp); + run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL); + + run_rt3070_rf_read(sc, 30, &rf); + rf = (rf & ~0x18) | 0x10; + run_rt3070_rf_write(sc, 30, rf); + + if (sc->mac_ver != 0x5592) { + run_write(sc, RT2860_TX_SW_CFG1, 0); + if (sc->mac_rev < 0x0211) { + run_write(sc, RT2860_TX_SW_CFG2, + sc->patch_dac ? 0x2c : 0x0f); + } else + run_write(sc, RT2860_TX_SW_CFG2, 0); + } +} + int run_txrx_enable(struct run_softc *sc) { @@ -3305,6 +4475,20 @@ run_txrx_enable(struct run_softc *sc) return 0; } +void +run_adjust_freq_offset(struct run_softc *sc) +{ + uint8_t rf, tmp; + + run_rt3070_rf_read(sc, 17, &rf); + tmp = rf; + rf = (rf & ~0x7f) | (sc->freq & 0x7f); + rf = MIN(rf, 0x5f); + + if (tmp != rf) + run_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf); +} + int run_init(struct ifnet *ifp) { @@ -3395,7 +4579,23 @@ run_init(struct ifnet *ifp) run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344); run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa); - if (sc->mac_ver >= 0x3070) { + if (sc->mac_ver >= 0x5390) { + run_write(sc, RT2860_TX_SW_CFG0, + 4 << RT2860_DLY_PAPE_EN_SHIFT | 4); + if (sc->mac_ver >= 0x5392) { + run_write(sc, RT2860_MAX_LEN_CFG, 0x00002fff); + if (sc->mac_ver == 0x5592) { + run_write(sc, RT2860_HT_FBK_CFG1, 0xedcba980); + run_write(sc, RT2860_TXOP_HLDR_ET, 0x00000082); + } else { + run_write(sc, RT2860_HT_FBK_CFG1, 0xedcb4980); + run_write(sc, RT2860_LG_FBK_CFG0, 0xedcba322); + } + } + } else if (sc->mac_ver == 0x3593) { + run_write(sc, RT2860_TX_SW_CFG0, + 4 << RT2860_DLY_PAPE_EN_SHIFT | 2); + } else if (sc->mac_ver >= 0x3070) { /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ run_write(sc, RT2860_TX_SW_CFG0, 4 << RT2860_DLY_PAPE_EN_SHIFT); @@ -3424,6 +4624,7 @@ run_init(struct ifnet *ifp) goto fail; } + /* abort TSF synchronization */ run_read(sc, RT2860_BCN_TIME_CFG, &tmp); tmp &= ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | RT2860_TBTT_TIMER_EN); @@ -3449,14 +4650,16 @@ run_init(struct ifnet *ifp) run_write(sc, RT2860_WMM_TXOP1_CFG, 48 << 16 | 96); /* write vendor-specific BBP values (from EEPROM) */ - for (i = 0; i < 8; i++) { - if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff) - continue; - run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val); + if (sc->mac_ver < 0x3593) { + for (i = 0; i < 8; i++) { + if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff) + continue; + run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val); + } } /* select Main antenna for 1T1R devices */ - if (sc->rf_rev == RT3070_RF_3020) + if (sc->rf_rev == RT3070_RF_3020 || sc->rf_rev == RT5390_RF_5370) run_set_rx_antenna(sc, 0); /* send LEDs operating mode to microcontroller */ @@ -3464,7 +4667,11 @@ run_init(struct ifnet *ifp) (void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]); (void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]); - if (sc->mac_ver >= 0x3070) + if (sc->mac_ver >= 0x5390) + run_rt5390_rf_init(sc); + else if (sc->mac_ver == 0x3593) + run_rt3593_rf_init(sc); + else if (sc->mac_ver >= 0x3070) run_rt3070_rf_init(sc); /* disable non-existing Rx chains */ @@ -3482,7 +4689,11 @@ run_init(struct ifnet *ifp) bbp1 &= ~(1 << 3 | 1 << 4); run_bbp_write(sc, 1, bbp1); - if (sc->mac_ver >= 0x3070) + if (sc->mac_ver >= 0x5390) + run_rt5390_rf_setup(sc); + else if (sc->mac_ver == 0x3593) + run_rt3593_rf_setup(sc); + else if (sc->mac_ver >= 0x3070) run_rt3070_rf_setup(sc); /* select default channel */ @@ -3549,6 +4760,23 @@ run_stop(struct ifnet *ifp, int disable) usb_wait_task(sc->sc_udev, &sc->sc_task); splx(s); + /* Disable Tx/Rx DMA. */ + run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp); + tmp &= ~(RT2860_RX_DMA_EN | RT2860_TX_DMA_EN); + run_write(sc, RT2860_WPDMA_GLO_CFG, tmp); + + for (ntries = 0; ntries < 100; ntries++) { + if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0) + break; + if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) + break; + DELAY(10); + } + if (ntries == 100) { + printf("%s: timeout waiting for DMA engine\n", + sc->sc_dev.dv_xname); + } + /* disable Tx/Rx */ run_read(sc, RT2860_MAC_SYS_CTRL, &tmp); tmp &= ~(RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); diff --git a/sys/dev/usb/if_runvar.h b/sys/dev/usb/if_runvar.h index 34576e38958..aad304cee16 100644 --- a/sys/dev/usb/if_runvar.h +++ b/sys/dev/usb/if_runvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_runvar.h,v 1.9 2013/04/15 09:23:01 mglocker Exp $ */ +/* $OpenBSD: if_runvar.h,v 1.10 2014/05/24 10:10:17 stsp Exp $ */ /*- * Copyright (c) 2008,2009 Damien Bergamini @@ -28,7 +28,7 @@ /* NB: "11" is the maximum number of padding bytes needed for Tx */ #define RUN_MAX_TXSZ \ (sizeof (struct rt2870_txd) + \ - sizeof (struct rt2860_rxwi) + \ + sizeof (struct rt2860_txwi) + \ MCLBYTES + 11) #define RUN_TX_TIMEOUT 5000 /* ms */ @@ -36,7 +36,7 @@ #define RUN_RX_RING_COUNT 1 #define RUN_TX_RING_COUNT 8 -#define RT2870_WCID_MAX 253 +#define RT2870_WCID_MAX 64 #define RUN_AID2WCID(aid) ((aid) & 0xff) struct run_rx_radiotap_header { @@ -144,7 +144,7 @@ struct run_softc { uint16_t mac_ver; uint16_t mac_rev; - uint8_t rf_rev; + uint16_t rf_rev; uint8_t freq; uint8_t ntxchains; uint8_t nrxchains; @@ -164,6 +164,7 @@ struct run_softc { uint8_t txmixgain_5ghz; int8_t txpow1[54]; int8_t txpow2[54]; + int8_t txpow3[54]; int8_t rssi_2ghz[3]; int8_t rssi_5ghz[3]; uint8_t lna[4];