2010-04-11 12:31:25

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH v2 0/9] rt2x00: Align with vendor driver and add support for rt3070/rt3071/rt3090/rt3390.

This patch series aligns rt2x00 with the latest versions of the Ralink
rt2860 / rt2870 / rt3070 / rt3090 drivers, and adds support for RT3070,
RT3071, RT3090, and RT3390 based devices.

The patches are relative to wireless-next-2.6, and can also be pulled
from:

git://git.gwingerde.nl/rt2x00-next-2.6

v2: Handle comments received from Ivo, Julian and Felix.

Gertjan van Wingerde (9):
rt2x00: Let RF chipset decide the RF channel switch method to use in rt2800.
rt2x00: Update rt2800 register definitions towards latest definitions.
rt2x00: Align RT chipset definitions with vendor driver.
rt2x00: Refactor rt2800 version constants.
rt2x00: Align rt2800 register initialization with vendor driver.
rt2x00: Finish rt3070 support in rt2800 register initialization.
rt2x00: Add rt3071 support in rt2800 register initialization.
rt2x00: Add rt3090 support in rt2800 register initialization.
rt2x00: Add rt3390 support in rt2800 register initialization.

drivers/net/wireless/rt2x00/rt2800.h | 108 +++++++-
drivers/net/wireless/rt2x00/rt2800lib.c | 464 ++++++++++++++++++++++---------
drivers/net/wireless/rt2x00/rt2800pci.c | 13 -
drivers/net/wireless/rt2x00/rt2x00.h | 29 ++-
4 files changed, 458 insertions(+), 156 deletions(-)



2010-04-30 17:54:34

by Helmut Schaa

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

Am Mittwoch 28 April 2010 schrieb Antonio Quartulli:
> On mer, apr 28, 2010 at 02:56:16 +0200, Helmut Schaa wrote:
> > Am Mittwoch 28 April 2010 schrieb Antonio Quartulli:
> > > Hi all, I found out that after this commit:
> > >
> > > commit 23812383c6b03afef44c4aa642500f8235c3d079
> > > Author: Helmut Schaa <[email protected]>
> > > Date: Mon Apr 26 13:48:45 2010 +0200
> > >
> > > rt2x00: rt2800lib: Fix rx path on SoC devices
> > >
> > > my card becomes unstable, I mean that the connection lose packets and
> > > sometimes it disassociates from the AP.
> > > I also found that the singnal level reported by iwconfig is wrong (it
> > > reports -191dBm)
> >
> > Uhhh, are you 100% sure? The patch doesn't touch any PCI code at all.
> > Maybe the card was unstable before already? Could you please verify again?
> >
> > Thanks you very much for your testing, it's really appreciated.
> >
>
> I pull the latest commit on wireless-testing. Now it seems to work well.
> I cannot understand what happened. Anyway the signal level is still
> wrong because iwconfig shows a positive value instead of a negative one
> (the absolute value seems plausible).

Hmm, my connection isn't always stable. Either the reception or the
transmission of frames still causes trouble sometimes.

When I force the device to use a fixed rate I can get a pretty stable
connection.

- 11g rates seem to work only when I'm really close to the AP (~1m)
- 11b rates seem to work much better but I can also see retries sometimes.
- 11n rates seem to work as well (but are not used by the default rate control
algorithm yet).

So, could you please try different fixed rates and see what results you get?

iwconfig wlan0 rate 11M

should do the trick. Replace 11M in subsequent tests with 1M or 6M or 54M to
get different results.

Btw. does anybody know how I can force a fixed rate without Wext?

> On 2.6.34-rc* kernel I still have the same issue I noticed some times
> ago:
>
> Apr 28 00:10:18 eagle3 kernel: [ 1359.907914] rt2800pci 0000:06:00.0: firmware: requesting rt2860.bin
> Apr 28 00:10:18 eagle3 kernel: [ 1360.033584] phy1 -> rt2x00lib_request_firmware: Info - Firmware detected - version: 0.26.
> Apr 28 00:10:18 eagle3 kernel: [ 1360.043280] phy1 -> rt2800pci_load_firmware: Error - PBF system register not ready.
> Apr 28 00:10:18 eagle3 kernel: [ 1360.043793] phy1 -> rt2x00pci_regbusy_read: Error - Indirect register access failed:
> offset=0x00007010, value=0x3dca191a

Can't help you with these, sorry.

Helmut

2010-04-11 12:31:29

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 5/9] rt2x00: Align rt2800 register initialization with vendor driver.

Align the rt2800 register initializations with the latest versions of the
Ralink vendor driver.
This patch is also preparation for the addition of support for RT3070 /
RT3071 / RT3090 / RT3390 based devices.

Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 130 ++++++++++++++++++++++--------
drivers/net/wireless/rt2x00/rt2800pci.c | 13 ---
2 files changed, 95 insertions(+), 48 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 8a4ed76..1890b9a 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -359,11 +359,6 @@ static int rt2800_blink_set(struct led_classdev *led_cdev,
rt2800_register_read(led->rt2x00dev, LED_CFG, &reg);
rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on);
rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
- rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
- rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
- rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
- rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
- rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
rt2800_register_write(led->rt2x00dev, LED_CFG, reg);

return 0;
@@ -609,10 +604,6 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)
{
u32 reg;

- rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
- rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20);
- rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
-
rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
!!erp->short_preamble);
@@ -631,15 +622,12 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)

rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
- rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);

rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
- rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
- rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);

rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
@@ -984,10 +972,6 @@ static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
libconf->conf->short_frame_max_tx_count);
rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT,
libconf->conf->long_frame_max_tx_count);
- rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
- rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
- rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
- rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
}

@@ -1110,6 +1094,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
u32 reg;
unsigned int i;

+ rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+ rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
if (rt2x00_is_usb(rt2x00dev)) {
/*
* Wait until BBP and RF are ready.
@@ -1129,8 +1121,25 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
reg & ~0x00002000);
- } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
+ } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
+ /*
+ * Reset DMA indexes
+ */
+ rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
+ rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+
+ rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+ rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+ }

rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
@@ -1175,6 +1184,13 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);

+ rt2800_config_filter(rt2x00dev, FIF_ALLMULTI);
+
+ rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, 9);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
+ rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+
if (rt2x00_is_usb(rt2x00dev) &&
rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
@@ -1198,6 +1214,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)

rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
+ rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 32);
rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);

@@ -1213,38 +1230,61 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);

+ rt2800_register_read(rt2x00dev, LED_CFG, &reg);
+ rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, 70);
+ rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, 30);
+ rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
+ rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
+ rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
+ rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
+ rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
+ rt2800_register_write(rt2x00dev, LED_CFG, reg);
+
rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);

+ rt2800_register_read(rt2x00dev, TX_RTY_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
+ rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
+
rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY, 1);
rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE, 1);
rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);

rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
- rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 3);
rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, 1);
rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);

rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
- rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 3);
rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, 1);
rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);

rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
@@ -1257,11 +1297,13 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);

rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
- rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL,
+ !rt2x00_is_usb(rt2x00dev));
rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
@@ -1269,6 +1311,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);

rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
@@ -1281,6 +1324,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);

rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
@@ -1293,6 +1337,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);

if (rt2x00_is_usb(rt2x00dev)) {
@@ -1322,6 +1367,15 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);

rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
+
+ rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, 32);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, 32);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, 314);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
+ rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);

/*
@@ -1471,26 +1525,32 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)

rt2800_bbp_write(rt2x00dev, 65, 0x2c);
rt2800_bbp_write(rt2x00dev, 66, 0x38);
- rt2800_bbp_write(rt2x00dev, 69, 0x12);
+
+ if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
+ rt2800_bbp_write(rt2x00dev, 69, 0x16);
+ rt2800_bbp_write(rt2x00dev, 73, 0x12);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 69, 0x12);
+ rt2800_bbp_write(rt2x00dev, 73, 0x10);
+ }
+
rt2800_bbp_write(rt2x00dev, 70, 0x0a);
- rt2800_bbp_write(rt2x00dev, 73, 0x10);
rt2800_bbp_write(rt2x00dev, 81, 0x37);
rt2800_bbp_write(rt2x00dev, 82, 0x62);
rt2800_bbp_write(rt2x00dev, 83, 0x6a);
- rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
+ if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D) ||
+ rt2x00_rt_rev(rt2x00dev, RT2870, REV_RT2870D))
+ rt2800_bbp_write(rt2x00dev, 84, 0x19);
+ else
+ rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
rt2800_bbp_write(rt2x00dev, 86, 0x00);
rt2800_bbp_write(rt2x00dev, 91, 0x04);
rt2800_bbp_write(rt2x00dev, 92, 0x00);
rt2800_bbp_write(rt2x00dev, 103, 0x00);
rt2800_bbp_write(rt2x00dev, 105, 0x05);
-
- if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
- rt2800_bbp_write(rt2x00dev, 69, 0x16);
- rt2800_bbp_write(rt2x00dev, 73, 0x12);
- }
-
- if (rt2x00_rt_rev_gte(rt2x00dev, RT2860, REV_RT2860D))
- rt2800_bbp_write(rt2x00dev, 84, 0x19);
+ rt2800_bbp_write(rt2x00dev, 106, 0x35);

if (rt2x00_rt(rt2x00dev, RT2872)) {
rt2800_bbp_write(rt2x00dev, 31, 0x08);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index a2b37d3..2131f8f 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -347,19 +347,6 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
struct queue_entry_priv_pci *entry_priv;
u32 reg;

- rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
- rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
-
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
-
/*
* Initialize registers.
*/
--
1.7.0.4


2010-04-11 12:31:27

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 2/9] rt2x00: Update rt2800 register definitions towards latest definitions.

Definitions taken from the latest rt2860 / rt2870 / rt3070 / rt3090 Ralink
vendor drivers.

Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 55 +++++++++++++++++++++++++++++-
drivers/net/wireless/rt2x00/rt2800lib.c | 2 +-
2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 74c0433..455dc3f 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -56,6 +56,7 @@
#define RF3021 0x0007
#define RF3022 0x0008
#define RF3052 0x0009
+#define RF3320 0x000b

/*
* Chipset version.
@@ -90,10 +91,16 @@
#define NUM_TX_QUEUES 4

/*
- * USB registers.
+ * Registers.
*/

