2013-06-28 19:13:14

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 00/19] rt2x00: add experimental support for RT3593

This patch-set implements experiemental support for the
RT3593 chipset. The patches are tested on the Linksys
AE3000 USB device only, however other USB devices which
are using the RT3573 chips might work as well.

The patch-set depends on the following series:
'rt2x00: rt2800lib: add support for extended EEPROM of three-cain devices'

Gabor Juhos (19):
rt2x00: rt2800lib: add BBP register initialization for RT3593
rt2x00: rt2800lib: add RFCSR register initialization for RT3593
rt2x00: rt2800lib: add BBP post initialization for RT3593
rt2x00: rt2800lib: add TX power configuration for RT3593
rt2x00: rt2800lib: fix BBP1_TX_ANTENNA field configuration for 3T
devices
rt2x00: rt2800lib: fix antenna configuration for RT3593
rt2x00: rt2800lib: add rt2800_txpower_to_dev helper
rt2x00: rt2800lib: fix default TX power values for RT3593
rt2x00: rt2800lib: introduce rt2800_get_txmixer_gain_{24,5}g helpers
rt2x00: rt2800lib: hardcode TX mixer gain values for RT3593
rt2x00: rt2x00lib: fix LNA_A[12] gain values for RT3593
rt2x00: rt2800lib: add default_power3 field for three-chain devices
rt2x00: rt2800lib: add rf_vals for RF3053
rt2x00: rt2800lib: add channel configuration for RF3053
rt2x00: rt2800lib: enable VCO recalibration for RF3053
rt2x00: rt2800lib: enable RF3053 support
rt2x00: rt2800lib: enable RT3593 support
rt2x00: rt2800usb: use correct [RT]XWI size for RT3593
rt2x00: rt2800usb: add USB device ID for Linksys AE3000

drivers/net/wireless/rt2x00/rt2800.h | 186 ++++-
drivers/net/wireless/rt2x00/rt2800lib.c | 1210 ++++++++++++++++++++++++++++++-
drivers/net/wireless/rt2x00/rt2800usb.c | 6 +-
drivers/net/wireless/rt2x00/rt2x00.h | 1 +
4 files changed, 1358 insertions(+), 45 deletions(-)

--
1.7.10



2013-06-28 19:13:15

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 02/19] rt2x00: rt2800lib: add RFCSR register initialization for RT3593

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

References:
NICInitRT3593RFRegisters in chips/rt3593.c
RT3593LoadRFNormalModeSetup in chips/rt3593.c

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 10 +++
drivers/net/wireless/rt2x00/rt2800lib.c | 122 +++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 02bc80d..47aceae 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2093,6 +2093,10 @@ struct mac_iveiv_entry {
#define RFCSR17_R FIELD8(0x20)
#define RFCSR17_CODE FIELD8(0x7f)

+/* RFCSR 18 */
+#define RFCSR18_XO_TUNE_BYPASS FIELD8(0x40)
+
+
/*
* RFCSR 20:
*/
@@ -2174,6 +2178,12 @@ struct mac_iveiv_entry {
*/
#define RFCSR50_TX FIELD8(0x3f)
#define RFCSR50_EP FIELD8(0xc0)
+/* bits for RT3593*/
+#define RFCSR50_TX_LO2_EN FIELD8(0x10)
+
+/* RFCSR 51 */
+/* bits for RT3593*/
+#define RFCSR51_BITS24 FIELD8(0x1c)

/*
* RF registers
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 32ecd1a..0041b2c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4964,6 +4964,42 @@ static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev)
}
}

+static void rt2800_normal_mode_setup_3593(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+ u8 rfcsr;
+ u8 tx_gain;
+
+ rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR50_TX_LO2_EN, 0);
+ rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
+ tx_gain = rt2x00_get_field8(drv_data->txmixer_gain_24g,
+ RFCSR17_TXMIXER_GAIN);
+ rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, tx_gain);
+ rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
+ rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0);
+ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
+ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+ /* TODO: enable stream mode */
+}
+
static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev)
{
u8 reg;
@@ -5346,6 +5382,89 @@ static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev)
rt2800_normal_mode_setup_3xxx(rt2x00dev);
}

+static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+ u32 reg;
+ u8 rfcsr;
+
+ /* Disable GPIO #4 and #7 function for LAN PE control */
+ rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
+ rt2x00_set_field32(&reg, GPIO_SWITCH_4, 0);
+ rt2x00_set_field32(&reg, GPIO_SWITCH_7, 0);
+ rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+
+ /* Initialize default register values */
+ rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
+ rt2800_rfcsr_write(rt2x00dev, 3, 0x80);
+ rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
+ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
+ rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
+ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
+ rt2800_rfcsr_write(rt2x00dev, 11, 0x40);
+ rt2800_rfcsr_write(rt2x00dev, 12, 0x4e);
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
+ rt2800_rfcsr_write(rt2x00dev, 18, 0x40);
+ rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
+ rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+ rt2800_rfcsr_write(rt2x00dev, 32, 0x78);
+ rt2800_rfcsr_write(rt2x00dev, 33, 0x3b);
+ rt2800_rfcsr_write(rt2x00dev, 34, 0x3c);
+ rt2800_rfcsr_write(rt2x00dev, 35, 0xe0);
+ rt2800_rfcsr_write(rt2x00dev, 38, 0x86);
+ rt2800_rfcsr_write(rt2x00dev, 39, 0x23);
+ rt2800_rfcsr_write(rt2x00dev, 44, 0xd3);
+ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
+ rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
+ rt2800_rfcsr_write(rt2x00dev, 49, 0x8e);
+ rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
+ rt2800_rfcsr_write(rt2x00dev, 51, 0x75);
+ rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
+ rt2800_rfcsr_write(rt2x00dev, 53, 0x18);
+ rt2800_rfcsr_write(rt2x00dev, 54, 0x18);
+ rt2800_rfcsr_write(rt2x00dev, 55, 0x18);
+ rt2800_rfcsr_write(rt2x00dev, 56, 0xdb);
+ rt2800_rfcsr_write(rt2x00dev, 57, 0x6e);
+
+ /* Initiate calibration */
+ /* TODO: use rt2800_rf_init_calibration ? */
+ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
+ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
+
+ rt2800_adjust_freq_offset(rt2x00dev);
+
+ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR18_XO_TUNE_BYPASS, 1);
+ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr);
+
+ rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+ rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+ rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+ rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+ usleep_range(1000, 1500);
+ rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+ rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
+ rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+
+ /* Set initial values for RX filter calibration */
+ drv_data->calibration_bw20 = 0x1f;
+ drv_data->calibration_bw40 = 0x2f;
+
+ /* Save BBP 25 & 26 values for later use in channel switching */
+ rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25);
+ rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
+
+ rt2800_led_open_drain_enable(rt2x00dev);
+ rt2800_normal_mode_setup_3593(rt2x00dev);
+
+ /* TODO: post BBP initialization */
+
+ /* TODO: enable stream mode support */
+}
+
static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
{
rt2800_rf_init_calibration(rt2x00dev, 2);
@@ -5571,6 +5690,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
case RT3390:
rt2800_init_rfcsr_3390(rt2x00dev);
break;
+ case RT3593:
+ rt2800_init_rfcsr_3593(rt2x00dev);
+ break;
case RT3572:
rt2800_init_rfcsr_3572(rt2x00dev);
break;
--
1.7.10


2013-06-29 11:37:36

by Gabor Juhos

[permalink] [raw]
Subject: Re: [PATCH 19/19] rt2x00: rt2800usb: add USB device ID for Linksys AE3000

2013.06.29. 0:26 keltezéssel, Xose Vazquez Perez írta:
> Gabor Juhos wrote:
>
>> diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
>> index c24c1fd..6136871 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
>> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
>> @@ -1183,6 +1183,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
>> { USB_DEVICE(0x04bb, 0x0944) },
>> /* Linksys */
>> { USB_DEVICE(0x13b1, 0x002f) },
>> + { USB_DEVICE(0x13b1, 0x003b) },
>> { USB_DEVICE(0x1737, 0x0079) },
>> /* Ralink */
>> { USB_DEVICE(0x148f, 0x3572) },
>> --
>
> You should separate RT3573 and RT3572 devices.
> Rename CONFIG_RT2800USB_RT35XX to CONFIG_RT2800USB_RT3572
> and do a new CONFIG_RT2800USB_RT3573 section.

Renaming a config option is not a good idea IMO. I would simply add a
CONFIG_RT2800USB_RT3573 symbol which depends on CONFIG_RT2800USB_RT35XX instead.

> And also you can add safely this usb-ids. All of them
> are RT3573 devices:
>
> 0x1b75, 0x7733 AirLive 450Mbps Wireless-N Dual Band USB Adapter
> 0x0b05, 0x17bc ASUS USB-N66 450Mbps Dual Band USB Adapter
> 0x0b05, 0x17ad ASUS USB-N66 Dual Band N Network Adapter
> 0x050d, 0x1103 Belkin Wireless Adapter
> 0x148f, 0xf301 Cameo Ralink3573 3x3 single band USB dongle
> 0x7392, 0x7733 Edimax
> 0x0e66, 0x0020 Hawking HD45U Dual Band USB Wireless-N Adapter
> 0x0e66, 0x0021 Hawking HD45U Dual Band Wls-450N Adapter
> 0x04bb, 0x094e I-O DATA WN-AG450U Wireless LAN Adapter
> 0x0789, 0x016b Logitec LAN-W450AN/U2
> 0x0846, 0x9012 NETGEAR WNDA4100 N900 Wireless Dual Band USB Adapter
> 0x0846, 0x9019 NETGEAR WNDA4200D Wireless Dual Band USB Adapter
> 0x2019, 0xed19 Planex GW-USDual450
> 0x148f, 0x3573 Ralink 802.11n USB Wireless LAN Card
> 0x0df6, 0x0067 Sitecom Wireless Dualband Network Adapter N750 X6
> 0x0df6, 0x006a Sitecom Wireless Dualband Network Adapter N900 X7
> 0x0586, 0x3421 ZyXEL Dual-Band Wireless N450 USB Adapter

I did not test any of these devices and I don't even know from where did you get
these IDs. Only a subset of these IDs is present in the Ralink driver.

If you feel that all of these can be added safely, you can send a follow-up patch.

-Gabor

2013-06-28 19:13:17

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 15/19] rt2x00: rt2800lib: enable VCO recalibration for RF3053

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index ab67dba..0a0f96f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4196,6 +4196,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
break;
case RF3290:
+ case RF3053:
case RF5360:
case RF5370:
case RF5372:
@@ -7596,6 +7597,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
case RF3022:
case RF3320:
case RF3052:
+ case RF3053:
case RF3290:
case RF5360:
case RF5370:
--
1.7.10


2013-06-28 19:13:17

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 11/19] rt2x00: rt2x00lib: fix LNA_A[12] gain values for RT3593

The LNA_A[12] gain values are stored at a different
offset in the EEPROM on RT3593 based devices. However
the current code unconditionally reads those values
from the location used by other chipsets.

Fix the code to use the correct EEPROM offset.

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

