mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ho Jie Feng <hjf3108@gmail.com>
To: linux-wireless@vger.kernel.org
Cc: Ho Jie Feng <hjf3108@gmail.com>, Stanislaw Gruszka <stf_xl@wp.pl>,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH wireless] wifi: rt2x00: retry RF3053 VCO calibration with higher bias
Date: Mon, 26 Oct 2026 00:11:40 +0800	[thread overview]
Message-ID: <20261025161140.66990-1-hjf3108@gmail.com> (raw)

VCO calibration with the default RF3053 VCO IC can cause
RFCSR 4, the result register to saturate at 0x7f on 2.4 GHz,
leaving lower channels unusable.

When calibration fails, retry the calibration with a higher VCO_IC
for RT3593. This should allow existing devices to work as before,
while allowing devices with the VCO calibration failure to work
successfully.

Hardware: Netgear WNDA4100 (USB 0846:9013, RT3593 rev 0402, RF3053)

Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
---
 .../net/wireless/ralink/rt2x00/rt2800lib.c    | 66 ++++++++++++-------
 1 file changed, 44 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 2e2e382b62475..68755e388fd59 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -2794,6 +2794,44 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 	rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 }
 
+static void rt2800_set_vco_ic_rf3053(struct rt2x00_dev *rt2x00dev,
+				     struct rf_channel *rf,
+				     unsigned int attempt)
+{
+	u8 rfcsr;
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 6);
+	if (rf->channel >= 1 && rf->channel <= 14)
+		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1 + attempt);
+	else if (rf->channel >= 36 && rf->channel <= 64)
+		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
+	else if (rf->channel >= 100 && rf->channel <= 128)
+		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
+	else
+		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
+	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+}
+
+static void rt2800_vco_calibrate_rf3053(struct rt2x00_dev *rt2x00dev,
+					struct rf_channel *rf)
+{
+	u8 rfcsr;
+
+	/* Initiate VCO calibration */
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 3);
+	if (rf->channel <= 14) {
+		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+	} else {
+		rt2x00_set_field8(&rfcsr, RFCSR3_BIT1, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR3_BIT2, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR3_BIT3, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR3_BIT4, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR3_BIT5, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+	}
+	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
+}
+
 static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 					 struct ieee80211_conf *conf,
 					 struct rf_channel *rf,
@@ -2977,16 +3015,7 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 		rfcsr = 0x12;
 	rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
 
-	rfcsr = rt2800_rfcsr_read(rt2x00dev, 6);
-	if (rf->channel >= 1 && rf->channel <= 14)
-		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
-	else if (rf->channel >= 36 && rf->channel <= 64)
-		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
-	else if (rf->channel >= 100 && rf->channel <= 128)
-		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
-	else
-		rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
-	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+	rt2800_set_vco_ic_rf3053(rt2x00dev, rf, 0);
 
 	rfcsr = rt2800_rfcsr_read(rt2x00dev, 30);
 	rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
@@ -3046,19 +3075,12 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 		rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
 	}
 
-	/* Initiate VCO calibration */
-	rfcsr = rt2800_rfcsr_read(rt2x00dev, 3);
-	if (rf->channel <= 14) {
-		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
-	} else {
-		rt2x00_set_field8(&rfcsr, RFCSR3_BIT1, 1);
-		rt2x00_set_field8(&rfcsr, RFCSR3_BIT2, 1);
-		rt2x00_set_field8(&rfcsr, RFCSR3_BIT3, 1);
-		rt2x00_set_field8(&rfcsr, RFCSR3_BIT4, 1);
-		rt2x00_set_field8(&rfcsr, RFCSR3_BIT5, 1);
-		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+	rt2800_vco_calibrate_rf3053(rt2x00dev, rf);
+	usleep_range(1000, 2000);
+	if (rt2800_rfcsr_read(rt2x00dev, 4) == 0x7f) {
+		rt2800_set_vco_ic_rf3053(rt2x00dev, rf, 1);
+		rt2800_vco_calibrate_rf3053(rt2x00dev, rf);
 	}
-	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
 
 	if (rf->channel >= 1 && rf->channel <= 14) {
 		rfcsr = 0x23;

base-commit: 9d8ec0b5b5295bd23d979d1b2b905de25c36fff2
-- 
2.55.0


                 reply	other threads:[~2026-10-25 16:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261025161140.66990-1-hjf3108@gmail.com \
    --to=hjf3108@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=stf_xl@wp.pl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®