/*
+ * OPT_14: Unknown register used by rt3xxx devices.
+ */
+#define OPT_14_CSR 0x0114
+#define OPT_14_CSR_BIT0 FIELD32(0x00000001)
+
+/*
* INT_SOURCE_CSR: Interrupt source register.
* Write one to clear corresponding bit.
* TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c
@@ -398,6 +405,31 @@
#define EFUSE_DATA3 0x059c

/*
+ * LDO_CFG0
+ */
+#define LDO_CFG0 0x05d4
+#define LDO_CFG0_DELAY3 FIELD32(0x000000ff)
+#define LDO_CFG0_DELAY2 FIELD32(0x0000ff00)
+#define LDO_CFG0_DELAY1 FIELD32(0x00ff0000)
+#define LDO_CFG0_BGSEL FIELD32(0x03000000)
+#define LDO_CFG0_LDO_CORE_VLEVEL FIELD32(0x1c000000)
+#define LD0_CFG0_LDO25_LEVEL FIELD32(0x60000000)
+#define LDO_CFG0_LDO25_LARGEA FIELD32(0x80000000)
+
+/*
+ * GPIO_SWITCH
+ */
+#define GPIO_SWITCH 0x05dc
+#define GPIO_SWITCH_0 FIELD32(0x00000001)
+#define GPIO_SWITCH_1 FIELD32(0x00000002)
+#define GPIO_SWITCH_2 FIELD32(0x00000004)
+#define GPIO_SWITCH_3 FIELD32(0x00000008)
+#define GPIO_SWITCH_4 FIELD32(0x00000010)
+#define GPIO_SWITCH_5 FIELD32(0x00000020)
+#define GPIO_SWITCH_6 FIELD32(0x00000040)
+#define GPIO_SWITCH_7 FIELD32(0x00000080)
+
+/*
* MAC Control/Status Registers(CSR).
* Some values are set in TU, whereas 1 TU == 1024 us.
*/
@@ -1492,6 +1524,14 @@ struct mac_iveiv_entry {
#define BBP4_BANDWIDTH FIELD8(0x18)

/*
+ * BBP 138: Unknown
+ */
+#define BBP138_RX_ADC1 FIELD8(0x02)
+#define BBP138_RX_ADC2 FIELD8(0x04)
+#define BBP138_TX_DAC1 FIELD8(0x20)
+#define BBP138_TX_DAC2 FIELD8(0x40)
+
+/*
* RFCSR registers
* The wordsize of the RFCSR is 8 bits.
*/
@@ -1499,7 +1539,8 @@ struct mac_iveiv_entry {
/*
* RFCSR 6:
*/
-#define RFCSR6_R FIELD8(0x03)
+#define RFCSR6_R1 FIELD8(0x03)
+#define RFCSR6_R2 FIELD8(0x40)

/*
* RFCSR 7:
@@ -1512,6 +1553,14 @@ struct mac_iveiv_entry {
#define RFCSR12_TX_POWER FIELD8(0x1f)

/*
+ * RFCSR 17:
+ */
+#define RFCSR17_R1 FIELD8(0x07)
+#define RFCSR17_R2 FIELD8(0x08)
+#define RFCSR17_R3 FIELD8(0x20)
+
+
+/*
* RFCSR 22:
*/
#define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01)
@@ -1603,6 +1652,8 @@ struct mac_iveiv_entry {
#define EEPROM_NIC_WPS_PBC FIELD16(0x0080)
#define EEPROM_NIC_BW40M_BG FIELD16(0x0100)
#define EEPROM_NIC_BW40M_A FIELD16(0x0200)
+#define EEPROM_NIC_ANT_DIVERSITY FIELD16(0x0800)
+#define EEPROM_NIC_DAC_TEST FIELD16(0x8000)

/*
* EEPROM frequency
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 6fdec15..394c8e4 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -797,7 +797,7 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);

rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
+ rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);

rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
--
1.7.0.4


2010-04-28 17:44:31

by Antonio Quartulli

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

On mer, apr 28, 2010 at 02:56:16 +0200, Helmut Schaa wrote:
> Am Mittwoch 28 April 2010 schrieb Antonio Quartulli:
> > On mar, apr 27, 2010 at 01:15:21 +0200, Antonio Quartulli wrote:
> > > On lun, apr 26, 2010 at 01:11:20 +0200, Helmut Schaa wrote:
> > > > Am Montag 26 April 2010 schrieb Helmut Schaa:
> > > > > Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> > > > > > rt2x00 had preliminary support for RT3070 based devices, but the support was
> > > > > > incomplete.
> > > > > > Update the RT3070 register initialization to be similar to the latest Ralink
> > > > > > vendor driver.
> > > > > >
> > > > > > With this patch my rt3070 based devices start showing a sign of life.
> > > > >
> > > > > Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> > > > > more details.
> > > >
> > > > Antonio, did that patch also break rx on your PCI device with rt2872?
> > > > If not this is only needed for SoC.
> > > Hi, I cloned the wireless-testing git a few minutes ago.
> > > My card (rt2x00_set_chip: Info - Chipset detected - rt: 2872, rf: 0003,
> > > rev: 0200) on miniPCI works correctly without any kind of problem.
> > > No hangs at all.
> >
> > Hi all, I found out that after this commit:
> >
> > commit 23812383c6b03afef44c4aa642500f8235c3d079
> > Author: Helmut Schaa <[email protected]>
> > Date: Mon Apr 26 13:48:45 2010 +0200
> >
> > rt2x00: rt2800lib: Fix rx path on SoC devices
> >
> > my card becomes unstable, I mean that the connection lose packets and
> > sometimes it disassociates from the AP.
> > I also found that the singnal level reported by iwconfig is wrong (it
> > reports -191dBm)
>
> Uhhh, are you 100% sure? The patch doesn't touch any PCI code at all.
> Maybe the card was unstable before already? Could you please verify again?
>
> Thanks you very much for your testing, it's really appreciated.
>

I pull the latest commit on wireless-testing. Now it seems to work well.
I cannot understand what happened. Anyway the signal level is still
wrong because iwconfig shows a positive value instead of a negative one
(the absolute value seems plausible).

On 2.6.34-rc* kernel I still have the same issue I noticed some times
ago:

Apr 28 00:10:18 eagle3 kernel: [ 1359.907914] rt2800pci 0000:06:00.0: firmware: requesting rt2860.bin
Apr 28 00:10:18 eagle3 kernel: [ 1360.033584] phy1 -> rt2x00lib_request_firmware: Info - Firmware detected - version: 0.26.
Apr 28 00:10:18 eagle3 kernel: [ 1360.043280] phy1 -> rt2800pci_load_firmware: Error - PBF system register not ready.
Apr 28 00:10:18 eagle3 kernel: [ 1360.043793] phy1 -> rt2x00pci_regbusy_read: Error - Indirect register access failed:
offset=0x00007010, value=0x3dca191a


Regards

--
Antonio Quartulli

Ognuno di noi, da solo, non vale nulla
Ernesto "Che" Guevara

2010-04-28 12:56:35

by Helmut Schaa

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

Am Mittwoch 28 April 2010 schrieb Antonio Quartulli:
> On mar, apr 27, 2010 at 01:15:21 +0200, Antonio Quartulli wrote:
> > On lun, apr 26, 2010 at 01:11:20 +0200, Helmut Schaa wrote:
> > > Am Montag 26 April 2010 schrieb Helmut Schaa:
> > > > Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> > > > > rt2x00 had preliminary support for RT3070 based devices, but the support was
> > > > > incomplete.
> > > > > Update the RT3070 register initialization to be similar to the latest Ralink
> > > > > vendor driver.
> > > > >
> > > > > With this patch my rt3070 based devices start showing a sign of life.
> > > >
> > > > Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> > > > more details.
> > >
> > > Antonio, did that patch also break rx on your PCI device with rt2872?
> > > If not this is only needed for SoC.
> > Hi, I cloned the wireless-testing git a few minutes ago.
> > My card (rt2x00_set_chip: Info - Chipset detected - rt: 2872, rf: 0003,
> > rev: 0200) on miniPCI works correctly without any kind of problem.
> > No hangs at all.
>
> Hi all, I found out that after this commit:
>
> commit 23812383c6b03afef44c4aa642500f8235c3d079
> Author: Helmut Schaa <[email protected]>
> Date: Mon Apr 26 13:48:45 2010 +0200
>
> rt2x00: rt2800lib: Fix rx path on SoC devices
>
> my card becomes unstable, I mean that the connection lose packets and
> sometimes it disassociates from the AP.
> I also found that the singnal level reported by iwconfig is wrong (it
> reports -191dBm)

Uhhh, are you 100% sure? The patch doesn't touch any PCI code at all.
Maybe the card was unstable before already? Could you please verify again?

Thanks you very much for your testing, it's really appreciated.

Helmut

2010-04-11 12:31:29

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 7/9] rt2x00: Add rt3071 support in rt2800 register initialization.

Add RT3071 specific register initializations to rt2x00, based on the latest
Ralink rt3070 vendor driver.

With this patch my RT3071 based devices start showing a sign of life.

Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 102 ++++++++++++++++++++++++++++---
1 files changed, 93 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 7d1cb7e..fe7171f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1042,7 +1042,8 @@ EXPORT_SYMBOL_GPL(rt2800_link_stats);
static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
{
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
- if (rt2x00_rt(rt2x00dev, RT3070))
+ if (rt2x00_rt(rt2x00dev, RT3070) ||
+ rt2x00_rt(rt2x00dev, RT3071))
return 0x1c + (2 * rt2x00dev->lna_gain);
else
return 0x2e + rt2x00dev->lna_gain;
@@ -1091,6 +1092,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
+ u16 eeprom;
unsigned int i;

rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
@@ -1190,7 +1192,22 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);

- if (rt2x00_rt(rt2x00dev, RT3070)) {
+ if (rt2x00_rt(rt2x00dev, RT3071)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2,
+ 0x0000002c);
+ else
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2,
+ 0x0000000f);
+ } else {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ }
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, reg);
+ } else if (rt2x00_rt(rt2x00dev, RT3070)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);

if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@@ -1540,7 +1557,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)

rt2800_bbp_write(rt2x00dev, 70, 0x0a);

- if (rt2x00_rt(rt2x00dev, RT3070)) {
+ if (rt2x00_rt(rt2x00dev, RT3070) ||
+ rt2x00_rt(rt2x00dev, RT3071)) {
rt2800_bbp_write(rt2x00dev, 79, 0x13);
rt2800_bbp_write(rt2x00dev, 80, 0x05);
rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -1561,7 +1579,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 91, 0x04);
rt2800_bbp_write(rt2x00dev, 92, 0x00);

- if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F))
+ if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
+ rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E))
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
else
rt2800_bbp_write(rt2x00dev, 103, 0x00);
@@ -1569,6 +1588,18 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 105, 0x05);
rt2800_bbp_write(rt2x00dev, 106, 0x35);

+ if (rt2x00_rt(rt2x00dev, RT3071)) {
+ rt2800_bbp_read(rt2x00dev, 138, &value);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
+ value |= 0x20;
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
+ value &= ~0x02;
+
+ rt2800_bbp_write(rt2x00dev, 138, value);
+ }
+
if (rt2x00_rt(rt2x00dev, RT2872)) {
rt2800_bbp_write(rt2x00dev, 31, 0x08);
rt2800_bbp_write(rt2x00dev, 78, 0x0e);
@@ -1656,7 +1687,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
u32 reg;
u16 eeprom;

- if (!rt2x00_rt(rt2x00dev, RT3070))
+ if (!rt2x00_rt(rt2x00dev, RT3070) &&
+ !rt2x00_rt(rt2x00dev, RT3071))
return 0;

/*
@@ -1669,7 +1701,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);

- if (rt2x00_rt(rt2x00dev, RT3070)) {
+ if (rt2x00_rt(rt2x00dev, RT3070) ||
+ rt2x00_rt(rt2x00dev, RT3071)) {
rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
@@ -1696,6 +1729,23 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+ } else if (rt2x00_rt(rt2x00dev, RT3071)) {
+ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1);
+ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+ rt2800_rfcsr_write(rt2x00dev, 31, 0x14);
+
+ rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+ rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
+ rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+ else
+ rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
+ }
+ rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
}

/*
@@ -1706,6 +1756,11 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
rt2x00dev->calibration[1] =
rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+ } else if (rt2x00_rt(rt2x00dev, RT3071)) {
+ rt2x00dev->calibration[0] =
+ rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
+ rt2x00dev->calibration[1] =
+ rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15);
}

/*
@@ -1724,7 +1779,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
rt2800_bbp_write(rt2x00dev, 4, bbp);

- if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F))
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E))
rt2800_rfcsr_write(rt2x00dev, 27, 0x03);

rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg);
@@ -1733,6 +1789,11 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)

rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+ rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
+ }
rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
@@ -1740,9 +1801,32 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
EEPROM_TXMIXER_GAIN_BG_VAL));
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);

- if (rt2x00_rt(rt2x00dev, RT3070)) {
+ if (rt2x00_rt(rt2x00dev, RT3071)) {
+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 15, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR15_TX_LO2_EN, 0);
+ rt2800_rfcsr_write(rt2x00dev, 15, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR20_RX_LO1_EN, 0);
+ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR21_RX_LO2_EN, 0);
+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
+ }
+
+ if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071)) {
rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr);
- if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F))
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E))
rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3);
else
rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0);
--
1.7.0.4


2010-04-26 11:02:28

by Helmut Schaa

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> rt2x00 had preliminary support for RT3070 based devices, but the support was
> incomplete.
> Update the RT3070 register initialization to be similar to the latest Ralink
> vendor driver.
>
> With this patch my rt3070 based devices start showing a sign of life.

Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
more details.

[...]

> @@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> {
> u8 rfcsr;
> u8 bbp;
> + u32 reg;
> + u16 eeprom;
>
> - if (rt2x00_is_usb(rt2x00dev) &&
> - !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
> + if (!rt2x00_rt(rt2x00dev, RT3070))
> return 0;
>
> - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> - if (!rt2x00_rf(rt2x00dev, RF3020) &&
> - !rt2x00_rf(rt2x00dev, RF3021) &&
> - !rt2x00_rf(rt2x00dev, RF3022))
> - return 0;
> - }

Any reason why you've removed this part? The following code was executed on
pci and soc devices when they had an 3020, 3021 or 3022 rf.

> /*
> * Init RF calibration.
> */
> @@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
> rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
>
> - if (rt2x00_is_usb(rt2x00dev)) {
> + if (rt2x00_rt(rt2x00dev, RT3070)) {
> rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
> rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> - rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
> + rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
> rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
> rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> @@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
> rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> - rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
> rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
> - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> - rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
> - rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
> - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
> - rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
> - rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> - rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> - rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> - rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
> - rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
> - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> - rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
> - rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> - rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
> - rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
> - rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> - rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
> - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
> - rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
> - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
> - rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
> - rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
> - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> - rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
> - rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
> - rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
> - rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> - rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
> - rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
> - rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
> - rt2800_rfcsr_write(rt2x00dev, 29, 0x83);

This part is actually needed for getting rx to work on the SoC devices.

Should I post a patch that adds this code again and is only executed on SoC
devices with rf3020, 3021 and 3022?

Thanks,
Helmut

2010-04-10 19:14:05

by Gertjan van Wingerde

[permalink] [raw]
Subject: Re: [PATCH 5/9] rt2x00: Align rt2800 register initialization with vendor driver.

On 04/09/10 00:33, Ivo van Doorn wrote:
> On Thursday 08 April 2010, Gertjan van Wingerde wrote:
>> Align the rt2800 register initializations with the latest versions of the
>> Ralink vendor driver.
>> This patch is also preparation for the addition of support for RT3070 /
>> RT3071 / RT3090 / RT3390 based devices.
>>
>> Signed-off-by: Gertjan van Wingerde <[email protected]>
>> ---
>> drivers/net/wireless/rt2x00/rt2800lib.c | 155 +++++++++++++++++++++++--------
>> drivers/net/wireless/rt2x00/rt2800pci.c | 13 ---
>> 2 files changed, 114 insertions(+), 54 deletions(-)
>
>> @@ -531,12 +526,8 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
>> !(filter_flags & FIF_PLCPFAIL));
>> rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME,
>> !(filter_flags & FIF_PROMISC_IN_BSS));
>> - rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
>> - rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
>> rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST,
>> !(filter_flags & FIF_ALLMULTI));
>> - rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BROADCAST, 0);
>> - rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_DUPLICATE, 1);
>> rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END_ACK,
>> !(filter_flags & FIF_CONTROL));
>> rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END,
>> @@ -549,8 +540,6 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
>> !(filter_flags & FIF_CONTROL));
>> rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
>> !(filter_flags & FIF_PSPOLL));
>> - rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
>> - rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
>> rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
>> !(filter_flags & FIF_CONTROL));
>> rt2800_register_write(rt2x00dev, RX_FILTER_CFG, reg);
>
> I'm not a big fan of these changes. Unless the filters don't work as expected,
> I rather see the entire list of filters set to their correct values here.