References:
RT3593_EEPROM_RSSI2_OFFSET_ALNAGAIN1_24G_READ in include/chip/rt3593.h
RT3593_EEPROM_RSSI2_OFFSET_ALNAGAIN2_5G_READ in include/chip/rt3593.h

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 4 +++
drivers/net/wireless/rt2x00/rt2800lib.c | 55 ++++++++++++++++++++++++-------
2 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 69749ba5..7688e15 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2672,6 +2672,10 @@ enum rt2800_eeprom_word {
#define EEPROM_BBP_VALUE FIELD16(0x00ff)
#define EEPROM_BBP_REG_ID FIELD16(0xff00)

+/* EEPROM_EXT_LNA2 */
+#define EEPROM_EXT_LNA2_A1 FIELD16(0x00ff)
+#define EEPROM_EXT_LNA2_A2 FIELD16(0xff00)
+
/*
* EEPROM IQ Calibration, unlike other entries those are byte addresses.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index ea9b98d..f079d70 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1827,11 +1827,25 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
} else if (libconf->rf.channel <= 128) {
- rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
- lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
+ if (rt2x00_rt(rt2x00dev, RT3593)) {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom,
+ EEPROM_EXT_LNA2_A1);
+ } else {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom,
+ EEPROM_RSSI_BG2_LNA_A1);
+ }
} else {
- rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
- lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
+ if (rt2x00_rt(rt2x00dev, RT3593)) {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom,
+ EEPROM_EXT_LNA2_A2);
+ } else {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom,
+ EEPROM_RSSI_A2_LNA_A2);
+ }
}

rt2x00dev->lna_gain = lna_gain;
@@ -6489,10 +6503,12 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
- if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
- rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
- rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
- default_lna_gain);
+ if (!rt2x00_rt(rt2x00dev, RT3593)) {
+ if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
+ default_lna_gain);
+ }
rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);

drv_data->txmixer_gain_5g = rt2800_get_txmixer_gain_5g(rt2x00dev);
@@ -6507,12 +6523,27 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
- if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
- rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
- rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
- default_lna_gain);
+ if (!rt2x00_rt(rt2x00dev, RT3593)) {
+ if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
+ default_lna_gain);
+ }
rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);

+ if (rt2x00_rt(rt2x00dev, RT3593)) {
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word);
+ if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_EXT_LNA2_A1,
+ default_lna_gain);
+ if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A2) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_EXT_LNA2_A2) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_EXT_LNA2_A1,
+ default_lna_gain);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_EXT_LNA2, word);
+ }
+
return 0;
}

--
1.7.10


2013-06-28 19:13:26

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 13/19] rt2x00: rt2800lib: add rf_vals for RF3053

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

References:
FreqItems3053 in chips/rt3593.c

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 70 +++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index bc21a57..6dcf03a 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -6962,6 +6962,72 @@ static const struct rf_channel rf_vals_5592_xtal40[] = {
{196, 83, 0, 12, 1},
};

+static const struct rf_channel rf_vals_3053[] = {
+ /* Channel, N, R, K */
+ {1, 241, 2, 2},
+ {2, 241, 2, 7},
+ {3, 242, 2, 2},
+ {4, 242, 2, 7},
+ {5, 243, 2, 2},
+ {6, 243, 2, 7},
+ {7, 244, 2, 2},
+ {8, 244, 2, 7},
+ {9, 245, 2, 2},
+ {10, 245, 2, 7},
+ {11, 246, 2, 2},
+ {12, 246, 2, 7},
+ {13, 247, 2, 2},
+ {14, 248, 2, 4},
+
+ {36, 0x56, 0, 4},
+ {38, 0x56, 0, 6},
+ {40, 0x56, 0, 8},
+ {44, 0x57, 0, 0},
+ {46, 0x57, 0, 2},
+ {48, 0x57, 0, 4},
+ {52, 0x57, 0, 8},
+ {54, 0x57, 0, 10},
+ {56, 0x58, 0, 0},
+ {60, 0x58, 0, 4},
+ {62, 0x58, 0, 6},
+ {64, 0x58, 0, 8},
+
+ {100, 0x5B, 0, 8},
+ {102, 0x5B, 0, 10},
+ {104, 0x5C, 0, 0},
+ {108, 0x5C, 0, 4},
+ {110, 0x5C, 0, 6},
+ {112, 0x5C, 0, 8},
+
+ /* NOTE: Channel 114 has been removed intentionally.
+ * The EEPROM contains no TX power values for that,
+ * and it is disabled in the vendor driver as well.
+ */
+
+ {116, 0x5D, 0, 0},
+ {118, 0x5D, 0, 2},
+ {120, 0x5D, 0, 4},
+ {124, 0x5D, 0, 8},
+ {126, 0x5D, 0, 10},
+ {128, 0x5E, 0, 0},
+ {132, 0x5E, 0, 4},
+ {134, 0x5E, 0, 6},
+ {136, 0x5E, 0, 8},
+ {140, 0x5F, 0, 0},
+
+ {149, 0x5F, 0, 9},
+ {151, 0x5F, 0, 11},
+ {153, 0x60, 0, 1},
+ {157, 0x60, 0, 5},
+ {159, 0x60, 0, 7},
+ {161, 0x60, 0, 9},
+ {165, 0x61, 0, 1},
+ {167, 0x61, 0, 3},
+ {169, 0x61, 0, 5},
+ {171, 0x61, 0, 7},
+ {173, 0x61, 0, 9},
+};
+
static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
@@ -7053,6 +7119,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_3x);
spec->channels = rf_vals_3x;
+ } else if (rt2x00_rf(rt2x00dev, RF3053)) {
+ spec->supported_bands |= SUPPORT_BAND_5GHZ;
+ spec->num_channels = ARRAY_SIZE(rf_vals_3053);
+ spec->channels = rf_vals_3053;
} else if (rt2x00_rf(rt2x00dev, RF5592)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;

--
1.7.10


2013-06-28 19:13:27

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 16/19] rt2x00: rt2800lib: enable RF3053 support

Support for the RF3053 has been implemented in
the previous changes, so it is safe to mark it
supported in the driver.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 0a0f96f..b7fa8f9 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -6949,6 +6949,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
case RF3021:
case RF3022:
case RF3052:
+ case RF3053:
case RF3290:
case RF3320:
case RF3322:
--
1.7.10


2013-06-28 19:13:14

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 01/19] rt2x00: rt2800lib: add BBP register initialization for RT3593

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

References:
NICInitRT3593BbpRegisters in chips/rt3593.c
NICInitBBP in common/rtmp_init.c
NICInitAsicFromEEPROM in common/rtmp_init.c

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 6f58ceb..32ecd1a 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4505,6 +4505,22 @@ static void rt2800_init_bbp_3572(struct rt2x00_dev *rt2x00dev)
rt2800_disable_unused_dac_adc(rt2x00dev);
}

+static void rt2800_init_bbp_3593(struct rt2x00_dev *rt2x00dev)
+{
+ rt2800_init_bbp_early(rt2x00dev);
+
+ rt2800_bbp_write(rt2x00dev, 79, 0x13);
+ rt2800_bbp_write(rt2x00dev, 80, 0x05);
+ rt2800_bbp_write(rt2x00dev, 81, 0x33);
+ rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+
+ rt2800_bbp_write(rt2x00dev, 84, 0x19);
+
+ /* Enable DC filter */
+ if (rt2x00_rt_rev_gte(rt2x00dev, RT3593, REV_RT3593E))
+ rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+}
+
static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
{
int ant, div_mode;
@@ -4720,6 +4736,9 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
case RT3572:
rt2800_init_bbp_3572(rt2x00dev);
break;
+ case RT3593:
+ rt2800_init_bbp_3593(rt2x00dev);
+ return;
case RT5390:
case RT5392:
rt2800_init_bbp_53xx(rt2x00dev);
--
1.7.10


2013-06-28 19:13:22

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 05/19] rt2x00: rt2800lib: fix BBP1_TX_ANTENNA field configuration for 3T devices

The field must be set to 2 instead of 0 for
devices with three TX chains.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b6f456c..6f6f48f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1764,7 +1764,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
break;
case 3:
- rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
+ rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
break;
}

--
1.7.10


2013-06-28 19:13:30

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 19/19] rt2x00: rt2800usb: add USB device ID for Linksys AE3000

The Linksys AE3000 device is based on the RT3573
chipset. The support for this chipset is available
already, and the AE3000 device works with the driver.

Only managed mode works correctly at the moment,
for AP mode additional changes are needed in the
driver.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800usb.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index c24c1fd..6136871 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1183,6 +1183,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x04bb, 0x0944) },
/* Linksys */
{ USB_DEVICE(0x13b1, 0x002f) },
+ { USB_DEVICE(0x13b1, 0x003b) },
{ USB_DEVICE(0x1737, 0x0079) },
/* Ralink */
{ USB_DEVICE(0x148f, 0x3572) },
--
1.7.10


2013-06-28 19:13:16

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 08/19] rt2x00: rt2800lib: fix default TX power values for RT3593

The TX power values in the EEPROM are using
a different format for the RT3593 chip. The
default TX power value uses bits 0..4 only.
Bits 5..8 contains value for fine grained
power control. Additionally, the lower and
upper limits of the TX power values are the
same for both bands.

Improve the rt2800_txpower_to_dev function,
in order to compute the correct default power
values for the RT3593 chip as well.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 7 +++++++
drivers/net/wireless/rt2x00/rt2800lib.c | 7 +++++++
2 files changed, 14 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index d3e8f6d..69749ba5 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2603,6 +2603,10 @@ enum rt2800_eeprom_word {
#define EEPROM_TXPOWER_A_1 FIELD16(0x00ff)
#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)

+/* EEPROM_TXPOWER_{A,G} fields for RT3593 */
+#define EEPROM_TXPOWER_ALC FIELD8(0x1f)
+#define EEPROM_TXPOWER_FINE_CTRL FIELD8(0xe0)
+
/*
* EEPROM temperature compensation boundaries 802.11A
* MINUS4: If the actual TSSI is below this boundary, tx power needs to be
@@ -2884,6 +2888,9 @@ enum rt2800_eeprom_word {
#define MAX_A_TXPOWER 15
#define DEFAULT_TXPOWER 5

+#define MIN_A_TXPOWER_3593 0
+#define MAX_A_TXPOWER_3593 31
+
#define TXPOWER_G_FROM_DEV(__txpower) \
((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 9d05273..cbc3dc3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2729,8 +2729,15 @@ static char rt2800_txpower_to_dev(struct rt2x00_dev *rt2x00dev,
unsigned int channel,
char txpower)
{
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC);
+
if (channel <= 14)
return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
+
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ return clamp_t(char, txpower, MIN_A_TXPOWER_3593,
+ MAX_A_TXPOWER_3593);
else
return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
}
--
1.7.10


2013-06-30 09:03:10

by Andreas Hartmann

[permalink] [raw]
Subject: Re: [PATCH 00/19] rt2x00: add experimental support for RT3593

Hello Gabor,

bad guy is back again :-)

Gabor Juhos wrote:
> This patch-set implements experiemental support for the
> RT3593 chipset. The patches are tested on the Linksys
> AE3000 USB device only, however other USB devices which
> are using the RT3573 chips might work as well.

I did another test with raspberry pi. Same network parameters (2.4 GHz,
40MHz, eap-tls, ccmp/ccmp) but this time w/o any other load on the
wlan. But there is a reinforced-concrete floor between AP and STA.

netperf with rt2800usb / backports-20130617 / kernel 3.6.11 gives:

MIGRATED TCP STREAM TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.39 28.16
MIGRATED TCP MAERTS TEST from 0.0.0.0 () port 0 AF_INET from server port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.00 30.23
TCP SENDFILE TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.35 27.69


Same with DPO_RT5572_LinuxSTA_2.6.1.3_20121022

MIGRATED TCP STREAM TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.01 97.95
MIGRATED TCP MAERTS TEST from 0.0.0.0 () port 0 AF_INET from server port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.01 121.69
TCP SENDFILE TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.01 82.75

If you compare the result w/ rt2800usb/AE3000 with rt2800usb/rt3572[1]
you can see: no difference :-(.


Kind regards,
Andreas

[1] http://comments.gmane.org/gmane.linux.drivers.rt2x00.user/1992

2013-06-28 21:42:12

by Xose Vazquez Perez

[permalink] [raw]
Subject: Re: [PATCH 02/19] rt2x00: rt2800lib: add RFCSR register initialization for RT3593

Gabor Juhos wrote:

> Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
> driver.

There is a more recent version: DPO_RT5572_LinuxSTA_2.6.1.3_20121022

> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 32ecd1a..0041b2c 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> [...]
> + /* Initialize default register values */
> + rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
> + rt2800_rfcsr_write(rt2x00dev, 3, 0x80);

from ./20120911_RT3573_Linux_STA_v2.5.0.0_Rev1_DPO/chips/rt3593.c

{RF_R02, 0x80}

but it was deleted in ./DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt3593.c

Was it deliberate ? or a mistake ??

2013-06-28 19:13:27

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 18/19] rt2x00: rt2800usb: use correct [RT]XWI size for RT3593

