2013-08-17 12:09:39

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH v2 0/6] rt2x00: rt2800lib: frequency offset adjustment fixes

The patch-set contain small fixes for the frequency adjustment
code of the rt2800 driver.

Gabor Juhos (6):
rt2x00: rt2800lib: fix frequency offset boundary calculation
rt2x00: rt2800lib: optimize frequency offset adjustment
rt2x00: rt2800lib: use a MCU command for frequency adjustment on USB
devices
rt2x00: rt2800lib: use step-by-step frequency offset adjustment on
MMIO devices
rt2x00: rt2800lib: move rt2800_adjust_freq_offset function
rt2x00: rt2800lib: adjust frequency offset for RF3053

drivers/net/wireless/rt2x00/rt2800.h | 1 +
drivers/net/wireless/rt2x00/rt2800lib.c | 52 ++++++++++++++++++++++---------
2 files changed, 39 insertions(+), 14 deletions(-)

--
1.7.10


2013-08-17 12:09:42

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH v2 3/6] rt2x00: rt2800lib: use a MCU command for frequency adjustment on USB devices

According to the Ralink driver, there is an MCU
command which can be used to send the frequency
offset value directly to the USB device without
going through the RFCSR writing sequence.

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
RTMPAdjustFrequencyOffset function in common/rt_rf.c

Signed-off-by: Gabor Juhos <[email protected]>
---
Changes since v1:
- add a MCU_FREQ_OFFSET constant and use that instead
of a hardcoded number
---
drivers/net/wireless/rt2x00/rt2800.h | 1 +
drivers/net/wireless/rt2x00/rt2800lib.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 6e69b96..e25e5bf 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2794,6 +2794,7 @@ enum rt2800_eeprom_word {
#define MCU_RADAR 0x60
#define MCU_BOOT_SIGNAL 0x72
#define MCU_ANT_SELECT 0X73
+#define MCU_FREQ_OFFSET 0x74
#define MCU_BBP_SIGNAL 0x80
#define MCU_POWER_SAVE 0x83
#define MCU_BAND_SELECT 0x91
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 3407ac9..bebc56f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2509,7 +2509,11 @@ static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
if (rfcsr == prev_rfcsr)
return;

- rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+ if (rt2x00_is_usb(rt2x00dev))
+ rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
+ freq_offset, prev_rfcsr);
+ else
+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
}

static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
--
1.7.10

2013-08-17 12:09:40

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH v2 2/6] rt2x00: rt2800lib: optimize frequency offset adjustment

Don't write the new value into the register if it is
the same as the old value to avoid unncessary USB bus
traffic with USB devices. The change also saves a few
cycle on MMIO based devices.

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
RTMPAdjustFrequencyOffset function in common/rt_rf.c

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

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index de27277..3407ac9 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2497,13 +2497,18 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
{
u8 freq_offset;
- u8 rfcsr;
+ u8 rfcsr, prev_rfcsr;

freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);

rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+ prev_rfcsr = rfcsr;
+
rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
+ if (rfcsr == prev_rfcsr)
+ return;
+
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
}

--
1.7.10

2013-08-17 12:09:45

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH v2 6/6] rt2x00: rt2800lib: adjust frequency offset for RF3053

Along with other chipsets, the Ralink driver uses the
frequency adjustment code for RF3053 as well. Remove
the bogus place-holder comment from the RF3053 specific
channel configuration function and call the frequency
adjustment function instead

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
RT3593_ChipSwitchChannel function in chips/rt3593.c

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

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 1b81fc9..aa6b6b0 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2360,7 +2360,7 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
}
rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);

- /* TODO: frequency calibration? */
+ rt2800_adjust_freq_offset(rt2x00dev);

if (conf_is_ht40(conf)) {
txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
--
1.7.10

2013-08-17 12:09:43

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH v2 4/6] rt2x00: rt2800lib: use step-by-step frequency offset adjustment on MMIO devices

According to the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver, the RFCSR17 register can't be programmed in
one step on devices which are using the frequency
offset adjustment code.

Update the code to use step-by-step adjustment.

Reference:
RT30xxWriteRFRegister function in common/rt_rf.c

Signed-off-by: Gabor Juhos <[email protected]>
---
Changes since v1:
- new patch
---
drivers/net/wireless/rt2x00/rt2800lib.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index bebc56f..623ad9d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2496,7 +2496,7 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,