OK. I'll back this out for now. I removed these bits as they now are being set at initialization
time already, and it didn't seem necessary to program these particular filters again to the same
value. But it is not critical, and it doesn't fix anything anyway.

>
>> @@ -1176,6 +1179,31 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>> rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
>> rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
>>
>> + rt2800_register_read(rt2x00dev, RX_FILTER_CFG, &reg);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CRC_ERROR, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PHY_ERROR, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST, 0);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BROADCAST, 0);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_DUPLICATE, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END_ACK, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_ACK, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CTS, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_RTS, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
>> + rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL, 1);
>> + rt2800_register_write(rt2x00dev, RX_FILTER_CFG, reg);
>
> Can't we just fix this by calling the config_filter() function with the proper settings?
> This function is getting huge by now, so we could try to reduce it a bit.

Yep, it should be doable to do this by calling config_filter.

>
>> @@ -1214,38 +1243,61 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>> rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
>> rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
>>
>> + rt2800_register_read(rt2x00dev, LED_CFG, &reg);
>> + rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, 70);
>> + rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, 30);
>> + rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
>> + rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
>> + rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
>> + rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
>> + rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
>> + rt2800_register_write(rt2x00dev, LED_CFG, reg);
>
> Same here.

That's difficult. We have no other function simply manipulating the LED_CFG register.
There is rt2800_blink_set, but that is working completely different.
I'd prefer to leave this as is, instead of introducing another small helper.

>
>> rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
>>
>> + rt2800_register_read(rt2x00dev, TX_RTY_CFG, &reg);
>> + rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
>> + rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
>> + rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
>> + rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
>> + rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
>> + rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
>> + rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
>
> And here.

Same as for LED_CFG. Using rt2800_config_retry_limit would involve setting up a
complete libconf structure. Seems like a bit of overkill for the purpose.

>
>> + if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
>> + rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 1);
>> + else if (rt2x00_is_usb(rt2x00dev))
>> + rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
>
> perhaps:
> rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, !rt2x00_is_usb(rt2x00dev));

Hmm, could be. Not too fond of that construction though. I think the somewhat more verbose
variant I had is clearer and easier to understand what is going on.

>
>> @@ -1323,6 +1382,15 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>> rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
>>
>> rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
>> +
>> + rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
>> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, 32);
>> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, 32);
>> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
>> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, 314);
>> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
>> + rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
>
> Not really fond of the magical values written to the device, while mac80211
> sends us the proper values later. This is probably a register initialization ordering issue?

These magical values come straight from the Ralink vendor driver. As you know that code isn't
the best documented code we've seen, so I don't know what these magical values actually represent.
They are just initialization values for the time until we get associated.

For code clarity in comparison to the Ralink vendor driver I prefer to leave these in.

---
Gertjan

2010-04-11 12:31:26

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 9/9] rt2x00: Add rt3390 support in rt2800 register initialization.

Add RT3390 specific register initializations to rt2x00, based on the latest
Ralink rt3390 vendor driver.

Untested as I don't actually own an RT3390 based device, but given experiences
on rt3070/rt3071 very hopeful that this will actually work..

Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 70 ++++++++++++++++++++++++++-----
1 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index d746082..6386000 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1044,7 +1044,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090))
+ rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3390))
return 0x1c + (2 * rt2x00dev->lna_gain);
else
return 0x2e + rt2x00dev->lna_gain;
@@ -1194,11 +1195,13 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);

if (rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090)) {
+ rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3390)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
- rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
+ rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
@@ -1562,7 +1565,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)

if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090)) {
+ rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3390)) {
rt2800_bbp_write(rt2x00dev, 79, 0x13);
rt2800_bbp_write(rt2x00dev, 80, 0x05);
rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -1585,7 +1589,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)

if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
- rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E))
+ rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
+ rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E))
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
else
rt2800_bbp_write(rt2x00dev, 103, 0x00);
@@ -1594,7 +1599,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 106, 0x35);

if (rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090)) {
+ rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3390)) {
rt2800_bbp_read(rt2x00dev, 138, &value);

rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
@@ -1695,7 +1701,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)

if (!rt2x00_rt(rt2x00dev, RT3070) &&
!rt2x00_rt(rt2x00dev, RT3071) &&
- !rt2x00_rt(rt2x00dev, RT3090))
+ !rt2x00_rt(rt2x00dev, RT3090) &&
+ !rt2x00_rt(rt2x00dev, RT3390))
return 0;