The RT3593 chipset requires different [RT]XWI size
values. Modify the driver to use the correct values.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 1 +
drivers/net/wireless/rt2x00/rt2800usb.c | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 1ba797b..a313241 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2814,6 +2814,7 @@ enum rt2800_eeprom_word {
#define TXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32))

#define RXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32))
+#define RXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32))
#define RXWI_DESC_SIZE_6WORDS (6 * sizeof(__le32))

/*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 840833b..c24c1fd 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -854,7 +854,10 @@ static void rt2800usb_queue_init(struct data_queue *queue)
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
unsigned short txwi_size, rxwi_size;

- if (rt2x00_rt(rt2x00dev, RT5592)) {
+ if (rt2x00_rt(rt2x00dev, RT3593)) {
+ txwi_size = TXWI_DESC_SIZE_4WORDS;
+ rxwi_size = RXWI_DESC_SIZE_5WORDS;
+ } else if (rt2x00_rt(rt2x00dev, RT5592)) {
txwi_size = TXWI_DESC_SIZE_5WORDS;
rxwi_size = RXWI_DESC_SIZE_6WORDS;
} else {
--
1.7.10


2013-06-29 05:44:46

by Andreas Hartmann

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 01/19] rt2x00: rt2800lib: add BBP register initialization for RT3593

Hi Gabor,

thanks for your submission. I tried to test it, but stuck at the problem
mentioned below.


Regards,
Andreas

Gabor Juhos wrote:
> Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
> driver.
>
> References:
> NICInitRT3593BbpRegisters in chips/rt3593.c
> NICInitBBP in common/rtmp_init.c
> NICInitAsicFromEEPROM in common/rtmp_init.c
>
> Signed-off-by: Gabor Juhos <[email protected]>
> ---
> drivers/net/wireless/rt2x00/rt2800lib.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 6f58ceb..32ecd1a 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -4505,6 +4505,22 @@ static void rt2800_init_bbp_3572(struct rt2x00_dev *rt2x00dev)
> rt2800_disable_unused_dac_adc(rt2x00dev);
> }
>
> +static void rt2800_init_bbp_3593(struct rt2x00_dev *rt2x00dev)
> +{
> + rt2800_init_bbp_early(rt2x00dev);
> +
> + rt2800_bbp_write(rt2x00dev, 79, 0x13);
> + rt2800_bbp_write(rt2x00dev, 80, 0x05);
> + rt2800_bbp_write(rt2x00dev, 81, 0x33);
> + rt2800_bbp_write(rt2x00dev, 137, 0x0f);
> +
> + rt2800_bbp_write(rt2x00dev, 84, 0x19);
> +
> + /* Enable DC filter */
> + if (rt2x00_rt_rev_gte(rt2x00dev, RT3593, REV_RT3593E))

Where is REV_RT3593E defined?

/tmp/backports-20130617/drivers/net/wireless/rt2x00/rt2800lib.c: In
function ?rt2800_init_bbp_3593?:
/tmp/backports-20130617/drivers/net/wireless/rt2x00/rt2800lib.c:5325:43:
error: ?REV_RT3593E? undeclared (first use in this function)


Thanks,
Andreas

2013-06-28 19:13:17

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 04/19] rt2x00: rt2800lib: add TX power configuration for RT3593

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

References:
RTMPReadTxPwrPerRateExt in chips/rt3593.c
RT3593_AsicGetTxPowerOffset in chips/rt3593.c

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 116 +++++++++
drivers/net/wireless/rt2x00/rt2800lib.c | 425 ++++++++++++++++++++++++++++++-
2 files changed, 538 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 47aceae..7b7caeb 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1083,6 +1083,15 @@
#define TX_PWR_CFG_0_9MBS FIELD32(0x00f00000)
#define TX_PWR_CFG_0_12MBS FIELD32(0x0f000000)
#define TX_PWR_CFG_0_18MBS FIELD32(0xf0000000)
+/* bits for 3T devices */
+#define TX_PWR_CFG_0_CCK1_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_0_CCK1_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_0_CCK5_CH0 FIELD32(0x00000f00)
+#define TX_PWR_CFG_0_CCK5_CH1 FIELD32(0x0000f000)
+#define TX_PWR_CFG_0_OFDM6_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_0_OFDM6_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_0_OFDM12_CH0 FIELD32(0x0f000000)
+#define TX_PWR_CFG_0_OFDM12_CH1 FIELD32(0xf0000000)

/*
* TX_PWR_CFG_1:
@@ -1096,6 +1105,15 @@
#define TX_PWR_CFG_1_MCS1 FIELD32(0x00f00000)
#define TX_PWR_CFG_1_MCS2 FIELD32(0x0f000000)
#define TX_PWR_CFG_1_MCS3 FIELD32(0xf0000000)
+/* bits for 3T devices */
+#define TX_PWR_CFG_1_OFDM24_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_1_OFDM24_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_1_OFDM48_CH0 FIELD32(0x00000f00)
+#define TX_PWR_CFG_1_OFDM48_CH1 FIELD32(0x0000f000)
+#define TX_PWR_CFG_1_MCS0_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_1_MCS0_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_1_MCS2_CH0 FIELD32(0x0f000000)
+#define TX_PWR_CFG_1_MCS2_CH1 FIELD32(0xf0000000)

/*
* TX_PWR_CFG_2:
@@ -1109,6 +1127,15 @@
#define TX_PWR_CFG_2_MCS9 FIELD32(0x00f00000)
#define TX_PWR_CFG_2_MCS10 FIELD32(0x0f000000)
#define TX_PWR_CFG_2_MCS11 FIELD32(0xf0000000)
+/* bits for 3T devices */
+#define TX_PWR_CFG_2_MCS4_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_2_MCS4_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_2_MCS6_CH0 FIELD32(0x00000f00)
+#define TX_PWR_CFG_2_MCS6_CH1 FIELD32(0x0000f000)
+#define TX_PWR_CFG_2_MCS8_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_2_MCS8_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_2_MCS10_CH0 FIELD32(0x0f000000)
+#define TX_PWR_CFG_2_MCS10_CH1 FIELD32(0xf0000000)

/*
* TX_PWR_CFG_3:
@@ -1122,6 +1149,15 @@
#define TX_PWR_CFG_3_UKNOWN2 FIELD32(0x00f00000)
#define TX_PWR_CFG_3_UKNOWN3 FIELD32(0x0f000000)
#define TX_PWR_CFG_3_UKNOWN4 FIELD32(0xf0000000)
+/* bits for 3T devices */
+#define TX_PWR_CFG_3_MCS12_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_3_MCS12_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_3_MCS14_CH0 FIELD32(0x00000f00)
+#define TX_PWR_CFG_3_MCS14_CH1 FIELD32(0x0000f000)
+#define TX_PWR_CFG_3_STBC0_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_3_STBC0_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_3_STBC2_CH0 FIELD32(0x0f000000)
+#define TX_PWR_CFG_3_STBC2_CH1 FIELD32(0xf0000000)

/*
* TX_PWR_CFG_4:
@@ -1131,6 +1167,11 @@
#define TX_PWR_CFG_4_UKNOWN6 FIELD32(0x000000f0)
#define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00)
#define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000)
+/* bits for 3T devices */
+#define TX_PWR_CFG_3_STBC4_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_3_STBC4_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_3_STBC6_CH0 FIELD32(0x00000f00)
+#define TX_PWR_CFG_3_STBC6_CH1 FIELD32(0x0000f000)

/*
* TX_PIN_CFG:
@@ -1452,6 +1493,81 @@
*/
#define EXP_ACK_TIME 0x1380