static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
{
- u8 freq_offset;
+ u8 freq_offset, prev_freq_offset;
u8 rfcsr, prev_rfcsr;

freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
@@ -2509,11 +2509,24 @@ static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
if (rfcsr == prev_rfcsr)
return;

- if (rt2x00_is_usb(rt2x00dev))
+ if (rt2x00_is_usb(rt2x00dev)) {
rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
freq_offset, prev_rfcsr);
- else
+ return;
+ }
+
+ prev_freq_offset = rt2x00_get_field8(prev_rfcsr, RFCSR17_CODE);
+ while (prev_freq_offset != freq_offset) {
+ if (prev_freq_offset < freq_offset)
+ prev_freq_offset++;
+ else
+ prev_freq_offset--;
+
+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, prev_freq_offset);
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+
+ usleep_range(1000, 1500);
+ }
}

static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
--
1.7.10

2013-08-17 12:09:40

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH v2 1/6] rt2x00: rt2800lib: fix frequency offset boundary calculation

The current code in the 'rt2800_adjust_freq_offset'
function limits the device specific frequency offset
value to FREQ_BOUND but ignores the fact that the
uppermost bit is not part of the frequency offset
value. As the result, the driver always uses the
FREQ_BOUND value if the uppermost bit is set.

Update the code to use the correct source value
for calculating the boundary.

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
RTMPAdjustFrequencyOffset function in common/rt_rf.c

Signed-off-by: Gabor Juhos <[email protected]>
---
Changes since v1: ---
---
drivers/net/wireless/rt2x00/rt2800lib.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 2f64034..de27277 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2496,13 +2496,14 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,

static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
{
+ u8 freq_offset;
u8 rfcsr;

+ freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
+ freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
+
rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
- if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
- rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
- else
- rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
}

--
1.7.10

2013-08-17 12:09:44

by Gabor Juhos

[permalink] [raw]
Subject: [PATCH v2 5/6] rt2x00: rt2800lib: move rt2800_adjust_freq_offset function

Move the rt2800_adjust_freq_offset function before
the channel configuration functions to make it usable
from those without a forward declaration.

The patch contains no functional changes.

Signed-off-by: Gabor Juhos <[email protected]>
---
Changes since v1: ---
---
drivers/net/wireless/rt2x00/rt2800lib.c | 73 ++++++++++++++++---------------
1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 623ad9d..1b81fc9 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1875,6 +1875,43 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
rt2x00dev->lna_gain = lna_gain;
}

+#define FREQ_OFFSET_BOUND 0x5f
+
+static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
+{
+ u8 freq_offset, prev_freq_offset;
+ u8 rfcsr, prev_rfcsr;
+
+ freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
+ freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
+
+ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+ prev_rfcsr = rfcsr;
+
+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
+ if (rfcsr == prev_rfcsr)
+ return;
+
+ if (rt2x00_is_usb(rt2x00dev)) {
+ rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
+ freq_offset, prev_rfcsr);
+ return;
+ }
+
+ prev_freq_offset = rt2x00_get_field8(prev_rfcsr, RFCSR17_CODE);
+ while (prev_freq_offset != freq_offset) {
+ if (prev_freq_offset < freq_offset)
+ prev_freq_offset++;
+ else
+ prev_freq_offset--;
+
+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, prev_freq_offset);
+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+
+ usleep_range(1000, 1500);
+ }
+}
+
static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,
@@ -2492,42 +2529,6 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,

#define POWER_BOUND 0x27
#define POWER_BOUND_5G 0x2b
-#define FREQ_OFFSET_BOUND 0x5f
-
-static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
-{
- u8 freq_offset, prev_freq_offset;
- u8 rfcsr, prev_rfcsr;
-
- freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
- freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
-
- rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
- prev_rfcsr = rfcsr;
-
- rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
- if (rfcsr == prev_rfcsr)
- return;
-
- if (rt2x00_is_usb(rt2x00dev)) {
- rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
- freq_offset, prev_rfcsr);
- return;
- }
-
- prev_freq_offset = rt2x00_get_field8(prev_rfcsr, RFCSR17_CODE);
- while (prev_freq_offset != freq_offset) {
- if (prev_freq_offset < freq_offset)
- prev_freq_offset++;
- else
- prev_freq_offset--;
-
- rt2x00_set_field8(&rfcsr, RFCSR17_CODE, prev_freq_offset);
- rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
-
- usleep_range(1000, 1500);
- }
-}

static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
--
1.7.10