/*
@@ -1730,6 +1737,39 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
+ } else if (rt2x00_rt(rt2x00dev, RT3390)) {
+ rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
+ rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
+ rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
+ rt2800_rfcsr_write(rt2x00dev, 3, 0x62);
+ rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
+ rt2800_rfcsr_write(rt2x00dev, 5, 0x8b);
+ rt2800_rfcsr_write(rt2x00dev, 6, 0x42);
+ rt2800_rfcsr_write(rt2x00dev, 7, 0x34);
+ rt2800_rfcsr_write(rt2x00dev, 8, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
+ rt2800_rfcsr_write(rt2x00dev, 10, 0x61);
+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
+ rt2800_rfcsr_write(rt2x00dev, 12, 0x3b);
+ rt2800_rfcsr_write(rt2x00dev, 13, 0xe0);
+ rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
+ rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
+ rt2800_rfcsr_write(rt2x00dev, 16, 0xe0);
+ rt2800_rfcsr_write(rt2x00dev, 17, 0x94);
+ rt2800_rfcsr_write(rt2x00dev, 18, 0x5c);
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x4a);
+ rt2800_rfcsr_write(rt2x00dev, 20, 0xb2);
+ rt2800_rfcsr_write(rt2x00dev, 21, 0xf6);
+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 23, 0x14);
+ rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x3d);
+ rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+ rt2800_rfcsr_write(rt2x00dev, 28, 0x41);
+ rt2800_rfcsr_write(rt2x00dev, 29, 0x8f);
+ rt2800_rfcsr_write(rt2x00dev, 30, 0x20);
+ rt2800_rfcsr_write(rt2x00dev, 31, 0x0f);
}

if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@@ -1756,6 +1796,10 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
}
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+ } else if (rt2x00_rt(rt2x00dev, RT3390)) {
+ rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
+ rt2x00_set_field32(&reg, GPIO_SWITCH_5, 0);
+ rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
}

/*
@@ -1767,7 +1811,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00dev->calibration[1] =
rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
} else if (rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090)) {
+ rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3390)) {
rt2x00dev->calibration[0] =
rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
rt2x00dev->calibration[1] =
@@ -1792,7 +1837,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)

if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
- rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E))
+ rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E))
rt2800_rfcsr_write(rt2x00dev, 27, 0x03);

rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg);
@@ -1802,7 +1848,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
- rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
+ rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
@@ -1827,7 +1874,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
}

if (rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3090)) {
+ rt2x00_rt(rt2x00dev, RT3090) ||
+ rt2x00_rt(rt2x00dev, RT3390)) {
rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
--
1.7.0.4


2010-04-28 13:09:43

by Antonio Quartulli

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

On mar, apr 27, 2010 at 01:15:21 +0200, Antonio Quartulli wrote:
> On lun, apr 26, 2010 at 01:11:20 +0200, Helmut Schaa wrote:
> > Am Montag 26 April 2010 schrieb Helmut Schaa:
> > > Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> > > > rt2x00 had preliminary support for RT3070 based devices, but the support was
> > > > incomplete.
> > > > Update the RT3070 register initialization to be similar to the latest Ralink
> > > > vendor driver.
> > > >
> > > > With this patch my rt3070 based devices start showing a sign of life.
> > >
> > > Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> > > more details.
> >
> > Antonio, did that patch also break rx on your PCI device with rt2872?
> > If not this is only needed for SoC.
> Hi, I cloned the wireless-testing git a few minutes ago.
> My card (rt2x00_set_chip: Info - Chipset detected - rt: 2872, rf: 0003,
> rev: 0200) on miniPCI works correctly without any kind of problem.
> No hangs at all.

Hi all, I found out that after this commit:

commit 23812383c6b03afef44c4aa642500f8235c3d079
Author: Helmut Schaa <[email protected]>
Date: Mon Apr 26 13:48:45 2010 +0200

rt2x00: rt2800lib: Fix rx path on SoC devices

my card becomes unstable, I mean that the connection lose packets and
sometimes it disassociates from the AP.
I also found that the singnal level reported by iwconfig is wrong (it
reports -191dBm)

Regards

>
> Regards
>
> >
> > Thanks,
> > Helmut
> >
> > > [...]
> > >
> > > > @@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > > > {
> > > > u8 rfcsr;
> > > > u8 bbp;
> > > > + u32 reg;
> > > > + u16 eeprom;
> > > >
> > > > - if (rt2x00_is_usb(rt2x00dev) &&
> > > > - !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
> > > > + if (!rt2x00_rt(rt2x00dev, RT3070))
> > > > return 0;
> > > >
> > > > - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > > > - if (!rt2x00_rf(rt2x00dev, RF3020) &&
> > > > - !rt2x00_rf(rt2x00dev, RF3021) &&
> > > > - !rt2x00_rf(rt2x00dev, RF3022))
> > > > - return 0;
> > > > - }
> > >
> > > Any reason why you've removed this part? The following code was executed on
> > > pci and soc devices when they had an 3020, 3021 or 3022 rf.
> > >
> > > > /*
> > > > * Init RF calibration.
> > > > */
> > > > @@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > > > rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
> > > > rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
> > > >
> > > > - if (rt2x00_is_usb(rt2x00dev)) {
> > > > + if (rt2x00_rt(rt2x00dev, RT3070)) {
> > > > rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > > > rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > > > rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > > > rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
> > > > rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > > > - rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
> > > > + rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
> > > > rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > > > rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
> > > > rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > > > @@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > > > rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > > > rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
> > > > rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > > > - rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
> > > > rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
> > > > - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > > > - rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
> > > > - rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
> > > > - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
> > > > - rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
> > > > - rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > > > - rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > > > - rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > > > - rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
> > > > - rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
> > > > - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > > > - rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
> > > > - rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > > > - rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
> > > > - rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
> > > > - rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > > > - rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
> > > > - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
> > > > - rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
> > > > - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
> > > > - rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
> > > > - rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
> > > > - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > > > - rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
> > > > - rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
> > > > - rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
> > > > - rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > > > - rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
> > > > - rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
> > > > - rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
> > > > - rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
> > >
> > > This part is actually needed for getting rx to work on the SoC devices.
> > >
> > > Should I post a patch that adds this code again and is only executed on SoC
> > > devices with rf3020, 3021 and 3022?
> > >
> > > Thanks,
> > > Helmut
> > >
>
> --
> Antonio Quartulli
>
> Ognuno di noi, da solo, non vale nulla
> Ernesto "Che" Guevara
>
> _______________________________________________
> users mailing list
> [email protected]
> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com

--
Antonio Quartulli

Ognuno di noi, da solo, non vale nulla
Ernesto "Che" Guevara

2010-04-26 19:59:48

by Helmut Schaa

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

Am Montag 26 April 2010 schrieb Gertjan van Wingerde:
> On 04/26/10 13:02, Helmut Schaa wrote:
> > Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> >> rt2x00 had preliminary support for RT3070 based devices, but the support was
> >> incomplete.
> >> Update the RT3070 register initialization to be similar to the latest Ralink
> >> vendor driver.
> >>
> >> With this patch my rt3070 based devices start showing a sign of life.
> >
> > Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> > more details.
> >
> > [...]
> >
> >> @@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> >> {
> >> u8 rfcsr;
> >> u8 bbp;
> >> + u32 reg;
> >> + u16 eeprom;
> >>
> >> - if (rt2x00_is_usb(rt2x00dev) &&
> >> - !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
> >> + if (!rt2x00_rt(rt2x00dev, RT3070))
> >> return 0;
> >>
> >> - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> >> - if (!rt2x00_rf(rt2x00dev, RF3020) &&
> >> - !rt2x00_rf(rt2x00dev, RF3021) &&
> >> - !rt2x00_rf(rt2x00dev, RF3022))
> >> - return 0;
> >> - }
> >
> > Any reason why you've removed this part? The following code was executed on
> > pci and soc devices when they had an 3020, 3021 or 3022 rf.
>
> I removed it because the Ralink driver only checks for RT chipset type, not for
> the RF chipset type. Looks like that in the conversion the unmentioned RT2872
> got lost.
>
> >
> >> /*
> >> * Init RF calibration.
> >> */
> >> @@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> >> rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
> >> rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
> >>
> >> - if (rt2x00_is_usb(rt2x00dev)) {
> >> + if (rt2x00_rt(rt2x00dev, RT3070)) {
> >> rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> >> rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> >> rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> >> rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
> >> rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> >> - rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
> >> + rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
> >> rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> >> rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
> >> rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> >> @@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> >> rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> >> rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
> >> rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> >> - rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
> >> rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
> >> - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> >> - rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
> >> - rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
> >> - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
> >> - rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
> >> - rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> >> - rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> >> - rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> >> - rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
> >> - rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
> >> - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> >> - rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
> >> - rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> >> - rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
> >> - rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
> >> - rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> >> - rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
> >> - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
> >> - rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
> >> - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
> >> - rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
> >> - rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
> >> - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> >> - rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
> >> - rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
> >> - rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
> >> - rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> >> - rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
> >> - rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
> >> - rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
> >> - rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
> >
> > This part is actually needed for getting rx to work on the SoC devices.
>
> Hmm, interesting, as I don't know where this code actually came from. It isn't needed for
> PCI devices in general (at least not the PCI devices I've checked), so it may be specific to SoC.
>
> >
> > Should I post a patch that adds this code again and is only executed on SoC
> > devices with rf3020, 3021 and 3022?
> >
>
> OK. I have just checked the two RT2872 based devices I have (one PCI one and one USB one),
> and both of them act very strangely.

Strangely ;) ? The SoC device was basically able to transmit frames but
could't receive at all (at least that was my impression). Do you have a
different issue?

> I'll check against the Ralink SoC driver code that I've got as to how the initialization should actually
> be.

Ok.

Helmut

2010-04-26 11:12:53

by Helmut Schaa

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

Am Montag 26 April 2010 schrieb Helmut Schaa:
> Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> > rt2x00 had preliminary support for RT3070 based devices, but the support was
> > incomplete.
> > Update the RT3070 register initialization to be similar to the latest Ralink
> > vendor driver.
> >
> > With this patch my rt3070 based devices start showing a sign of life.
>
> Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> more details.

Antonio, did that patch also break rx on your PCI device with rt2872?
If not I'm going to enable this code only on SOC devices.

Thanks,
Helmut

> [...]
>
> > @@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > {
> > u8 rfcsr;
> > u8 bbp;
> > + u32 reg;
> > + u16 eeprom;
> >
> > - if (rt2x00_is_usb(rt2x00dev) &&
> > - !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
> > + if (!rt2x00_rt(rt2x00dev, RT3070))
> > return 0;
> >
> > - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > - if (!rt2x00_rf(rt2x00dev, RF3020) &&
> > - !rt2x00_rf(rt2x00dev, RF3021) &&
> > - !rt2x00_rf(rt2x00dev, RF3022))
> > - return 0;
> > - }
>
> Any reason why you've removed this part? The following code was executed on
> pci and soc devices when they had an 3020, 3021 or 3022 rf.
>
> > /*
> > * Init RF calibration.
> > */
> > @@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
> > rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
> >
> > - if (rt2x00_is_usb(rt2x00dev)) {
> > + if (rt2x00_rt(rt2x00dev, RT3070)) {
> > rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
> > rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > - rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
> > + rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
> > rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
> > rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > @@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
> > rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > - rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
> > rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
> > - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > - rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
> > - rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
> > - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
> > - rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
> > - rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > - rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > - rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > - rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
> > - rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
> > - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > - rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
> > - rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > - rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
> > - rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
> > - rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > - rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
> > - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
> > - rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
> > - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
> > - rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
> > - rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
> > - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > - rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
> > - rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
> > - rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
> > - rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > - rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
> > - rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
> > - rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
> > - rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
>
> This part is actually needed for getting rx to work on the SoC devices.
>
> Should I post a patch that adds this code again and is only executed on SoC
> devices with rf3020, 3021 and 3022?
>
> Thanks,
> Helmut
>


2010-04-11 16:56:31

by Ivo Van Doorn

[permalink] [raw]
Subject: Re: [PATCH 5/9] rt2x00: Align rt2800 register initialization with vendor driver.

On Sunday 11 April 2010, Gertjan van Wingerde wrote:
> Align the rt2800 register initializations with the latest versions of the
> Ralink vendor driver.
> This patch is also preparation for the addition of support for RT3070 /
> RT3071 / RT3090 / RT3390 based devices.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>

Acked-by: Ivo van Doorn <[email protected]>



2010-04-26 19:52:31

by Gertjan van Wingerde

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

On 04/26/10 13:02, Helmut Schaa wrote:
> Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
>> rt2x00 had preliminary support for RT3070 based devices, but the support was
>> incomplete.
>> Update the RT3070 register initialization to be similar to the latest Ralink
>> vendor driver.
>>
>> With this patch my rt3070 based devices start showing a sign of life.
>
> Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> more details.
>
> [...]
>
>> @@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>> {
>> u8 rfcsr;
>> u8 bbp;
>> + u32 reg;
>> + u16 eeprom;
>>
>> - if (rt2x00_is_usb(rt2x00dev) &&
>> - !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
>> + if (!rt2x00_rt(rt2x00dev, RT3070))
>> return 0;
>>
>> - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
>> - if (!rt2x00_rf(rt2x00dev, RF3020) &&
>> - !rt2x00_rf(rt2x00dev, RF3021) &&
>> - !rt2x00_rf(rt2x00dev, RF3022))
>> - return 0;
>> - }
>
> Any reason why you've removed this part? The following code was executed on
> pci and soc devices when they had an 3020, 3021 or 3022 rf.

I removed it because the Ralink driver only checks for RT chipset type, not for
the RF chipset type. Looks like that in the conversion the unmentioned RT2872
got lost.

>
>> /*
>> * Init RF calibration.
>> */
>> @@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>> rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
>> rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
>>
>> - if (rt2x00_is_usb(rt2x00dev)) {
>> + if (rt2x00_rt(rt2x00dev, RT3070)) {
>> rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
>> rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
>> rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
>> rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
>> rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
>> - rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
>> + rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
>> rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
>> rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
>> rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
>> @@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>> rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
>> rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
>> rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
>> - rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
>> rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
>> - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
>> - rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
>> - rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
>> - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
>> - rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
>> - rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
>> - rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
>> - rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
>> - rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
>> - rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
>> - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
>> - rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
>> - rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
>> - rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
>> - rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
>> - rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
>> - rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
>> - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
>> - rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
>> - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
>> - rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
>> - rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
>> - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
>> - rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
>> - rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
>> - rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
>> - rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
>> - rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
>> - rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
>> - rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
>> - rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
>
> This part is actually needed for getting rx to work on the SoC devices.

Hmm, interesting, as I don't know where this code actually came from. It isn't needed for
PCI devices in general (at least not the PCI devices I've checked), so it may be specific to SoC.

>
> Should I post a patch that adds this code again and is only executed on SoC
> devices with rf3020, 3021 and 3022?
>

OK. I have just checked the two RT2872 based devices I have (one PCI one and one USB one),
and both of them act very strangely.

I'll check against the Ralink SoC driver code that I've got as to how the initialization should actually
be.

---
Gertjan.

2010-04-11 12:31:25

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

rt2x00 had preliminary support for RT3070 based devices, but the support was
incomplete.
Update the RT3070 register initialization to be similar to the latest Ralink
vendor driver.

With this patch my rt3070 based devices start showing a sign of life.

Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 133 ++++++++++++++++--------------
1 files changed, 71 insertions(+), 62 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 1890b9a..7d1cb7e 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1042,8 +1042,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_stats);
static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
{
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
- if (rt2x00_is_usb(rt2x00dev) &&
- rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
+ if (rt2x00_rt(rt2x00dev, RT3070))
return 0x1c + (2 * rt2x00dev->lna_gain);
else
return 0x2e + rt2x00dev->lna_gain;
@@ -1191,11 +1190,16 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);

- if (rt2x00_is_usb(rt2x00dev) &&
- rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E)) {
+ if (rt2x00_rt(rt2x00dev, RT3070)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000002c);
+ } else {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ }
} else {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -1535,7 +1539,15 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
}

rt2800_bbp_write(rt2x00dev, 70, 0x0a);
- rt2800_bbp_write(rt2x00dev, 81, 0x37);
+
+ if (rt2x00_rt(rt2x00dev, RT3070)) {
+ rt2800_bbp_write(rt2x00dev, 79, 0x13);
+ rt2800_bbp_write(rt2x00dev, 80, 0x05);
+ rt2800_bbp_write(rt2x00dev, 81, 0x33);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 81, 0x37);
+ }
+
rt2800_bbp_write(rt2x00dev, 82, 0x62);
rt2800_bbp_write(rt2x00dev, 83, 0x6a);

@@ -1548,7 +1560,12 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 86, 0x00);
rt2800_bbp_write(rt2x00dev, 91, 0x04);
rt2800_bbp_write(rt2x00dev, 92, 0x00);
- rt2800_bbp_write(rt2x00dev, 103, 0x00);
+
+ if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F))
+ rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+ else
+ rt2800_bbp_write(rt2x00dev, 103, 0x00);
+
rt2800_bbp_write(rt2x00dev, 105, 0x05);
rt2800_bbp_write(rt2x00dev, 106, 0x35);

@@ -1558,13 +1575,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 80, 0x08);
}

- if (rt2x00_is_usb(rt2x00dev) &&
- rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E)) {
- rt2800_bbp_write(rt2x00dev, 70, 0x0a);
- rt2800_bbp_write(rt2x00dev, 84, 0x99);
- rt2800_bbp_write(rt2x00dev, 105, 0x05);
- }
-
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);

@@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
{
u8 rfcsr;
u8 bbp;
+ u32 reg;
+ u16 eeprom;

- if (rt2x00_is_usb(rt2x00dev) &&
- !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
+ if (!rt2x00_rt(rt2x00dev, RT3070))
return 0;

- if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
- if (!rt2x00_rf(rt2x00dev, RF3020) &&
- !rt2x00_rf(rt2x00dev, RF3021) &&
- !rt2x00_rf(rt2x00dev, RF3022))
- return 0;
- }
-
/*
* Init RF calibration.
*/
@@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);

- if (rt2x00_is_usb(rt2x00dev)) {
+ if (rt2x00_rt(rt2x00dev, RT3070)) {
rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
- rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
+ rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
@@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
- rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
- } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
- rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
- rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
- rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
- rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
- rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
- rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
- rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
- rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
- rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
- rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
- rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
- rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
- rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
- rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
- rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
- rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
- rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
- rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
- rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
- rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
- rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
- rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
- rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
- rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
- rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
- rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
- rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
- rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
- rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
- rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
+ }
+
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
+ rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+ rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+ rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+ rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
}

/*
* Set RX Filter calibration for 20MHz and 40MHz
*/
- rt2x00dev->calibration[0] =
- rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
- rt2x00dev->calibration[1] =
- rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+ if (rt2x00_rt(rt2x00dev, RT3070)) {
+ rt2x00dev->calibration[0] =
+ rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
+ rt2x00dev->calibration[1] =
+ rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+ }

/*
* Set back to initial state
@@ -1743,6 +1724,34 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
rt2800_bbp_write(rt2x00dev, 4, bbp);

+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F))
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
+
+ rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg);
+ rt2x00_set_field32(&reg, OPT_14_CSR_BIT0, 1);
+ rt2800_register_write(rt2x00dev, OPT_14_CSR, reg);
+
+ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
+ rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
+ rt2x00_get_field16(eeprom,
+ EEPROM_TXMIXER_GAIN_BG_VAL));
+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+
+ if (rt2x00_rt(rt2x00dev, RT3070)) {
+ rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr);
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F))
+ rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR27_R2, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR27_R3, 0);
+ rt2x00_set_field8(&rfcsr, RFCSR27_R4, 0);
+ rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(rt2800_init_rfcsr);
--
1.7.0.4


2010-04-11 16:57:12

by Ivo Van Doorn

[permalink] [raw]
Subject: Re: [PATCH 7/9] rt2x00: Add rt3071 support in rt2800 register initialization.

On Sunday 11 April 2010, Gertjan van Wingerde wrote:
> Add RT3071 specific register initializations to rt2x00, based on the latest
> Ralink rt3070 vendor driver.
>
> With this patch my RT3071 based devices start showing a sign of life.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>

Acked-by: Ivo van Doorn <[email protected]>


2010-04-11 12:31:25

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 4/9] rt2x00: Refactor rt2800 version constants.

The rt2800 version constants are inconsistent, and the version number don't
mean a lot of things anyway. Refactor the constants to have some more
meaningful names, and introduce and use some new helpers to check these
chipset revisions. At the same time rename to revision, as they are more
revision numbers rather than version numbers.

Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 16 ++++++++++------
drivers/net/wireless/rt2x00/rt2800lib.c | 30 ++++++++++--------------------
drivers/net/wireless/rt2x00/rt2x00.h | 22 ++++++++++++++++++++--
3 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 4d5871b..ec89372 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -59,13 +59,17 @@
#define RF3320 0x000b

/*
- * Chipset version.
- */
-#define RT2860C_VERSION 0x0100
-#define RT2860D_VERSION 0x0101
-#define RT2880E_VERSION 0x0200
-#define RT2883_VERSION 0x0300
-#define RT3070_VERSION 0x0200
+ * Chipset revisions.
+ */
+#define REV_RT2860C 0x0100
+#define REV_RT2860D 0x0101
+#define REV_RT2870D 0x0101
+#define REV_RT2872E 0x0200
+#define REV_RT3070E 0x0200
+#define REV_RT3070F 0x0201
+#define REV_RT3071E 0x0211
+#define REV_RT3090E 0x0211
+#define REV_RT3390E 0x0211

/*
* Signal information.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 2ab8884..8a4ed76 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -896,8 +896,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
rt2800_bbp_write(rt2x00dev, 3, bbp);

- if (rt2x00_rt(rt2x00dev, RT2860) &&
- (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
+ if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
if (conf_is_ht40(conf)) {
rt2800_bbp_write(rt2x00dev, 69, 0x1a);
rt2800_bbp_write(rt2x00dev, 70, 0x0a);
@@ -1060,8 +1059,7 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
{
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
if (rt2x00_is_usb(rt2x00dev) &&
- rt2x00_rt(rt2x00dev, RT3070) &&
- (rt2x00_rev(rt2x00dev) == RT3070_VERSION))
+ rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
return 0x1c + (2 * rt2x00dev->lna_gain);
else
return 0x2e + rt2x00dev->lna_gain;
@@ -1092,8 +1090,7 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
const u32 count)
{
- if (rt2x00_rt(rt2x00dev, RT2860) &&
- (rt2x00_rev(rt2x00dev) == RT2860C_VERSION))
+ if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C))
return;

/*
@@ -1179,8 +1176,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);

if (rt2x00_is_usb(rt2x00dev) &&
- rt2x00_rt(rt2x00dev, RT3070) &&
- (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
+ rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -1207,11 +1203,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)

rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
- if ((rt2x00_rt(rt2x00dev, RT2872) &&
- (rt2x00_rev(rt2x00dev) >= RT2880E_VERSION)) ||
+ if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
rt2x00_rt(rt2x00dev, RT2883) ||
- (rt2x00_rt(rt2x00dev, RT3070) &&
- (rt2x00_rev(rt2x00dev) < RT3070_VERSION)))
+ rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
else
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
@@ -1490,14 +1484,12 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 103, 0x00);
rt2800_bbp_write(rt2x00dev, 105, 0x05);

- if (rt2x00_rt(rt2x00dev, RT2860) &&
- (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
+ if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
rt2800_bbp_write(rt2x00dev, 69, 0x16);
rt2800_bbp_write(rt2x00dev, 73, 0x12);
}

- if (rt2x00_rt(rt2x00dev, RT2860) &&
- (rt2x00_rev(rt2x00dev) > RT2860D_VERSION))
+ if (rt2x00_rt_rev_gte(rt2x00dev, RT2860, REV_RT2860D))
rt2800_bbp_write(rt2x00dev, 84, 0x19);

if (rt2x00_rt(rt2x00dev, RT2872)) {
@@ -1507,8 +1499,7 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
}

if (rt2x00_is_usb(rt2x00dev) &&
- rt2x00_rt(rt2x00dev, RT3070) &&
- (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
+ rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E)) {
rt2800_bbp_write(rt2x00dev, 70, 0x0a);
rt2800_bbp_write(rt2x00dev, 84, 0x99);
rt2800_bbp_write(rt2x00dev, 105, 0x05);
@@ -1594,8 +1585,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
u8 bbp;

if (rt2x00_is_usb(rt2x00dev) &&
- rt2x00_rt(rt2x00dev, RT3070) &&
- (rt2x00_rev(rt2x00dev) != RT3070_VERSION))
+ !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
return 0;

if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 16aa850..4de505b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -929,12 +929,12 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev);
}

-static inline char rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt)
+static inline bool rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt)
{
return (rt2x00dev->chip.rt == rt);
}

-static inline char rt2x00_rf(struct rt2x00_dev *rt2x00dev, const u16 rf)
+static inline bool rt2x00_rf(struct rt2x00_dev *rt2x00dev, const u16 rf)
{
return (rt2x00dev->chip.rf == rf);
}
@@ -944,6 +944,24 @@ static inline u16 rt2x00_rev(struct rt2x00_dev *rt2x00dev)
return rt2x00dev->chip.rev;
}

+static inline bool rt2x00_rt_rev(struct rt2x00_dev *rt2x00dev,
+ const u16 rt, const u16 rev)
+{
+ return (rt2x00_rt(rt2x00dev, rt) && rt2x00_rev(rt2x00dev) == rev);
+}
+
+static inline bool rt2x00_rt_rev_lt(struct rt2x00_dev *rt2x00dev,
+ const u16 rt, const u16 rev)
+{
+ return (rt2x00_rt(rt2x00dev, rt) && rt2x00_rev(rt2x00dev) < rev);
+}
+
+static inline bool rt2x00_rt_rev_gte(struct rt2x00_dev *rt2x00dev,
+ const u16 rt, const u16 rev)
+{
+ return (rt2x00_rt(rt2x00dev, rt) && rt2x00_rev(rt2x00dev) >= rev);
+}
+
static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev,
enum rt2x00_chip_intf intf)
{
--
1.7.0.4


2010-04-11 12:31:25

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 1/9] rt2x00: Let RF chipset decide the RF channel switch method to use in rt2800.

It seems that the distinction between RF channel switch method is solely based
on the RF chipset that is used.
Refactor the channel switch decision to just take the RF chipset into account,
thereby greatly simplifying the check.

Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 31 ++++++++++++++-----------------
1 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index ec3ec78..6fdec15 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -717,10 +717,10 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
rt2x00dev->lna_gain = lna_gain;
}

-static void rt2800_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf,
- struct rf_channel *rf,
- struct channel_info *info)
+static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
{
rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);

@@ -786,10 +786,10 @@ static void rt2800_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
rt2800_rf_write(rt2x00dev, 4, rf->rf4);
}

-static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf,
- struct rf_channel *rf,
- struct channel_info *info)
+static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
{
u8 rfcsr;

@@ -826,16 +826,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
unsigned int tx_pin;
u8 bbp;

- if ((rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3090) ||
- rt2x00_rt(rt2x00dev, RT2872)) &&
- (rt2x00_rf(rt2x00dev, RF2020) ||
- rt2x00_rf(rt2x00dev, RF3020) ||
- rt2x00_rf(rt2x00dev, RF3021) ||
- rt2x00_rf(rt2x00dev, RF3022)))
- rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info);
+ if (rt2x00_rf(rt2x00dev, RF2020) ||
+ rt2x00_rf(rt2x00dev, RF3020) ||
+ rt2x00_rf(rt2x00dev, RF3021) ||
+ rt2x00_rf(rt2x00dev, RF3022))
+ rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
else
- rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info);
+ rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);

/*
* Change BBP settings
--
1.7.0.4


2010-04-11 16:56:48

by Ivo Van Doorn

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

On Sunday 11 April 2010, Gertjan van Wingerde wrote:
> rt2x00 had preliminary support for RT3070 based devices, but the support was
> incomplete.
> Update the RT3070 register initialization to be similar to the latest Ralink
> vendor driver.
>
> With this patch my rt3070 based devices start showing a sign of life.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>

Acked-by: Ivo van Doorn <[email protected]>

2010-04-26 11:11:34

by Helmut Schaa

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

Am Montag 26 April 2010 schrieb Helmut Schaa:
> Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> > rt2x00 had preliminary support for RT3070 based devices, but the support was
> > incomplete.
> > Update the RT3070 register initialization to be similar to the latest Ralink
> > vendor driver.
> >
> > With this patch my rt3070 based devices start showing a sign of life.
>
> Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> more details.

Antonio, did that patch also break rx on your PCI device with rt2872?
If not this is only needed for SoC.

Thanks,
Helmut

> [...]
>
> > @@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > {
> > u8 rfcsr;
> > u8 bbp;
> > + u32 reg;
> > + u16 eeprom;
> >
> > - if (rt2x00_is_usb(rt2x00dev) &&
> > - !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
> > + if (!rt2x00_rt(rt2x00dev, RT3070))
> > return 0;
> >
> > - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > - if (!rt2x00_rf(rt2x00dev, RF3020) &&
> > - !rt2x00_rf(rt2x00dev, RF3021) &&
> > - !rt2x00_rf(rt2x00dev, RF3022))
> > - return 0;
> > - }
>
> Any reason why you've removed this part? The following code was executed on
> pci and soc devices when they had an 3020, 3021 or 3022 rf.
>
> > /*
> > * Init RF calibration.
> > */
> > @@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
> > rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
> >
> > - if (rt2x00_is_usb(rt2x00dev)) {
> > + if (rt2x00_rt(rt2x00dev, RT3070)) {
> > rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
> > rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > - rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
> > + rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
> > rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
> > rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > @@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
> > rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > - rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
> > rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
> > - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > - rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
> > - rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
> > - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
> > - rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
> > - rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > - rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > - rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > - rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
> > - rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
> > - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > - rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
> > - rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > - rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
> > - rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
> > - rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > - rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
> > - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
> > - rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
> > - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
> > - rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
> > - rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
> > - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > - rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
> > - rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
> > - rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
> > - rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > - rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
> > - rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
> > - rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
> > - rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
>
> This part is actually needed for getting rx to work on the SoC devices.
>
> Should I post a patch that adds this code again and is only executed on SoC
> devices with rf3020, 3021 and 3022?
>
> Thanks,
> Helmut
>


2010-04-11 16:55:44

by Ivo Van Doorn

[permalink] [raw]
Subject: Re: [PATCH 4/9] rt2x00: Refactor rt2800 version constants.

On Sunday 11 April 2010, Gertjan van Wingerde wrote:
> The rt2800 version constants are inconsistent, and the version number don't
> mean a lot of things anyway. Refactor the constants to have some more
> meaningful names, and introduce and use some new helpers to check these
> chipset revisions. At the same time rename to revision, as they are more
> revision numbers rather than version numbers.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>

Acked-by: Ivo van Doorn <[email protected]>


2010-04-10 20:52:25

by Gertjan van Wingerde

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

On 04/09/10 00:33, Ivo van Doorn wrote:
> On Thursday 08 April 2010, Gertjan van Wingerde wrote:
>> rt2x00 had preliminary support for RT3070 based devices, but the support was
>> incomplete.
>> Update the RT3070 register initialization to be similar to the latest Ralink
>> vendor driver.
>>
>> With this patch my rt3070 based devices start showing a sign of life.
>>
>> Signed-off-by: Gertjan van Wingerde <[email protected]>
>
>
>> @@ -1086,7 +1084,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
>> */
>> int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>> {
>> - u32 reg;
>> + u32 reg, reg2;
>> unsigned int i;
>>
>> rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
>> @@ -1204,11 +1202,18 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>> rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
>> rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
>>
>> - if (rt2x00_is_usb(rt2x00dev) &&
>> - rt2x00_rt(rt2x00dev, RT3070) && rt2x00_rev(rt2x00dev) == 0x0200) {
>> + if (rt2x00_rt(rt2x00dev, RT3070)) {
>> rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
>> - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
>> - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
>> +
>> + if (rt2x00_rev(rt2x00dev) < 0x0201) {
>> + reg = 0x00000000;
>> + reg2 = 0x0000002c;
>> + } else {
>> + reg = 0x00080606;
>> + reg2 = 0x00000000;
>> + }
>> + rt2800_register_write(rt2x00dev, TX_SW_CFG1, reg);
>> + rt2800_register_write(rt2x00dev, TX_SW_CFG2, reg2);
>
> Might as well put the rt2800_register_write call into the if, rather then storing
> it into variables first. That way it is consistent with the rest of the code.

OK.

>
>> @@ -1751,6 +1739,28 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>> rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
>> rt2800_bbp_write(rt2x00dev, 4, bbp);
>>
>> + if (rt2x00_rt(rt2x00dev, RT3070) && rt2x00_rev(rt2x00dev) < 0x0201)
>> + rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
>> +
>> + rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg);
>> + rt2x00_set_field32(&reg, OPT_14_CSR_BIT0, 1);
>> + rt2800_register_write(rt2x00dev, OPT_14_CSR, reg);
>> +
>> + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
>> + rt2x00_set_field8(&rfcsr, RFCSR17_R2, 0);
>> + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
>> + if ((eeprom & 0x07) >= 1)
>
> Might be nicer to do the access using rt2x00_get_field16,
> plus some name for this magical field in the header file.

OK. I'll do that. Note that the EEPROM field is used in multiple ways, possibly depending
on the chipset type. I'll add a comment stating that, so that it is explained why the
magical field for this EEPROM offset overlap.

>
>> + rt2x00_set_field8(&rfcsr, RFCSR17_R1, eeprom & 0x07);
>> + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
>> +
>> + if (rt2x00_rt(rt2x00dev, RT3070)) {
>> + rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr);
>> + rfcsr &= 0x77;
>> + if (rt2x00_rt(rt2x00dev, RT3070) && rt2x00_rev(rt2x00dev) < 0x0201)
>> + rfcsr |= 0x03;
>> + rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
>> + }
>
> Any ideas what these fields mean? Could set_field8 and _get_field8 simplify the code?

Again, no idea. I'll create some field names, like RFCSR27_R1, etc. This is aligned with
what was done for other unknown RF CSRs.

---
Gertjan.

2010-04-11 12:31:26

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 3/9] rt2x00: Align RT chipset definitions with vendor driver.

Only include definitions for RT chipsets that are also used inside the
Ralink vendor drivers.

Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800.h | 43 ++++++++++++++++++++++++++++--
drivers/net/wireless/rt2x00/rt2800lib.c | 22 +++++-----------
drivers/net/wireless/rt2x00/rt2x00.h | 7 ++---
3 files changed, 50 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 455dc3f..4d5871b 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1537,6 +1537,15 @@ struct mac_iveiv_entry {
*/

/*
+ * RFCSR 1:
+ */
+#define RFCSR1_RF_BLOCK_EN FIELD8(0x01)
+#define RFCSR1_RX0_PD FIELD8(0x04)
+#define RFCSR1_TX0_PD FIELD8(0x08)
+#define RFCSR1_RX1_PD FIELD8(0x10)
+#define RFCSR1_TX1_PD FIELD8(0x20)
+
+/*
* RFCSR 6:
*/
#define RFCSR6_R1 FIELD8(0x03)
@@ -1553,12 +1562,26 @@ struct mac_iveiv_entry {
#define RFCSR12_TX_POWER FIELD8(0x1f)

/*
+ * RFCSR 15:
+ */
+#define RFCSR15_TX_LO2_EN FIELD8(0x08)
+
+/*
* RFCSR 17:
*/
-#define RFCSR17_R1 FIELD8(0x07)
-#define RFCSR17_R2 FIELD8(0x08)
-#define RFCSR17_R3 FIELD8(0x20)
+#define RFCSR17_TXMIXER_GAIN FIELD8(0x07)
+#define RFCSR17_TX_LO1_EN FIELD8(0x08)
+#define RFCSR17_R FIELD8(0x20)

+/*
+ * RFCSR 20:
+ */
+#define RFCSR20_RX_LO1_EN FIELD8(0x08)
+
+/*
+ * RFCSR 21:
+ */
+#define RFCSR21_RX_LO2_EN FIELD8(0x08)

/*
* RFCSR 22:
@@ -1571,6 +1594,14 @@ struct mac_iveiv_entry {
#define RFCSR23_FREQ_OFFSET FIELD8(0x7f)

/*
+ * RFCSR 27:
+ */
+#define RFCSR27_R1 FIELD8(0x03)
+#define RFCSR27_R2 FIELD8(0x04)
+#define RFCSR27_R3 FIELD8(0x30)
+#define RFCSR27_R4 FIELD8(0x40)
+
+/*
* RFCSR 30:
*/
#define RFCSR30_RF_CALIBRATION FIELD8(0x80)
@@ -1710,6 +1741,12 @@ struct mac_iveiv_entry {
#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00)

/*
+ * EEPROM TXMIXER GAIN BG offset (note overlaps with EEPROM RSSI BG2).
+ */
+#define EEPROM_TXMIXER_GAIN_BG 0x0024
+#define EEPROM_TXMIXER_GAIN_BG_VAL FIELD16(0x0007)
+
+/*
* EEPROM RSSI A offset
*/
#define EEPROM_RSSI_A 0x0025
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 394c8e4..2ab8884 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1209,10 +1209,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
if ((rt2x00_rt(rt2x00dev, RT2872) &&
(rt2x00_rev(rt2x00dev) >= RT2880E_VERSION)) ||
- rt2x00_rt(rt2x00dev, RT2880) ||
rt2x00_rt(rt2x00dev, RT2883) ||
- rt2x00_rt(rt2x00dev, RT2890) ||
- rt2x00_rt(rt2x00dev, RT3052) ||
(rt2x00_rt(rt2x00dev, RT3070) &&
(rt2x00_rev(rt2x00dev) < RT3070_VERSION)))
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
@@ -1503,6 +1500,12 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
(rt2x00_rev(rt2x00dev) > RT2860D_VERSION))
rt2800_bbp_write(rt2x00dev, 84, 0x19);

+ if (rt2x00_rt(rt2x00dev, RT2872)) {
+ rt2800_bbp_write(rt2x00dev, 31, 0x08);
+ rt2800_bbp_write(rt2x00dev, 78, 0x0e);
+ rt2800_bbp_write(rt2x00dev, 80, 0x08);
+ }
+
if (rt2x00_is_usb(rt2x00dev) &&
rt2x00_rt(rt2x00dev, RT3070) &&
(rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
@@ -1511,12 +1514,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 105, 0x05);
}

- if (rt2x00_rt(rt2x00dev, RT3052)) {
- rt2800_bbp_write(rt2x00dev, 31, 0x08);
- rt2800_bbp_write(rt2x00dev, 78, 0x0e);
- rt2800_bbp_write(rt2x00dev, 80, 0x08);
- }
-
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);

@@ -1772,9 +1769,7 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
} else if (rt2x00_rt(rt2x00dev, RT2860) ||
rt2x00_rt(rt2x00dev, RT2870) ||
rt2x00_rt(rt2x00dev, RT2872) ||
- rt2x00_rt(rt2x00dev, RT2880) ||
- (rt2x00_rt(rt2x00dev, RT2883) &&
- (rt2x00_rev(rt2x00dev) < RT2883_VERSION))) {
+ rt2x00_rt(rt2x00dev, RT2872)) {
/*
* There is a max of 2 RX streams for RT28x0 series
*/
@@ -1879,10 +1874,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
if (!rt2x00_rt(rt2x00dev, RT2860) &&
!rt2x00_rt(rt2x00dev, RT2870) &&
!rt2x00_rt(rt2x00dev, RT2872) &&
- !rt2x00_rt(rt2x00dev, RT2880) &&
!rt2x00_rt(rt2x00dev, RT2883) &&
- !rt2x00_rt(rt2x00dev, RT2890) &&
- !rt2x00_rt(rt2x00dev, RT3052) &&
!rt2x00_rt(rt2x00dev, RT3070) &&
!rt2x00_rt(rt2x00dev, RT3071) &&
!rt2x00_rt(rt2x00dev, RT3090) &&
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index d9daa9c..16aa850 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -177,16 +177,15 @@ struct rt2x00_chip {
#define RT2573 0x2573
#define RT2860 0x2860 /* 2.4GHz PCI/CB */
#define RT2870 0x2870
-#define RT2872 0x2872
-#define RT2880 0x2880 /* WSOC */
+#define RT2872 0x2872 /* WSOC */
#define RT2883 0x2883 /* WSOC */
-#define RT2890 0x2890 /* 2.4GHz PCIe */
-#define RT3052 0x3052 /* WSOC */
#define RT3070 0x3070
#define RT3071 0x3071
#define RT3090 0x3090 /* 2.4GHz PCIe */
#define RT3390 0x3390
#define RT3572 0x3572
+#define RT3593 0x3593 /* PCIe */
+#define RT3883 0x3883 /* WSOC */

u16 rf;
u16 rev;
--
1.7.0.4


2010-04-08 22:17:09

by Ivo Van Doorn

[permalink] [raw]
Subject: Re: [PATCH 1/9] rt2x00: Let RF chipset decide the RF channel switch method to use in rt2800.

On Thursday 08 April 2010, Gertjan van Wingerde wrote:
> It seems that the distinction between RF channel switch method is solely based
> on the RF chipset that is used.
> Refactor the channel switch decision to just take the RF chipset into account,
> thereby greatly simplifying the check.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>

Acked-by: Ivo van Doorn <[email protected]>

2010-04-26 21:43:51

by Gertjan van Wingerde

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

On 04/26/10 21:59, Helmut Schaa wrote:
> Am Montag 26 April 2010 schrieb Gertjan van Wingerde:
>> On 04/26/10 13:02, Helmut Schaa wrote:
>>> Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:

<snip>

>>>
>>> This part is actually needed for getting rx to work on the SoC devices.
>>
>> Hmm, interesting, as I don't know where this code actually came from. It isn't needed for
>> PCI devices in general (at least not the PCI devices I've checked), so it may be specific to SoC.
>>
>>>
>>> Should I post a patch that adds this code again and is only executed on SoC
>>> devices with rf3020, 3021 and 3022?
>>>
>>
>> OK. I have just checked the two RT2872 based devices I have (one PCI one and one USB one),
>> and both of them act very strangely.
>
> Strangely ;) ? The SoC device was basically able to transmit frames but
> could't receive at all (at least that was my impression). Do you have a
> different issue?

Turns out I forgot to enable the PCIe one in my AP's ACL, so it simply was refused by the AP.
This card now works perfectly without your patch. Now, the difference is that my RT2872 is actually
accompanied by an RF2720 RF chipset, so there is a difference there.

>
>> I'll check against the Ralink SoC driver code that I've got as to how the initialization should actually
>> be.
>
> Ok.
>

The Ralink SoC driver code that I have follows exactly the procedure that was removed. So, I guess the original
code came from there, but it actually isn't needed for RT2860 devices. The Ralink code only runs this when an
RT2872 revision 0x0200 is accompanied with an RF3020, an RF3021 or an RF3022. For the benefit of correctness
I suggest we mimmick this in rt2x00, and only execute the sequence in those cases.
And, BTW, we can stop RF CSR initialization right after programming these static values. The Ralink driver doesn't
do anything else as well.
Finally, the Ralink driver has two more RF CSR writes in this sequence. It writes the value 0x00 to both RF CSR 30
and RF CSR 31. I suggest we add that to the sequence that will be added to rt2x00.

--
Gertjan.

2010-04-11 12:31:26

by Gertjan van Wingerde

[permalink] [raw]
Subject: [PATCH 8/9] rt2x00: Add rt3090 support in rt2800 register initialization.

Add RT3090 specific register initializations to rt2x00, based on the latest
Ralink rt3090 vendor driver.

Untested as I don't actually own an RT3090 based device, but given experiences
on rt3070/rt3071 very hopeful that this will actually work..

Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 54 +++++++++++++++++++++++--------
1 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index fe7171f..d746082 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1043,7 +1043,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
{
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
if (rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3071))
+ rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090))
return 0x1c + (2 * rt2x00dev->lna_gain);
else
return 0x2e + rt2x00dev->lna_gain;
@@ -1192,10 +1193,12 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);

- if (rt2x00_rt(rt2x00dev, RT3071)) {
+ if (rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
- if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) {
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
@@ -1558,7 +1561,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 70, 0x0a);

if (rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3071)) {
+ rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090)) {
rt2800_bbp_write(rt2x00dev, 79, 0x13);
rt2800_bbp_write(rt2x00dev, 80, 0x05);
rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -1580,7 +1584,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 92, 0x00);

if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
- rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E))
+ rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
+ rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E))
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
else
rt2800_bbp_write(rt2x00dev, 103, 0x00);
@@ -1588,7 +1593,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 105, 0x05);
rt2800_bbp_write(rt2x00dev, 106, 0x35);