+/* TX_PWR_CFG_5 */
+#define TX_PWR_CFG_5 0x1384
+#define TX_PWR_CFG_5_MCS16_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_5_MCS16_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_5_MCS16_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_5_MCS18_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_5_MCS18_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_5_MCS18_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_6 */
+#define TX_PWR_CFG_6 0x1388
+#define TX_PWR_CFG_6_MCS20_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_6_MCS20_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_6_MCS20_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_6_MCS22_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_6_MCS22_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_6_MCS22_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_0_EXT */
+#define TX_PWR_CFG_0_EXT 0x1390
+#define TX_PWR_CFG_0_EXT_CCK1_CH2 FIELD32(0x0000000f)
+#define TX_PWR_CFG_0_EXT_CCK5_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_0_EXT_OFDM6_CH2 FIELD32(0x000f0000)
+#define TX_PWR_CFG_0_EXT_OFDM12_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_1_EXT */
+#define TX_PWR_CFG_1_EXT 0x1394
+#define TX_PWR_CFG_1_EXT_OFDM24_CH2 FIELD32(0x0000000f)
+#define TX_PWR_CFG_1_EXT_OFDM48_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_1_EXT_MCS0_CH2 FIELD32(0x000f0000)
+#define TX_PWR_CFG_1_EXT_MCS2_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_2_EXT */
+#define TX_PWR_CFG_2_EXT 0x1398
+#define TX_PWR_CFG_2_EXT_MCS4_CH2 FIELD32(0x0000000f)
+#define TX_PWR_CFG_2_EXT_MCS6_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_2_EXT_MCS8_CH2 FIELD32(0x000f0000)
+#define TX_PWR_CFG_2_EXT_MCS10_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_3_EXT */
+#define TX_PWR_CFG_3_EXT 0x139c
+#define TX_PWR_CFG_3_EXT_MCS12_CH2 FIELD32(0x0000000f)
+#define TX_PWR_CFG_3_EXT_MCS14_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_3_EXT_STBC0_CH2 FIELD32(0x000f0000)
+#define TX_PWR_CFG_3_EXT_STBC2_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_4_EXT */
+#define TX_PWR_CFG_4_EXT 0x13a0
+#define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f)
+#define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00)
+
+/* TX_PWR_CFG_7 */
+#define TX_PWR_CFG_7 0x13d4
+#define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_7_OFDM54_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_7_OFDM54_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_7_MCS7_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_7_MCS7_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_7_MCS7_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_8 */
+#define TX_PWR_CFG_8 0x13d8
+#define TX_PWR_CFG_8_MCS15_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_8_MCS15_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_8_MCS15_CH2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_8_MCS23_CH0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_8_MCS23_CH1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_8_MCS23_CH2 FIELD32(0x0f000000)
+
+/* TX_PWR_CFG_9 */
+#define TX_PWR_CFG_9 0x13dc
+#define TX_PWR_CFG_9_STBC7_CH0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_9_STBC7_CH1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00)
+
/*
* RX_FILTER_CFG: RX configuration register.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 87b7f94..b6f456c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -3121,6 +3121,9 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
u8 eirp_txpower_criterion;
u8 reg_limit;

+ if (rt2x00_rt(rt2x00dev, RT3593))
+ return min_t(u8, txpower, 0xc);
+
if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
/*
* Check if eirp txpower exceed txpower_limit.
@@ -3156,6 +3159,412 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
return min_t(u8, txpower, 0xc);
}

+
+enum {
+ TX_PWR_CFG_0_IDX,
+ TX_PWR_CFG_1_IDX,
+ TX_PWR_CFG_2_IDX,
+ TX_PWR_CFG_3_IDX,
+ TX_PWR_CFG_4_IDX,
+ TX_PWR_CFG_5_IDX,
+ TX_PWR_CFG_6_IDX,
+ TX_PWR_CFG_7_IDX,
+ TX_PWR_CFG_8_IDX,
+ TX_PWR_CFG_9_IDX,
+ TX_PWR_CFG_0_EXT_IDX,
+ TX_PWR_CFG_1_EXT_IDX,
+ TX_PWR_CFG_2_EXT_IDX,
+ TX_PWR_CFG_3_EXT_IDX,
+ TX_PWR_CFG_4_EXT_IDX,
+ TX_PWR_CFG_IDX_COUNT,
+};
+
+static void rt2800_config_txpower_rt3593(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_channel *chan,
+ int power_level)
+{
+ u8 txpower;
+ u16 eeprom;
+ u32 regs[TX_PWR_CFG_IDX_COUNT];
+ unsigned int offset;
+ enum ieee80211_band band = chan->band;
+ int delta;
+ int i;
+
+ memset(regs, '\0', sizeof(regs));
+
+ /* TODO: adapt TX power reduction from the rt28xx code */
+
+ /* calculate temperature compensation delta */
+ delta = rt2800_get_gain_calibration_delta(rt2x00dev);
+
+ if (band == IEEE80211_BAND_5GHZ)
+ offset = 16;
+ else
+ offset = 0;
+
+ if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
+ offset += 8;
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset, &eeprom);
+
+ /* CCK 1MBS,2MBS */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 1, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_CCK1_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_CCK1_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
+ TX_PWR_CFG_0_EXT_CCK1_CH2, txpower);
+
+ /* CCK 5.5MBS,11MBS */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 1, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_CCK5_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_CCK5_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
+ TX_PWR_CFG_0_EXT_CCK5_CH2, txpower);
+
+ /* OFDM 6MBS,9MBS */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_OFDM6_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_OFDM6_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
+ TX_PWR_CFG_0_EXT_OFDM6_CH2, txpower);
+
+ /* OFDM 12MBS,18MBS */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_OFDM12_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
+ TX_PWR_CFG_0_OFDM12_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
+ TX_PWR_CFG_0_EXT_OFDM12_CH2, txpower);
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset + 1, &eeprom);
+
+ /* OFDM 24MBS,36MBS */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_OFDM24_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_OFDM24_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
+ TX_PWR_CFG_1_EXT_OFDM24_CH2, txpower);
+
+ /* OFDM 48MBS */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_OFDM48_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_OFDM48_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
+ TX_PWR_CFG_1_EXT_OFDM48_CH2, txpower);
+
+ /* OFDM 54MBS */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
+ TX_PWR_CFG_7_OFDM54_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
+ TX_PWR_CFG_7_OFDM54_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
+ TX_PWR_CFG_7_OFDM54_CH2, txpower);
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset + 2, &eeprom);
+
+ /* MCS 0,1 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_MCS0_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_MCS0_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
+ TX_PWR_CFG_1_EXT_MCS0_CH2, txpower);
+
+ /* MCS 2,3 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_MCS2_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
+ TX_PWR_CFG_1_MCS2_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
+ TX_PWR_CFG_1_EXT_MCS2_CH2, txpower);
+
+ /* MCS 4,5 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS4_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS4_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
+ TX_PWR_CFG_2_EXT_MCS4_CH2, txpower);
+
+ /* MCS 6 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS6_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS6_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
+ TX_PWR_CFG_2_EXT_MCS6_CH2, txpower);
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset + 3, &eeprom);
+
+ /* MCS 7 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
+ TX_PWR_CFG_7_MCS7_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
+ TX_PWR_CFG_7_MCS7_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
+ TX_PWR_CFG_7_MCS7_CH2, txpower);
+
+ /* MCS 8,9 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS8_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS8_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
+ TX_PWR_CFG_2_EXT_MCS8_CH2, txpower);
+
+ /* MCS 10,11 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS10_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
+ TX_PWR_CFG_2_MCS10_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
+ TX_PWR_CFG_2_EXT_MCS10_CH2, txpower);
+
+ /* MCS 12,13 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_MCS12_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_MCS12_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
+ TX_PWR_CFG_3_EXT_MCS12_CH2, txpower);
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset + 4, &eeprom);
+
+ /* MCS 14 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_MCS14_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_MCS14_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
+ TX_PWR_CFG_3_EXT_MCS14_CH2, txpower);
+
+ /* MCS 15 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
+ TX_PWR_CFG_8_MCS15_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
+ TX_PWR_CFG_8_MCS15_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
+ TX_PWR_CFG_8_MCS15_CH2, txpower);
+
+ /* MCS 16,17 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
+ TX_PWR_CFG_5_MCS16_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
+ TX_PWR_CFG_5_MCS16_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
+ TX_PWR_CFG_5_MCS16_CH2, txpower);
+
+ /* MCS 18,19 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
+ TX_PWR_CFG_5_MCS18_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
+ TX_PWR_CFG_5_MCS18_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
+ TX_PWR_CFG_5_MCS18_CH2, txpower);
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset + 5, &eeprom);
+
+ /* MCS 20,21 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
+ TX_PWR_CFG_6_MCS20_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
+ TX_PWR_CFG_6_MCS20_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
+ TX_PWR_CFG_6_MCS20_CH2, txpower);
+
+ /* MCS 22 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
+ TX_PWR_CFG_6_MCS22_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
+ TX_PWR_CFG_6_MCS22_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
+ TX_PWR_CFG_6_MCS22_CH2, txpower);
+
+ /* MCS 23 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
+ TX_PWR_CFG_8_MCS23_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
+ TX_PWR_CFG_8_MCS23_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
+ TX_PWR_CFG_8_MCS23_CH2, txpower);
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset + 6, &eeprom);
+
+ /* STBC, MCS 0,1 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_STBC0_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_STBC0_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
+ TX_PWR_CFG_3_EXT_STBC0_CH2, txpower);
+
+ /* STBC, MCS 2,3 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_STBC2_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
+ TX_PWR_CFG_3_STBC2_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
+ TX_PWR_CFG_3_EXT_STBC2_CH2, txpower);
+
+ /* STBC, MCS 4,5 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_4_EXT_IDX], TX_PWR_CFG_RATE0,
+ txpower);
+
+ /* STBC, MCS 6 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE2, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE3, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_4_EXT_IDX], TX_PWR_CFG_RATE2,
+ txpower);
+
+ /* read the next four txpower values */
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ offset + 7, &eeprom);
+
+ /* STBC, MCS 7 */
+ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
+ txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
+ txpower, delta);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
+ TX_PWR_CFG_9_STBC7_CH0, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
+ TX_PWR_CFG_9_STBC7_CH1, txpower);
+ rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
+ TX_PWR_CFG_9_STBC7_CH2, txpower);
+
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, regs[TX_PWR_CFG_0_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, regs[TX_PWR_CFG_1_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, regs[TX_PWR_CFG_2_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, regs[TX_PWR_CFG_3_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, regs[TX_PWR_CFG_4_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_5, regs[TX_PWR_CFG_5_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_6, regs[TX_PWR_CFG_6_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_7, regs[TX_PWR_CFG_7_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_8, regs[TX_PWR_CFG_8_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, regs[TX_PWR_CFG_9_IDX]);
+
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_0_EXT,
+ regs[TX_PWR_CFG_0_EXT_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_1_EXT,
+ regs[TX_PWR_CFG_1_EXT_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_2_EXT,
+ regs[TX_PWR_CFG_2_EXT_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_3_EXT,
+ regs[TX_PWR_CFG_3_EXT_IDX]);
+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_4_EXT,
+ regs[TX_PWR_CFG_4_EXT_IDX]);
+
+ for (i = 0; i < TX_PWR_CFG_IDX_COUNT; i++)
+ rt2x00_dbg(rt2x00dev,
+ "band:%cGHz, BW:%c0MHz, TX_PWR_CFG_%d%s = %08lx\n",
+ (band == IEEE80211_BAND_5GHZ) ? '5' : '2',
+ (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) ?
+ '4' : '2',
+ (i > TX_PWR_CFG_9_IDX) ?
+ (i - TX_PWR_CFG_9_IDX - 1) : i,
+ (i > TX_PWR_CFG_9_IDX) ? "_EXT" : "",
+ (unsigned long) regs[i]);
+}
+
/*
* We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and
* BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values,
@@ -3165,9 +3574,9 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
* EEPROM_TXPOWER_BYRATE offset. We adjust them and BBP R1 settings according to
* current conditions (i.e. band, bandwidth, temperature, user settings).
*/
-static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_channel *chan,
- int power_level)
+static void rt2800_config_txpower_rt28xx(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_channel *chan,
+ int power_level)
{
u8 txpower, r1;
u16 eeprom;
@@ -3339,6 +3748,16 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
}
}

+static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_channel *chan,
+ int power_level)
+{
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
+ else
+ rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
+}
+
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
{
rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan,
--
1.7.10


2013-06-28 19:13:18

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 17/19] rt2x00: rt2800lib: enable RT3593 support

Support for the RT3593 has been implemented in
the previous changes, so it is safe to mark it
supported in the driver.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b7fa8f9..d20c9f3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7637,6 +7637,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
case RT3352:
case RT3390:
case RT3572:
+ case RT3593:
case RT5390:
case RT5392:
case RT5592:
--
1.7.10


2013-06-28 19:13:25

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 10/19] rt2x00: rt2800lib: hardcode TX mixer gain values for RT3593

The reference code uses hardcoded zero TX mixer gain value
for RT3593. Do the same in the rt2x00 driver.

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
NICReadEEPROMParameters in common/rtmp_init.c

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 6f23eb0..ea9b98d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -6366,6 +6366,9 @@ static u8 rt2800_get_txmixer_gain_24g(struct rt2x00_dev *rt2x00dev)
{
u16 word;

+ if (rt2x00_rt(rt2x00dev, RT3593))
+ return 0;
+
rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
if ((word & 0x00ff) != 0x00ff)
return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
@@ -6377,6 +6380,9 @@ static u8 rt2800_get_txmixer_gain_5g(struct rt2x00_dev *rt2x00dev)
{
u16 word;

+ if (rt2x00_rt(rt2x00dev, RT3593))
+ return 0;
+
rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
if ((word & 0x00ff) != 0x00ff)
return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
--
1.7.10


2013-06-29 11:24:19

by Gabor Juhos

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 01/19] rt2x00: rt2800lib: add BBP register initialization for RT3593

Hi Adnreas,

> thanks for your submission. I tried to test it, but stuck at the problem
> mentioned below.
>
>
> Regards,
> Andreas
>
> Gabor Juhos wrote:
>> Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
>> driver.
>>
>> References:
>> NICInitRT3593BbpRegisters in chips/rt3593.c
>> NICInitBBP in common/rtmp_init.c
>> NICInitAsicFromEEPROM in common/rtmp_init.c
>>
>> Signed-off-by: Gabor Juhos <[email protected]>
>> ---
>> drivers/net/wireless/rt2x00/rt2800lib.c | 19 +++++++++++++++++++
>> 1 file changed, 19 insertions(+)
>>
>> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
>> index 6f58ceb..32ecd1a 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
>> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
>> @@ -4505,6 +4505,22 @@ static void rt2800_init_bbp_3572(struct rt2x00_dev *rt2x00dev)
>> rt2800_disable_unused_dac_adc(rt2x00dev);
>> }
>>
>> +static void rt2800_init_bbp_3593(struct rt2x00_dev *rt2x00dev)
>> +{
>> + rt2800_init_bbp_early(rt2x00dev);
>> +
>> + rt2800_bbp_write(rt2x00dev, 79, 0x13);
>> + rt2800_bbp_write(rt2x00dev, 80, 0x05);
>> + rt2800_bbp_write(rt2x00dev, 81, 0x33);
>> + rt2800_bbp_write(rt2x00dev, 137, 0x0f);
>> +
>> + rt2800_bbp_write(rt2x00dev, 84, 0x19);
>> +
>> + /* Enable DC filter */
>> + if (rt2x00_rt_rev_gte(rt2x00dev, RT3593, REV_RT3593E))
>
> Where is REV_RT3593E defined?
>
> /tmp/backports-20130617/drivers/net/wireless/rt2x00/rt2800lib.c: In
> function ?rt2800_init_bbp_3593?:
> /tmp/backports-20130617/drivers/net/wireless/rt2x00/rt2800lib.c:5325:43:
> error: ?REV_RT3593E? undeclared (first use in this function)

You are right, the patch-set should have contained 20 patches, but the first one
is missing. I will post that along with the second version of the series.

However if you want to try it in the meantime, you can find the patch in the
attachment. It must be applied before the other patches.

-Gabor


Attachments:
0001-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch (2.17 kB)

2013-06-28 19:13:17

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 12/19] rt2x00: rt2800lib: add default_power3 field for three-chain devices

The actual code uses two default TX power values.
This is enough for 1T and for 2T devices however
on 3T devices another value is needed for the third
chain.

Add a new field to struct channel_info and initialize
it from the 'rt2800_probe_hw_mode' function. Also modify
the 'rt2800_config_channel' to handle the new field as
well.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 22 ++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00.h | 1 +
2 files changed, 23 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index f079d70..bc21a57 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2769,6 +2769,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
info->default_power1);
info->default_power2 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
info->default_power2);
+ if (rt2x00dev->default_ant.tx_chain_num > 2)
+ info->default_power3 =
+ rt2800_txpower_to_dev(rt2x00dev, rf->channel,
+ info->default_power3);

switch (rt2x00dev->chip.rf) {
case RF2020:
@@ -6964,6 +6968,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
struct channel_info *info;
char *default_power1;
char *default_power2;
+ char *default_power3;
unsigned int i;
u16 eeprom;
u32 reg;
@@ -7116,9 +7121,17 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
default_power2 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);

+ if (rt2x00dev->default_ant.tx_chain_num > 2)
+ default_power3 = rt2800_eeprom_addr(rt2x00dev,
+ EEPROM_EXT_TXPOWER_BG3);
+ else
+ default_power3 = NULL;
+
for (i = 0; i < 14; i++) {
info[i].default_power1 = default_power1[i];
info[i].default_power2 = default_power2[i];
+ if (default_power3)
+ info[i].default_power3 = default_power3[i];
}

if (spec->num_channels > 14) {
@@ -7127,9 +7140,18 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
default_power2 = rt2800_eeprom_addr(rt2x00dev,
EEPROM_TXPOWER_A2);

+ if (rt2x00dev->default_ant.tx_chain_num > 2)
+ default_power3 =
+ rt2800_eeprom_addr(rt2x00dev,
+ EEPROM_EXT_TXPOWER_A3);
+ else
+ default_power3 = NULL;
+
for (i = 14; i < spec->num_channels; i++) {
info[i].default_power1 = default_power1[i - 14];
info[i].default_power2 = default_power2[i - 14];
+ if (default_power3)
+ info[i].default_power3 = default_power3[i - 14];
}
}

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index ee3fc57..fe4c572 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -211,6 +211,7 @@ struct channel_info {
short max_power;
short default_power1;
short default_power2;
+ short default_power3;
};

/*
--
1.7.10


2013-06-28 22:26:48

by Xose Vazquez Perez

[permalink] [raw]
Subject: Re: [PATCH 19/19] rt2x00: rt2800usb: add USB device ID for Linksys AE3000

Gabor Juhos wrote:

> diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
> index c24c1fd..6136871 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -1183,6 +1183,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
> { USB_DEVICE(0x04bb, 0x0944) },
> /* Linksys */
> { USB_DEVICE(0x13b1, 0x002f) },
> + { USB_DEVICE(0x13b1, 0x003b) },
> { USB_DEVICE(0x1737, 0x0079) },
> /* Ralink */
> { USB_DEVICE(0x148f, 0x3572) },
> --

You should separate RT3573 and RT3572 devices.
Rename CONFIG_RT2800USB_RT35XX to CONFIG_RT2800USB_RT3572
and do a new CONFIG_RT2800USB_RT3573 section.


And also you can add safely this usb-ids. All of them
are RT3573 devices:

0x1b75, 0x7733 AirLive 450Mbps Wireless-N Dual Band USB Adapter
0x0b05, 0x17bc ASUS USB-N66 450Mbps Dual Band USB Adapter
0x0b05, 0x17ad ASUS USB-N66 Dual Band N Network Adapter
0x050d, 0x1103 Belkin Wireless Adapter
0x148f, 0xf301 Cameo Ralink3573 3x3 single band USB dongle
0x7392, 0x7733 Edimax
0x0e66, 0x0020 Hawking HD45U Dual Band USB Wireless-N Adapter
0x0e66, 0x0021 Hawking HD45U Dual Band Wls-450N Adapter
0x04bb, 0x094e I-O DATA WN-AG450U Wireless LAN Adapter
0x0789, 0x016b Logitec LAN-W450AN/U2
0x0846, 0x9012 NETGEAR WNDA4100 N900 Wireless Dual Band USB Adapter
0x0846, 0x9019 NETGEAR WNDA4200D Wireless Dual Band USB Adapter
0x2019, 0xed19 Planex GW-USDual450
0x148f, 0x3573 Ralink 802.11n USB Wireless LAN Card
0x0df6, 0x0067 Sitecom Wireless Dualband Network Adapter N750 X6
0x0df6, 0x006a Sitecom Wireless Dualband Network Adapter N900 X7
0x0586, 0x3421 ZyXEL Dual-Band Wireless N450 USB Adapter

-thank you-

2013-06-28 19:13:18

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 14/19] rt2x00: rt2800lib: add channel configuration for RF3053

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
RT3593_ChipSwitchChannel in chips/rt3593.c

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 46 +++-
drivers/net/wireless/rt2x00/rt2800lib.c | 366 ++++++++++++++++++++++++++++++-
2 files changed, 409 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 7688e15..1ba797b 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2092,6 +2092,10 @@ struct mac_iveiv_entry {
#define BBP109_TX0_POWER FIELD8(0x0f)
#define BBP109_TX1_POWER FIELD8(0xf0)

+/* BBP 110 */
+#define BBP110_TX2_POWER FIELD8(0x0f)
+
+
/*
* BBP 138: Unknown
*/
@@ -2141,6 +2145,12 @@ struct mac_iveiv_entry {
#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80)
/* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */
#define RFCSR3_VCOCAL_EN FIELD8(0x80)
+/* Bits for RF3050 */
+#define RFCSR3_BIT1 FIELD8(0x02)
+#define RFCSR3_BIT2 FIELD8(0x04)
+#define RFCSR3_BIT3 FIELD8(0x08)
+#define RFCSR3_BIT4 FIELD8(0x10)
+#define RFCSR3_BIT5 FIELD8(0x20)

/*
* FRCSR 5:
@@ -2153,6 +2163,8 @@ struct mac_iveiv_entry {
#define RFCSR6_R1 FIELD8(0x03)
#define RFCSR6_R2 FIELD8(0x40)
#define RFCSR6_TXDIV FIELD8(0x0c)
+/* bits for RF3053 */
+#define RFCSR6_VCO_IC FIELD8(0xc0)

/*
* RFCSR 7:
@@ -2177,7 +2189,12 @@ struct mac_iveiv_entry {
* RFCSR 11:
*/
#define RFCSR11_R FIELD8(0x03)
+#define RFCSR11_PLL_MOD FIELD8(0x0c)
#define RFCSR11_MOD FIELD8(0xc0)
+/* bits for RF3053 */
+/* TODO: verify RFCSR11_MOD usage on other chips */
+#define RFCSR11_PLL_IDOH FIELD8(0x40)
+

/*
* RFCSR 12:
@@ -2273,6 +2290,12 @@ struct mac_iveiv_entry {
#define RFCSR31_RX_H20M FIELD8(0x20)
#define RFCSR31_RX_CALIB FIELD8(0x7f)

+/* RFCSR 32 bits for RF3053 */
+#define RFCSR32_TX_AGC_FC FIELD8(0xf8)
+
+/* RFCSR 36 bits for RF3053 */
+#define RFCSR36_RF_BS FIELD8(0x80)
+
/*
* RFCSR 38:
*/
@@ -2281,6 +2304,7 @@ struct mac_iveiv_entry {
/*
* RFCSR 39:
*/
+#define RFCSR39_RX_DIV FIELD8(0x40)
#define RFCSR39_RX_LO2_EN FIELD8(0x80)

/*
@@ -2288,18 +2312,36 @@ struct mac_iveiv_entry {
*/
#define RFCSR49_TX FIELD8(0x3f)
#define RFCSR49_EP FIELD8(0xc0)
+/* bits for RT3593 */
+#define RFCSR49_TX_LO1_IC FIELD8(0x1c)
+#define RFCSR49_TX_DIV FIELD8(0x20)

/*
* RFCSR 50:
*/
#define RFCSR50_TX FIELD8(0x3f)
#define RFCSR50_EP FIELD8(0xc0)
-/* bits for RT3593*/
+/* bits for RT3593 */
+#define RFCSR50_TX_LO1_EN FIELD8(0x20)
#define RFCSR50_TX_LO2_EN FIELD8(0x10)

/* RFCSR 51 */
-/* bits for RT3593*/
+/* bits for RT3593 */
+#define RFCSR51_BITS01 FIELD8(0x03)
#define RFCSR51_BITS24 FIELD8(0x1c)
+#define RFCSR51_BITS57 FIELD8(0xe0)
+
+#define RFCSR53_TX_POWER FIELD8(0x3f)
+#define RFCSR53_UNKNOWN FIELD8(0xc0)
+
+#define RFCSR54_TX_POWER FIELD8(0x3f)
+#define RFCSR54_UNKNOWN FIELD8(0xc0)
+
+#define RFCSR55_TX_POWER FIELD8(0x3f)
+#define RFCSR55_UNKNOWN FIELD8(0xc0)
+
+#define RFCSR57_DRV_CC FIELD8(0xfc)
+

/*
* RF registers
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 6dcf03a..ab67dba 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2169,6 +2169,303 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
}

+static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+ u8 txrx_agc_fc;
+ u8 txrx_h20m;
+ u8 rfcsr;
+ u8 bbp;
+ const bool txbf_enabled = false; /* TODO */
+
+ /* TODO: use TX{0,1,2}FinePowerControl values from EEPROM */
+ rt2800_bbp_read(rt2x00dev, 109, &bbp);
+ rt2x00_set_field8(&bbp, BBP109_TX0_POWER, 0);
+ rt2x00_set_field8(&bbp, BBP109_TX1_POWER, 0);
+ rt2800_bbp_write(rt2x00dev, 109, bbp);
+
+ rt2800_bbp_read(rt2x00dev, 110, &bbp);
+ rt2x00_set_field8(&bbp, BBP110_TX2_POWER, 0);
+ rt2800_bbp_write(rt2x00dev, 110, bbp);
+
+ if (rf->channel <= 14) {
+ /* Restore BBP 25 & 26 for 2.4 GHz */
+ rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25);
+ rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26);
+ } else {
+ /* Hard code BBP 25 & 26 for 5GHz */
+
+ /* Enable IQ Phase correction */
+ rt2800_bbp_write(rt2x00dev, 25, 0x09);
+ /* Setup IQ Phase correction value */
+ rt2800_bbp_write(rt2x00dev, 26, 0xff);
+ }
+
+ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
+ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3 & 0xf);
+
+ rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR11_R, (rf->rf2 & 0x3));
+ rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR11_PLL_IDOH, 1);
+ if (rf->channel <= 14)
+ rt2x00_set_field8(&rfcsr, RFCSR11_PLL_MOD, 1);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR11_PLL_MOD, 2);
+ rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 53, &rfcsr);
+ if (rf->channel <= 14) {
+ rfcsr = 0;
+ rt2x00_set_field8(&rfcsr, RFCSR53_TX_POWER,
+ info->default_power1 & 0x1f);
+ } else {
+ if (rt2x00_is_usb(rt2x00dev))
+ rfcsr = 0x40;
+
+ rt2x00_set_field8(&rfcsr, RFCSR53_TX_POWER,
+ ((info->default_power1 & 0x18) << 1) |
+ (info->default_power1 & 7));
+ }
+ rt2800_rfcsr_write(rt2x00dev, 53, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 55, &rfcsr);
+ if (rf->channel <= 14) {
+ rfcsr = 0;
+ rt2x00_set_field8(&rfcsr, RFCSR55_TX_POWER,
+ info->default_power2 & 0x1f);
+ } else {
+ if (rt2x00_is_usb(rt2x00dev))
+ rfcsr = 0x40;
+
+ rt2x00_set_field8(&rfcsr, RFCSR55_TX_POWER,
+ ((info->default_power2 & 0x18) << 1) |
+ (info->default_power2 & 7));
+ }
+ rt2800_rfcsr_write(rt2x00dev, 55, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 54, &rfcsr);
+ if (rf->channel <= 14) {
+ rfcsr = 0;
+ rt2x00_set_field8(&rfcsr, RFCSR54_TX_POWER,
+ info->default_power3 & 0x1f);
+ } else {
+ if (rt2x00_is_usb(rt2x00dev))
+ rfcsr = 0x40;
+
+ rt2x00_set_field8(&rfcsr, RFCSR54_TX_POWER,
+ ((info->default_power3 & 0x18) << 1) |
+ (info->default_power3 & 7));
+ }
+ rt2800_rfcsr_write(rt2x00dev, 54, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
+
+ switch (rt2x00dev->default_ant.tx_chain_num) {
+ case 3:
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+ /* fallthrough */
+ case 2:
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+ /* fallthrough */
+ case 1:
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+ break;
+ }
+
+ switch (rt2x00dev->default_ant.rx_chain_num) {
+ case 3:
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+ /* fallthrough */
+ case 2:
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+ /* fallthrough */
+ case 1:
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+ break;
+ }
+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+ /* TODO: frequency calibration? */
+
+ if (conf_is_ht40(conf)) {
+ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
+ RFCSR24_TX_AGC_FC);
+ txrx_h20m = rt2x00_get_field8(drv_data->calibration_bw40,
+ RFCSR24_TX_H20M);
+ } else {
+ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw20,
+ RFCSR24_TX_AGC_FC);
+ txrx_h20m = rt2x00_get_field8(drv_data->calibration_bw20,
+ RFCSR24_TX_H20M);
+ }
+
+ /* NOTE: the reference driver does not writes the new value
+ * back to RFCSR 32
+ */
+ rt2800_rfcsr_read(rt2x00dev, 32, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR32_TX_AGC_FC, txrx_agc_fc);
+
+ if (rf->channel <= 14)
+ rfcsr = 0xa0;
+ else
+ rfcsr = 0x80;
+ rt2800_rfcsr_write(rt2x00dev, 31, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, txrx_h20m);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, txrx_h20m);
+ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+ /* Band selection */
+ rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr);
+ if (rf->channel <= 14)
+ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0);
+ rt2800_rfcsr_write(rt2x00dev, 36, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 34, &rfcsr);
+ if (rf->channel <= 14)
+ rfcsr = 0x3c;
+ else
+ rfcsr = 0x20;
+ rt2800_rfcsr_write(rt2x00dev, 34, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
+ if (rf->channel <= 14)
+ rfcsr = 0x1a;
+ else
+ rfcsr = 0x12;
+ rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+ if (rf->channel >= 1 && rf->channel <= 14)
+ rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
+ else if (rf->channel >= 36 && rf->channel <= 64)
+ rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
+ else if (rf->channel >= 100 && rf->channel <= 128)
+ rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
+ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
+ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+ rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
+
+ if (rf->channel <= 14) {
+ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
+ } else {
+ rt2800_rfcsr_write(rt2x00dev, 10, 0xd8);
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x23);
+ }
+
+ rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR51_BITS01, 1);
+ rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
+ if (rf->channel <= 14) {
+ rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, 5);
+ rt2x00_set_field8(&rfcsr, RFCSR51_BITS57, 3);
+ } else {
+ rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, 4);
+ rt2x00_set_field8(&rfcsr, RFCSR51_BITS57, 2);
+ }
+ rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
+ if (rf->channel <= 14)
+ rt2x00_set_field8(&rfcsr, RFCSR49_TX_LO1_IC, 3);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR49_TX_LO1_IC, 2);
+
+ if (txbf_enabled)
+ rt2x00_set_field8(&rfcsr, RFCSR49_TX_DIV, 1);
+
+ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR50_TX_LO1_EN, 0);
+ rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr);
+ if (rf->channel <= 14)
+ rt2x00_set_field8(&rfcsr, RFCSR57_DRV_CC, 0x1b);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR57_DRV_CC, 0x0f);
+ rt2800_rfcsr_write(rt2x00dev, 57, rfcsr);
+
+ if (rf->channel <= 14) {
+ rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
+ rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
+ } else {
+ rt2800_rfcsr_write(rt2x00dev, 44, 0x9b);
+ rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
+ }
+
+ /* Initiate VCO calibration */
+ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
+ if (rf->channel <= 14) {
+ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+ } else {
+ rt2x00_set_field8(&rfcsr, RFCSR3_BIT1, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR3_BIT2, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR3_BIT3, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR3_BIT4, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR3_BIT5, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+ }
+ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
+
+ if (rf->channel >= 1 && rf->channel <= 14) {
+ rfcsr = 0x23;
+ if (txbf_enabled)
+ rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
+ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
+
+ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
+ } else if (rf->channel >= 36 && rf->channel <= 64) {
+ rfcsr = 0x36;
+ if (txbf_enabled)
+ rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
+ rt2800_rfcsr_write(rt2x00dev, 39, 0x36);
+
+ rt2800_rfcsr_write(rt2x00dev, 45, 0xeb);
+ } else if (rf->channel >= 100 && rf->channel <= 128) {
+ rfcsr = 0x32;
+ if (txbf_enabled)
+ rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
+ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
+
+ rt2800_rfcsr_write(rt2x00dev, 45, 0xb3);
+ } else {
+ rfcsr = 0x30;
+ if (txbf_enabled)
+ rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
+ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
+
+ rt2800_rfcsr_write(rt2x00dev, 45, 0x9b);
+ }
+}
+
#define POWER_BOUND 0x27
#define POWER_BOUND_5G 0x2b
#define FREQ_OFFSET_BOUND 0x5f
@@ -2785,6 +3082,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
case RF3052:
rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
break;
+ case RF3053:
+ rt2800_config_channel_rf3053(rt2x00dev, conf, rf, info);
+ break;
case RF3290:
rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
break;
@@ -2830,6 +3130,23 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 27, 0x20);
rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
+ } else if (rt2x00_rt(rt2x00dev, RT3593)) {
+ if (rf->channel > 14) {
+ /* Disable CCK Packet detection on 5GHz */
+ rt2800_bbp_write(rt2x00dev, 70, 0x00);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+ }
+
+ if (conf_is_ht40(conf))
+ rt2800_bbp_write(rt2x00dev, 105, 0x04);
+ else
+ rt2800_bbp_write(rt2x00dev, 105, 0x34);
+
+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 77, 0x98);
} else {
rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
@@ -2845,16 +3162,27 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2800_bbp_write(rt2x00dev, 82, 0x62);
rt2800_bbp_write(rt2x00dev, 75, 0x46);
} else {
- rt2800_bbp_write(rt2x00dev, 82, 0x84);
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ rt2800_bbp_write(rt2x00dev, 82, 0x62);
+ else
+ rt2800_bbp_write(rt2x00dev, 82, 0x84);
rt2800_bbp_write(rt2x00dev, 75, 0x50);
}
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ rt2800_bbp_write(rt2x00dev, 83, 0x8a);
}
+
} else {
if (rt2x00_rt(rt2x00dev, RT3572))
rt2800_bbp_write(rt2x00dev, 82, 0x94);
+ else if (rt2x00_rt(rt2x00dev, RT3593))
+ rt2800_bbp_write(rt2x00dev, 82, 0x82);
else
rt2800_bbp_write(rt2x00dev, 82, 0xf2);

+ if (rt2x00_rt(rt2x00dev, RT3593))
+ rt2800_bbp_write(rt2x00dev, 83, 0x9a);
+
if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
rt2800_bbp_write(rt2x00dev, 75, 0x46);
else
@@ -2925,6 +3253,41 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
if (rt2x00_rt(rt2x00dev, RT3572))
rt2800_rfcsr_write(rt2x00dev, 8, 0x80);

+ if (rt2x00_rt(rt2x00dev, RT3593)) {
+ if (rt2x00_is_usb(rt2x00dev)) {
+ rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
+
+ /* Band selection. GPIO #8 controls all paths */
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR8, 0);
+ if (rf->channel <= 14)
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL8, 1);
+ else
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL8, 0);
+
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR4, 0);
+ rt2x00_set_field32(&reg, GPIO_CTRL_DIR7, 0);
+
+ /* LNA PE control.
+ * GPIO #4 controls PE0 and PE1,
+ * GPIO #7 controls PE2
+ */
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL4, 1);
+ rt2x00_set_field32(&reg, GPIO_CTRL_VAL7, 1);
+
+ rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
+ }
+
+ /* AGC init */
+ if (rf->channel <= 14)
+ reg = 0x1c + 2 * rt2x00dev->lna_gain;
+ else
+ reg = 0x22 + ((rt2x00dev->lna_gain * 5) / 3);
+
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
+ usleep_range(1000, 1500);
+ }
+
if (rt2x00_rt(rt2x00dev, RT5592)) {
rt2800_bbp_write(rt2x00dev, 195, 141);
rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
@@ -5884,6 +6247,7 @@ static void rt3593_post_bbp_init(struct rt2x00_dev *rt2x00dev)

/* FIXME: BBP 105 owerwrite? */
rt2800_bbp_write(rt2x00dev, 105, 0x04);
+
}

