| 1 | --- a/drivers/net/wireless/rt2x00/rt2800lib.c |
| 2 | +++ b/drivers/net/wireless/rt2x00/rt2800lib.c |
| 3 | @@ -2250,15 +2250,18 @@ static void rt2800_config_channel(struct |
| 4 | /* |
| 5 | * Change BBP settings |
| 6 | */ |
| 7 | + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); |
| 8 | + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); |
| 9 | + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); |
| 10 | + |
| 11 | if (rt2x00_rt(rt2x00dev, RT3352)) { |
| 12 | rt2800_bbp_write(rt2x00dev, 27, 0x0); |
| 13 | rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); |
| 14 | rt2800_bbp_write(rt2x00dev, 27, 0x20); |
| 15 | rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); |
| 16 | + rt2800_bbp_write(rt2x00dev, 86, 0x38); |
| 17 | + rt2800_bbp_write(rt2x00dev, 83, 0x6a); |
| 18 | } else { |
| 19 | - rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); |
| 20 | - rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); |
| 21 | - rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); |
| 22 | rt2800_bbp_write(rt2x00dev, 86, 0); |
| 23 | } |
| 24 | |
| 25 | @@ -3890,6 +3893,7 @@ static int rt2800_init_rfcsr(struct rt2x |
| 26 | * Init RF calibration. |
| 27 | */ |
| 28 | if (rt2x00_rt(rt2x00dev, RT3290) || |
| 29 | + rt2x00_rt(rt2x00dev, RT3352) || |
| 30 | rt2x00_rt(rt2x00dev, RT5390) || |
| 31 | rt2x00_rt(rt2x00dev, RT5392)) { |
| 32 | rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); |
| 33 | @@ -4076,6 +4080,10 @@ static int rt2800_init_rfcsr(struct rt2x |
| 34 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); |
| 35 | return 0; |
| 36 | } else if (rt2x00_rt(rt2x00dev, RT3352)) { |
| 37 | + int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0, |
| 38 | + &rt2x00dev->cap_flags); |
| 39 | + int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1, |
| 40 | + &rt2x00dev->cap_flags); |
| 41 | rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); |
| 42 | rt2800_rfcsr_write(rt2x00dev, 1, 0x23); |
| 43 | rt2800_rfcsr_write(rt2x00dev, 2, 0x50); |
| 44 | @@ -4109,15 +4117,30 @@ static int rt2800_init_rfcsr(struct rt2x |
| 45 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); |
| 46 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); |
| 47 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); |
| 48 | - rt2800_rfcsr_write(rt2x00dev, 34, 0x01); |
| 49 | + rfcsr = 0x01; |
| 50 | + if (!tx0_int_pa) |
| 51 | + rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1); |
| 52 | + if (!tx1_int_pa) |
| 53 | + rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1); |
| 54 | + rt2800_rfcsr_write(rt2x00dev, 34, rfcsr ); |
| 55 | rt2800_rfcsr_write(rt2x00dev, 35, 0x03); |
| 56 | rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); |
| 57 | rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); |
| 58 | rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); |
| 59 | rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); |
| 60 | rt2800_rfcsr_write(rt2x00dev, 40, 0x33); |
| 61 | - rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); |
| 62 | - rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); |
| 63 | + rfcsr = 0x52; |
| 64 | + if (tx0_int_pa) { |
| 65 | + rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1); |
| 66 | + rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1); |
| 67 | + } |
| 68 | + rt2800_rfcsr_write(rt2x00dev, 41, rfcsr); |
| 69 | + rfcsr = 0x52; |
| 70 | + if (tx1_int_pa) { |
| 71 | + rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1); |
| 72 | + rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1); |
| 73 | + } |
| 74 | + rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); |
| 75 | rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); |
| 76 | rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); |
| 77 | rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); |
| 78 | @@ -4125,15 +4148,20 @@ static int rt2800_init_rfcsr(struct rt2x |
| 79 | rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); |
| 80 | rt2800_rfcsr_write(rt2x00dev, 48, 0x14); |
| 81 | rt2800_rfcsr_write(rt2x00dev, 49, 0x00); |
| 82 | - rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); |
| 83 | - rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); |
| 84 | - rt2800_rfcsr_write(rt2x00dev, 52, 0x00); |
| 85 | - rt2800_rfcsr_write(rt2x00dev, 53, 0x52); |
| 86 | - rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); |
| 87 | - rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); |
| 88 | - rt2800_rfcsr_write(rt2x00dev, 56, 0x00); |
| 89 | - rt2800_rfcsr_write(rt2x00dev, 57, 0x52); |
| 90 | - rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); |
| 91 | + rfcsr = 0x2d; |
| 92 | + if (!tx0_int_pa) |
| 93 | + rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1); |
| 94 | + if (!tx1_int_pa) |
| 95 | + rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1); |
| 96 | + rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); |
| 97 | + rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52)); |
| 98 | + rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0)); |
| 99 | + rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2)); |
| 100 | + rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0)); |
| 101 | + rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52)); |
| 102 | + rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0)); |
| 103 | + rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49)); |
| 104 | + rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0)); |
| 105 | rt2800_rfcsr_write(rt2x00dev, 59, 0x00); |
| 106 | rt2800_rfcsr_write(rt2x00dev, 60, 0x00); |
| 107 | rt2800_rfcsr_write(rt2x00dev, 61, 0x00); |
| 108 | @@ -4894,7 +4922,8 @@ static int rt2800_init_eeprom(struct rt2 |
| 109 | /* |
| 110 | * Detect if this device has Bluetooth co-existence. |
| 111 | */ |
| 112 | - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) |
| 113 | + if (!rt2x00_rt(rt2x00dev, RT3352) && |
| 114 | + rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) |
| 115 | __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags); |
| 116 | |
| 117 | /* |
| 118 | @@ -4923,6 +4952,22 @@ static int rt2800_init_eeprom(struct rt2 |
| 119 | EIRP_MAX_TX_POWER_LIMIT) |
| 120 | __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); |
| 121 | |
| 122 | + /* |
| 123 | + * Detect if device uses internal or external PA |
| 124 | + */ |
| 125 | + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); |
| 126 | + |
| 127 | + if (rt2x00_rt(rt2x00dev, RT3352)) { |
| 128 | + if (!rt2x00_get_field16(eeprom, |
| 129 | + EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) |
| 130 | + __set_bit(CAPABILITY_INTERNAL_PA_TX0, |
| 131 | + &rt2x00dev->cap_flags); |
| 132 | + if (!rt2x00_get_field16(eeprom, |
| 133 | + EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352)) |
| 134 | + __set_bit(CAPABILITY_INTERNAL_PA_TX1, |
| 135 | + &rt2x00dev->cap_flags); |
| 136 | + } |
| 137 | + |
| 138 | return 0; |
| 139 | } |
| 140 | |
| 141 | --- a/drivers/net/wireless/rt2x00/rt2800.h |
| 142 | +++ b/drivers/net/wireless/rt2x00/rt2800.h |
| 143 | @@ -2117,6 +2117,12 @@ struct mac_iveiv_entry { |
| 144 | #define RFCSR31_RX_CALIB FIELD8(0x7f) |
| 145 | |
| 146 | /* |
| 147 | + * RFCSR 34: |
| 148 | + */ |
| 149 | +#define RFCSR34_TX0_EXT_PA FIELD8(0x04) |
| 150 | +#define RFCSR34_TX1_EXT_PA FIELD8(0x08) |
| 151 | + |
| 152 | +/* |
| 153 | * RFCSR 38: |
| 154 | */ |
| 155 | #define RFCSR38_RX_LO1_EN FIELD8(0x20) |
| 156 | @@ -2127,6 +2133,18 @@ struct mac_iveiv_entry { |
| 157 | #define RFCSR39_RX_LO2_EN FIELD8(0x80) |
| 158 | |
| 159 | /* |
| 160 | + * RFCSR 41: |
| 161 | + */ |
| 162 | +#define RFCSR41_BIT1 FIELD8(0x01) |
| 163 | +#define RFCSR41_BIT4 FIELD8(0x08) |
| 164 | + |
| 165 | +/* |
| 166 | + * RFCSR 42: |
| 167 | + */ |
| 168 | +#define RFCSR42_BIT1 FIELD8(0x01) |
| 169 | +#define RFCSR42_BIT4 FIELD8(0x08) |
| 170 | + |
| 171 | +/* |
| 172 | * RFCSR 49: |
| 173 | */ |
| 174 | #define RFCSR49_TX FIELD8(0x3f) |
| 175 | @@ -2135,6 +2153,8 @@ struct mac_iveiv_entry { |
| 176 | * RFCSR 50: |
| 177 | */ |
| 178 | #define RFCSR50_TX FIELD8(0x3f) |
| 179 | +#define RFCSR50_TX0_EXT_PA FIELD8(0x02) |
| 180 | +#define RFCSR50_TX1_EXT_PA FIELD8(0x10) |
| 181 | |
| 182 | /* |
| 183 | * RF registers |
| 184 | @@ -2222,6 +2242,8 @@ struct mac_iveiv_entry { |
| 185 | * INTERNAL_TX_ALC: 0: disable, 1: enable |
| 186 | * BT_COEXIST: 0: disable, 1: enable |
| 187 | * DAC_TEST: 0: disable, 1: enable |
| 188 | + * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352) |
| 189 | + * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352) |
| 190 | */ |
| 191 | #define EEPROM_NIC_CONF1 0x001b |
| 192 | #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) |
| 193 | @@ -2239,6 +2261,8 @@ struct mac_iveiv_entry { |
| 194 | #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) |
| 195 | #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) |
| 196 | #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) |
| 197 | +#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352 FIELD16(0x4000) |
| 198 | +#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352 FIELD16(0x8000) |
| 199 | |
| 200 | /* |
| 201 | * EEPROM frequency |
| 202 | --- a/drivers/net/wireless/rt2x00/rt2x00.h |
| 203 | +++ b/drivers/net/wireless/rt2x00/rt2x00.h |
| 204 | @@ -742,6 +742,8 @@ enum rt2x00_capability_flags { |
| 205 | CAPABILITY_DOUBLE_ANTENNA, |
| 206 | CAPABILITY_BT_COEXIST, |
| 207 | CAPABILITY_VCO_RECALIBRATION, |
| 208 | + CAPABILITY_INTERNAL_PA_TX0, |
| 209 | + CAPABILITY_INTERNAL_PA_TX1, |
| 210 | }; |
| 211 | |
| 212 | /* |
| 213 | |