- if (rt2x00_rt(rt2x00dev, RT3071)) {
+ if (rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090)) {
rt2800_bbp_read(rt2x00dev, 138, &value);

rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
@@ -1688,7 +1694,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
u16 eeprom;

if (!rt2x00_rt(rt2x00dev, RT3070) &&
- !rt2x00_rt(rt2x00dev, RT3071))
+ !rt2x00_rt(rt2x00dev, RT3071) &&
+ !rt2x00_rt(rt2x00dev, RT3090))
return 0;

/*
@@ -1702,7 +1709,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);

if (rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3071)) {
+ rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090)) {
rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
@@ -1729,7 +1737,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
- } else if (rt2x00_rt(rt2x00dev, RT3071)) {
+ } else if (rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090)) {
rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1);
rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
@@ -1738,7 +1747,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)

rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
- if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) {
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
@@ -1756,7 +1766,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
rt2x00dev->calibration[1] =
rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
- } else if (rt2x00_rt(rt2x00dev, RT3071)) {
+ } else if (rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090)) {
rt2x00dev->calibration[0] =
rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
rt2x00dev->calibration[1] =
@@ -1780,7 +1791,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 4, bbp);

if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
- rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E))
+ rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E))
rt2800_rfcsr_write(rt2x00dev, 27, 0x03);

rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg);
@@ -1789,7 +1801,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)

rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
- if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) {
+ if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
+ rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
@@ -1801,7 +1814,20 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
EEPROM_TXMIXER_GAIN_BG_VAL));
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);

- if (rt2x00_rt(rt2x00dev, RT3071)) {
+ if (rt2x00_rt(rt2x00dev, RT3090)) {
+ rt2800_bbp_read(rt2x00dev, 138, &bbp);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
+ rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
+ rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1);
+
+ rt2800_bbp_write(rt2x00dev, 138, bbp);
+ }
+
+ if (rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3090)) {
rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
--
1.7.0.4


2010-04-27 11:41:30

by Antonio Quartulli

[permalink] [raw]
Subject: Re: [PATCH 6/9] rt2x00: Finish rt3070 support in rt2800 register initialization.

On lun, apr 26, 2010 at 01:11:20 +0200, Helmut Schaa wrote:
> Am Montag 26 April 2010 schrieb Helmut Schaa:
> > Am Sonntag 11 April 2010 schrieb Gertjan van Wingerde:
> > > rt2x00 had preliminary support for RT3070 based devices, but the support was
> > > incomplete.
> > > Update the RT3070 register initialization to be similar to the latest Ralink
> > > vendor driver.
> > >
> > > With this patch my rt3070 based devices start showing a sign of life.
> >
> > Gertjan, this patch breaks rx on my 305x SoC device. See inline comments for
> > more details.
>
> Antonio, did that patch also break rx on your PCI device with rt2872?
> If not this is only needed for SoC.
Hi, I cloned the wireless-testing git a few minutes ago.
My card (rt2x00_set_chip: Info - Chipset detected - rt: 2872, rf: 0003,
rev: 0200) on miniPCI works correctly without any kind of problem.
No hangs at all.

Regards

>
> Thanks,
> Helmut
>
> > [...]
> >
> > > @@ -1643,18 +1653,12 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > > {
> > > u8 rfcsr;
> > > u8 bbp;
> > > + u32 reg;
> > > + u16 eeprom;
> > >
> > > - if (rt2x00_is_usb(rt2x00dev) &&
> > > - !rt2x00_rt_rev(rt2x00dev, RT3070, REV_RT3070E))
> > > + if (!rt2x00_rt(rt2x00dev, RT3070))
> > > return 0;
> > >
> > > - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > > - if (!rt2x00_rf(rt2x00dev, RF3020) &&
> > > - !rt2x00_rf(rt2x00dev, RF3021) &&
> > > - !rt2x00_rf(rt2x00dev, RF3022))
> > > - return 0;
> > > - }
> >
> > Any reason why you've removed this part? The following code was executed on
> > pci and soc devices when they had an 3020, 3021 or 3022 rf.
> >
> > > /*
> > > * Init RF calibration.
> > > */
> > > @@ -1665,13 +1669,13 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > > rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
> > > rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
> > >
> > > - if (rt2x00_is_usb(rt2x00dev)) {
> > > + if (rt2x00_rt(rt2x00dev, RT3070)) {
> > > rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > > rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > > rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > > rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
> > > rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > > - rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
> > > + rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
> > > rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > > rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
> > > rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > > @@ -1684,48 +1688,25 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
> > > rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > > rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
> > > rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > > - rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
> > > rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
> > > - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
> > > - rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
> > > - rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
> > > - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
> > > - rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
> > > - rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
> > > - rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
> > > - rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
> > > - rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
> > > - rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
> > > - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
> > > - rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
> > > - rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
> > > - rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
> > > - rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
> > > - rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
> > > - rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
> > > - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
> > > - rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
> > > - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
> > > - rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
> > > - rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
> > > - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
> > > - rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
> > > - rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
> > > - rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
> > > - rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
> > > - rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
> > > - rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
> > > - rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
> > > - rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
> >
> > This part is actually needed for getting rx to work on the SoC devices.
> >
> > Should I post a patch that adds this code again and is only executed on SoC
> > devices with rf3020, 3021 and 3022?
> >
> > Thanks,
> > Helmut
> >

--
Antonio Quartulli

Ognuno di noi, da solo, non vale nulla
Ernesto "Che" Guevara

2010-04-10 20:58:48

by Ivo Van Doorn

[permalink] [raw]
Subject: Re: [PATCH 5/9] rt2x00: Align rt2800 register initialization with vendor driver.

> >
> >> @@ -1214,38 +1243,61 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
> >> rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
> >> rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
> >>
> >> + rt2800_register_read(rt2x00dev, LED_CFG, &reg);
> >> + rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, 70);
> >> + rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, 30);
> >> + rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
> >> + rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
> >> + rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
> >> + rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
> >> + rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
> >> + rt2800_register_write(rt2x00dev, LED_CFG, reg);
> >
> > Same here.
>
> That's difficult. We have no other function simply manipulating the LED_CFG register.
> There is rt2800_blink_set, but that is working completely different.
> I'd prefer to leave this as is, instead of introducing another small helper.
>
> >
> >> rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
> >>
> >> + rt2800_register_read(rt2x00dev, TX_RTY_CFG, &reg);
> >> + rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
> >> + rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
> >> + rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
> >> + rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
> >> + rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
> >> + rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
> >> + rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
> >
> > And here.
>
> Same as for LED_CFG. Using rt2800_config_retry_limit would involve setting up a
> complete libconf structure. Seems like a bit of overkill for the purpose.