static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
--
1.7.10


2013-06-29 11:24:19

by Gabor Juhos

[permalink] [raw]
Subject: Re: [PATCH 02/19] rt2x00: rt2800lib: add RFCSR register initialization for RT3593

2013.06.28. 23:42 keltezéssel, Xose Vazquez Perez írta:
> Gabor Juhos wrote:
>
>> Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
>> driver.
>
> There is a more recent version: DPO_RT5572_LinuxSTA_2.6.1.3_20121022

Yes, I know. However I wanted to test AP mode with the vendor driver and that is
only supported in the '2.6.0.1_20120629' version.

>
>> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
>> index 32ecd1a..0041b2c 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
>> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
>> [...]
>> + /* Initialize default register values */
>> + rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
>> + rt2800_rfcsr_write(rt2x00dev, 3, 0x80);
>
> from ./20120911_RT3573_Linux_STA_v2.5.0.0_Rev1_DPO/chips/rt3593.c
>
> {RF_R02, 0x80}
>
> but it was deleted in ./DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt3593.c
>
> Was it deliberate ? or a mistake ??

It is intentional. The patch is based on the *2.6.0.1* driver, and the value is
not present in that.

-Gabor



2013-06-28 19:13:19

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 03/19] rt2x00: rt2800lib: add BBP post initialization for RT3593

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
RT3593_PostBBPInitialization in chips/rt3553.c

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 48 ++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 0041b2c..87b7f94 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -5382,6 +5382,52 @@ static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev)
rt2800_normal_mode_setup_3xxx(rt2x00dev);
}