Ok, we could fix this later because it might not even be required to do this initialization here,
it isn't needed for the other (older) chipsets either. But until the rt2800 drivers have problems
we should stick as close as possible to the original driver. :)

> >> + if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
> >> + rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 1);
> >> + else if (rt2x00_is_usb(rt2x00dev))
> >> + rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
> >
> > perhaps:
> > rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, !rt2x00_is_usb(rt2x00dev));
>
> Hmm, could be. Not too fond of that construction though. I think the somewhat more verbose
> variant I had is clearer and easier to understand what is going on.

Of, but the if-else-if can be replaced with if-else, unless you expect a 4th platform ;)

> >> @@ -1323,6 +1382,15 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
> >> rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
> >>
> >> rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
> >> +
> >> + rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
> >> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, 32);
> >> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, 32);
> >> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
> >> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, 314);
> >> + rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
> >> + rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
> >
> > Not really fond of the magical values written to the device, while mac80211
> > sends us the proper values later. This is probably a register initialization ordering issue?
>
> These magical values come straight from the Ralink vendor driver. As you know that code isn't
> the best documented code we've seen, so I don't know what these magical values actually represent.
> They are just initialization values for the time until we get associated.
>
> For code clarity in comparison to the Ralink vendor driver I prefer to leave these in.

Ok.

Ivo