+static void rt3593_post_bbp_init(struct rt2x00_dev *rt2x00dev)
+{
+ u8 bbp;
+ bool txbf_enabled = false; /* FIXME */
+
+ rt2800_bbp_read(rt2x00dev, 105, &bbp);
+ if (rt2x00dev->default_ant.rx_chain_num == 1)
+ rt2x00_set_field8(&bbp, BBP105_MLD, 0);
+ else
+ rt2x00_set_field8(&bbp, BBP105_MLD, 1);
+ rt2800_bbp_write(rt2x00dev, 105, bbp);
+
+ rt2800_bbp4_mac_if_ctrl(rt2x00dev);
+
+ rt2800_bbp_write(rt2x00dev, 92, 0x02);
+ rt2800_bbp_write(rt2x00dev, 82, 0x82);
+ rt2800_bbp_write(rt2x00dev, 106, 0x05);
+ rt2800_bbp_write(rt2x00dev, 104, 0x92);
+ rt2800_bbp_write(rt2x00dev, 88, 0x90);
+ rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+ rt2800_bbp_write(rt2x00dev, 47, 0x48);
+ rt2800_bbp_write(rt2x00dev, 120, 0x50);
+
+ if (txbf_enabled)
+ rt2800_bbp_write(rt2x00dev, 163, 0xbd);
+ else
+ rt2800_bbp_write(rt2x00dev, 163, 0x9d);
+
+ /* SNR mapping */
+ rt2800_bbp_write(rt2x00dev, 142, 6);
+ rt2800_bbp_write(rt2x00dev, 143, 160);
+ rt2800_bbp_write(rt2x00dev, 142, 7);
+ rt2800_bbp_write(rt2x00dev, 143, 161);
+ rt2800_bbp_write(rt2x00dev, 142, 8);
+ rt2800_bbp_write(rt2x00dev, 143, 162);
+
+ /* ADC/DAC control */
+ rt2800_bbp_write(rt2x00dev, 31, 0x08);
+
+ /* RX AGC energy lower bound in log2 */
+ rt2800_bbp_write(rt2x00dev, 68, 0x0b);
+
+ /* FIXME: BBP 105 owerwrite? */
+ rt2800_bbp_write(rt2x00dev, 105, 0x04);
+}
+
static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
{
struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
@@ -5460,7 +5506,7 @@ static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
rt2800_led_open_drain_enable(rt2x00dev);
rt2800_normal_mode_setup_3593(rt2x00dev);

- /* TODO: post BBP initialization */
+ rt3593_post_bbp_init(rt2x00dev);

/* TODO: enable stream mode support */
}
--
1.7.10


2013-06-28 19:13:22

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 07/19] rt2x00: rt2800lib: add rt2800_txpower_to_dev helper

Introduce a new helper function for converting
the default TX power values from EEPROM into
mac80211 values.

The change improves the readability and it makes
it easier to add support for other chipsets.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 6 ------
drivers/net/wireless/rt2x00/rt2800lib.c | 21 ++++++++++++++-------
2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 7b7caeb..d3e8f6d 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2887,15 +2887,9 @@ enum rt2800_eeprom_word {
#define TXPOWER_G_FROM_DEV(__txpower) \
((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)

-#define TXPOWER_G_TO_DEV(__txpower) \
- clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
-
#define TXPOWER_A_FROM_DEV(__txpower) \
((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)

-#define TXPOWER_A_TO_DEV(__txpower) \
- clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
-
/*
* Board's maximun TX power limitation
*/
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index fa5bbae..9d05273 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2725,6 +2725,16 @@ static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel)
rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0);
}

+static char rt2800_txpower_to_dev(struct rt2x00_dev *rt2x00dev,
+ unsigned int channel,
+ char txpower)
+{
+ if (channel <= 14)
+ return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
+ else
+ return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
+}
+
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,
@@ -2734,13 +2744,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
unsigned int tx_pin;
u8 bbp, rfcsr;

- if (rf->channel <= 14) {
- info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1);
- info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2);
- } else {
- info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1);
- info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2);
- }
+ info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
+ info->default_power1);
+ info->default_power2 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
+ info->default_power2);

switch (rt2x00dev->chip.rf) {
case RF2020:
--
1.7.10


2013-06-29 15:06:28

by Andreas Hartmann

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 00/19] rt2x00: add experimental support for RT3593

Hello Gabor,

Gabor Juhos wrote:
> This patch-set implements experiemental support for the
> RT3593 chipset. The patches are tested on the Linksys
> AE3000 USB device only, however other USB devices which
> are using the RT3573 chips might work as well.


I tested your patchset (and all the others) with the same device you
used for developing in a real life scenario. My AP
http://wikidevi.com/wiki/TP-LINK_TL-WDN4800 is configured for 2.4 GHz,
40MHz, 802.11n, EAP-TLS.

The AE3000 is used with a notebook / core i5 processor.

The test was done *during a parallel running full hd video* in the
same net with another AE3000 running on raspberry pi with ralinks own
driver *always w/o any stuttering* (that's why I'm buying such devices)!
There is a reinforced-concrete floor between AP and the STAs.

>From /var/log/messages:

kernel: [33425.890174] cfg80211: Calling CRDA to update world regulatory domain
kernel: [33425.894221] cfg80211: World regulatory domain updated:
kernel: [33425.894230] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
kernel: [33425.894232] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
kernel: [33425.894234] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
kernel: [33425.894236] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
kernel: [33425.894238] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
kernel: [33425.894240] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
kernel: [33425.973578] usb 2-1.5: reset high-speed USB device number 3 using ehci-pci
kernel: [33426.070273] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 3593, rev 0402 detected
kernel: [33426.102833] ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 000d detected
kernel: [33426.103387] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
kernel: [33426.104122] usbcore: registered new interface driver rt2800usb
kernel: [33429.115258] ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
kernel: [33429.115305] ieee80211 phy0: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.33
kernel: [33429.359196] IPv6: ADDRCONF(NETDEV_UP): wlan2: link is not ready
kernel: [33432.884764] wlan2: authenticate with 11:22:33:44:55:66
kernel: [33432.937069] wlan2: send auth to 11:22:33:44:55:66 (try 1/3)
kernel: [33432.939615] wlan2: authenticated
kernel: [33432.940177] wlan2: associate with 11:22:33:44:55:66 (try 1/3)
kernel: [33432.943876] wlan2: RX AssocResp from 11:22:33:44:55:66 (capab=0x431 status=0 aid=1)
kernel: [33432.953244] wlan2: associated
kernel: [33432.953278] IPv6: ADDRCONF(NETDEV_CHANGE): wlan2: link becomes ready
kernel: [33432.953322] cfg80211: Calling CRDA for country: DE
kernel: [33432.957301] cfg80211: Regulatory domain changed to country: DE
kernel: [33432.957306] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
kernel: [33432.957310] cfg80211: (2400000 KHz - 2483500 KHz @ 40000 KHz), (N/A, 2000 mBm)
kernel: [33432.957313] cfg80211: (5150000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
kernel: [33432.957316] cfg80211: (5250000 KHz - 5350000 KHz @ 40000 KHz), (N/A, 2000 mBm)
kernel: [33432.957319] cfg80211: (5470000 KHz - 5725000 KHz @ 40000 KHz), (N/A, 2698 mBm)


netperf gives with rt2800usb on the notebook:

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
enable_enobufs failed: setsockopt
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.01 78.41
MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET from server () port 0 AF_INET : demo
enable_enobufs failed: setsockopt
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.00 115.92
TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.02 86.46



The exactly same (=unchanged conditions) done with
DPO_RT5572_LinuxSTA_2.6.1.3_20121022 on the notebook gives:


MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
enable_enobufs failed: setsockopt
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.02 130.36
MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET from server () port 0 AF_INET : demo
enable_enobufs failed: setsockopt
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.00 131.23
TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 10.03 131.33



Thanks,
kind regards,
Andreas

2013-06-28 19:13:24

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 09/19] rt2x00: rt2800lib: introduce rt2800_get_txmixer_gain_{24,5}g helpers

Move the TX mixer gain reading code into separate
helper functions in preparation for RT3593 support.

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 38 +++++++++++++++++++------------
1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index cbc3dc3..6f23eb0 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -6362,6 +6362,28 @@ int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);

+static u8 rt2800_get_txmixer_gain_24g(struct rt2x00_dev *rt2x00dev)
+{
+ u16 word;
+
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
+ if ((word & 0x00ff) != 0x00ff)
+ return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
+
+ return 0;
+}
+
+static u8 rt2800_get_txmixer_gain_5g(struct rt2x00_dev *rt2x00dev)
+{
+ u16 word;
+
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
+ if ((word & 0x00ff) != 0x00ff)
+ return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
+
+ return 0;
+}
+
static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
{
struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
@@ -6456,13 +6478,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);

- rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
- if ((word & 0x00ff) != 0x00ff) {
- drv_data->txmixer_gain_24g =
- rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
- } else {
- drv_data->txmixer_gain_24g = 0;
- }
+ drv_data->txmixer_gain_24g = rt2800_get_txmixer_gain_24g(rt2x00dev);

rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
@@ -6473,13 +6489,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
default_lna_gain);
rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);

- rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
- if ((word & 0x00ff) != 0x00ff) {
- drv_data->txmixer_gain_5g =
- rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
- } else {
- drv_data->txmixer_gain_5g = 0;
- }
+ drv_data->txmixer_gain_5g = rt2800_get_txmixer_gain_5g(rt2x00dev);

rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
--
1.7.10


2013-06-28 19:13:15

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH 06/19] rt2x00: rt2800lib: fix antenna configuration for RT3593

On the RT3593 chipset, BBP register 86 must be
configured by different values based on the RX
antenna numbers.

Configure this register from the 'rt2800_config_ant'
function.

Based on the Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
RT3593_CONFIG_SET_BY_ANTENNA in include/chip/rt3593.h

Signed-off-by: Gabor Juhos <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 6f6f48f..fa5bbae 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1804,6 +1804,13 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)

rt2800_bbp_write(rt2x00dev, 3, r3);
rt2800_bbp_write(rt2x00dev, 1, r1);
+
+ if (rt2x00_rt(rt2x00dev, RT3593)) {
+ if (ant->rx_chain_num == 1)
+ rt2800_bbp_write(rt2x00dev, 86, 0x00);
+ else
+ rt2800_bbp_write(rt2x00dev, 86, 0x46);
+ }
}
EXPORT_SYMBOL_GPL(rt2800_config_ant);

--
1.7.10


2013-07-01 15:24:01

by Andreas Hartmann

[permalink] [raw]
Subject: Re: [PATCH 00/19] rt2x00: add experimental support for RT3593

Hello Gabor,

Gabor Juhos wrote:
> Hi Andreas,
>
>> bad guy is back again :-)
>
> :)
>
>>
>> Gabor Juhos wrote:
>>> This patch-set implements experiemental support for the
>>> RT3593 chipset. The patches are tested on the Linksys
>>> AE3000 USB device only, however other USB devices which
>>> are using the RT3573 chips might work as well.
>>
>> I did another test with raspberry pi. Same network parameters (2.4 GHz,
>> 40MHz, eap-tls, ccmp/ccmp) but this time w/o any other load on the
>> wlan. But there is a reinforced-concrete floor between AP and STA.
>>
>> netperf with rt2800usb / backports-20130617 / kernel 3.6.11 gives:
>>
>> MIGRATED TCP STREAM TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
>> Recv Send Send
>> Socket Socket Message Elapsed
>> Size Size Size Time Throughput
>> bytes bytes bytes secs. 10^6bits/sec
>>
>> 87380 16384 16384 10.39 28.16
>> MIGRATED TCP MAERTS TEST from 0.0.0.0 () port 0 AF_INET from server port 0 AF_INET
>> Recv Send Send
>> Socket Socket Message Elapsed
>> Size Size Size Time Throughput
>> bytes bytes bytes secs. 10^6bits/sec
>>
>> 87380 16384 16384 10.00 30.23
>> TCP SENDFILE TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
>> Recv Send Send
>> Socket Socket Message Elapsed
>> Size Size Size Time Throughput
>> bytes bytes bytes secs. 10^6bits/sec
>>
>> 87380 16384 16384 10.35 27.69
>>
>>
>> Same with DPO_RT5572_LinuxSTA_2.6.1.3_20121022
>>
>> MIGRATED TCP STREAM TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
>> Recv Send Send
>> Socket Socket Message Elapsed
>> Size Size Size Time Throughput
>> bytes bytes bytes secs. 10^6bits/sec
>>
>> 87380 16384 16384 10.01 97.95
>> MIGRATED TCP MAERTS TEST from 0.0.0.0 () port 0 AF_INET from server port 0 AF_INET
>> Recv Send Send
>> Socket Socket Message Elapsed
>> Size Size Size Time Throughput
>> bytes bytes bytes secs. 10^6bits/sec
>>
>> 87380 16384 16384 10.01 121.69
>> TCP SENDFILE TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
>> Recv Send Send
>> Socket Socket Message Elapsed
>> Size Size Size Time Throughput
>> bytes bytes bytes secs. 10^6bits/sec
>>
>> 87380 16384 16384 10.01 82.75
>>
>> If you compare the result w/ rt2800usb/AE3000 with rt2800usb/rt3572[1]
>> you can see: no difference :-(.
>
> These results with the rt2800usb driver are quite bad. I don't yet have an idea
> what causes the huge performance loss on that platform.

One reason, from my point of view the main reason:
The rt2800usb driver causes to much interrupts (bad USB-handling). The
vendor driver uses a few interrupts with big data portions, rt2800usb
does it vice versa: small packets, but a lot more (1500 (14 Mbit/s) :
24.000 (9Mbit/s)).

See: http://article.gmane.org/gmane.linux.drivers.rt2x00.user/615

On systems with enough cpu resources, this problem doesn't hit that much
(but even there). But on all other systems, you're getting more or less
problems: all the more problems as worse the CPU resources get.

That's why rt5572sta performs mostly fine even with raspberry pi from my
point of view (besides the optimized rate control of the vendor driver).



Regards,
Andreas

2013-07-01 07:43:21

by Gabor Juhos

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 00/19] rt2x00: add experimental support for RT3593

Hi Andreas,

> Gabor Juhos wrote:
>> This patch-set implements experiemental support for the
>> RT3593 chipset. The patches are tested on the Linksys
>> AE3000 USB device only, however other USB devices which
>> are using the RT3573 chips might work as well.
>
>
> I tested your patchset (and all the others) with the same device you
> used for developing in a real life scenario. My AP
> http://wikidevi.com/wiki/TP-LINK_TL-WDN4800 is configured for 2.4 GHz,
> 40MHz, 802.11n, EAP-TLS.
>
> The AE3000 is used with a notebook / core i5 processor.
>
> The test was done *during a parallel running full hd video* in the
> same net with another AE3000 running on raspberry pi with ralinks own
> driver *always w/o any stuttering* (that's why I'm buying such devices)!
> There is a reinforced-concrete floor between AP and the STAs.
>
> From /var/log/messages:
>
> kernel: [33425.890174] cfg80211: Calling CRDA to update world regulatory domain
> kernel: [33425.894221] cfg80211: World regulatory domain updated:
> kernel: [33425.894230] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
> kernel: [33425.894232] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> kernel: [33425.894234] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
> kernel: [33425.894236] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
> kernel: [33425.894238] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> kernel: [33425.894240] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> kernel: [33425.973578] usb 2-1.5: reset high-speed USB device number 3 using ehci-pci
> kernel: [33426.070273] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 3593, rev 0402 detected
> kernel: [33426.102833] ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 000d detected
> kernel: [33426.103387] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
> kernel: [33426.104122] usbcore: registered new interface driver rt2800usb
> kernel: [33429.115258] ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
> kernel: [33429.115305] ieee80211 phy0: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.33
> kernel: [33429.359196] IPv6: ADDRCONF(NETDEV_UP): wlan2: link is not ready
> kernel: [33432.884764] wlan2: authenticate with 11:22:33:44:55:66
> kernel: [33432.937069] wlan2: send auth to 11:22:33:44:55:66 (try 1/3)
> kernel: [33432.939615] wlan2: authenticated
> kernel: [33432.940177] wlan2: associate with 11:22:33:44:55:66 (try 1/3)
> kernel: [33432.943876] wlan2: RX AssocResp from 11:22:33:44:55:66 (capab=0x431 status=0 aid=1)
> kernel: [33432.953244] wlan2: associated
> kernel: [33432.953278] IPv6: ADDRCONF(NETDEV_CHANGE): wlan2: link becomes ready
> kernel: [33432.953322] cfg80211: Calling CRDA for country: DE
> kernel: [33432.957301] cfg80211: Regulatory domain changed to country: DE
> kernel: [33432.957306] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
> kernel: [33432.957310] cfg80211: (2400000 KHz - 2483500 KHz @ 40000 KHz), (N/A, 2000 mBm)
> kernel: [33432.957313] cfg80211: (5150000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
> kernel: [33432.957316] cfg80211: (5250000 KHz - 5350000 KHz @ 40000 KHz), (N/A, 2000 mBm)
> kernel: [33432.957319] cfg80211: (5470000 KHz - 5725000 KHz @ 40000 KHz), (N/A, 2698 mBm)
>
>
> netperf gives with rt2800usb on the notebook:
>
> MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
> enable_enobufs failed: setsockopt
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.01 78.41
> MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET from server () port 0 AF_INET : demo
> enable_enobufs failed: setsockopt
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.00 115.92
> TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.02 86.46
>
>
>
> The exactly same (=unchanged conditions) done with
> DPO_RT5572_LinuxSTA_2.6.1.3_20121022 on the notebook gives:
>
>
> MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
> enable_enobufs failed: setsockopt
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.02 130.36
> MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET from server () port 0 AF_INET : demo
> enable_enobufs failed: setsockopt
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.00 131.23
> TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to server () port 0 AF_INET : demo
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.03 131.33

Thank you for the test results. I have tested the device in managed mode against
various APs. To be honest, those were connectivity tests mainly, I did not run
throughput tests so far. I will do that later.

Regards,
Gabor

2013-07-01 12:19:52

by Gabor Juhos

[permalink] [raw]
Subject: Re: [PATCH 00/19] rt2x00: add experimental support for RT3593

Hi Andreas,

> bad guy is back again :-)

:)

>
> Gabor Juhos wrote:
>> This patch-set implements experiemental support for the
>> RT3593 chipset. The patches are tested on the Linksys
>> AE3000 USB device only, however other USB devices which
>> are using the RT3573 chips might work as well.
>
> I did another test with raspberry pi. Same network parameters (2.4 GHz,
> 40MHz, eap-tls, ccmp/ccmp) but this time w/o any other load on the
> wlan. But there is a reinforced-concrete floor between AP and STA.
>
> netperf with rt2800usb / backports-20130617 / kernel 3.6.11 gives:
>
> MIGRATED TCP STREAM TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.39 28.16
> MIGRATED TCP MAERTS TEST from 0.0.0.0 () port 0 AF_INET from server port 0 AF_INET
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.00 30.23
> TCP SENDFILE TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.35 27.69
>
>
> Same with DPO_RT5572_LinuxSTA_2.6.1.3_20121022
>
> MIGRATED TCP STREAM TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.01 97.95
> MIGRATED TCP MAERTS TEST from 0.0.0.0 () port 0 AF_INET from server port 0 AF_INET
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.01 121.69
> TCP SENDFILE TEST from 0.0.0.0 () port 0 AF_INET to server port 0 AF_INET
> Recv Send Send
> Socket Socket Message Elapsed
> Size Size Size Time Throughput
> bytes bytes bytes secs. 10^6bits/sec
>
> 87380 16384 16384 10.01 82.75
>
> If you compare the result w/ rt2800usb/AE3000 with rt2800usb/rt3572[1]
> you can see: no difference :-(.

These results with the rt2800usb driver are quite bad. I don't yet have an idea
what causes the huge performance loss on that platform.

Although I don't have a Raspberry Pi nor any RT3572 based USB device, but I can
test the AE3000 on a few different embedded platforms. I will do some
performance tests on those once I have fixed the AP mode support for the RT3593.

-Gabor