All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ivo van Doorn <ivdoorn@gmail.com>
To: netdev@vger.kernel.org
Cc: rt2x00-devel@lfcorreia.dyndns.org
Subject: [PATCH 13/32] rt2x00: Tune link depending on link quality
Date: Fri, 28 Apr 2006 00:03:04 +0200	[thread overview]
Message-ID: <200604280003.05170.IvDoorn@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 7739 bytes --]

From: Ivo van Doorn <IvDoorn@gmail.com>

Add link tuning capabilities, and call this function
every time the rxdone handler has finished.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>

diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
--- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c	2006-04-27 21:42:29.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c	2006-04-27 21:45:08.000000000 +0200
@@ -618,6 +618,41 @@ rt2400pci_config_rate(struct rt2x00_pci 
 }
 
 /*
+ * Link tuning
+ */
+static void
+rt2400pci_link_tuner(struct rt2x00_pci *rt2x00pci)
+{
+	u8			reg;
+	char			false_cca_delta;
+
+	/*
+	 * Read false CCA counter.
+	 */
+	rt2x00_bbp_read(rt2x00pci, 39, &reg);
+
+	/*
+	 * Determine difference with previous CCA counter.
+	 */
+	false_cca_delta = reg - rt2x00pci->false_cca;
+	rt2x00pci->false_cca = reg;
+
+	/*
+	 * Check if the difference is higher than the
+	 * threshold and if so, tune the link.
+	 */
+	if (false_cca_delta >= 8) {
+		/*
+		 * Read and update RX AGC VGC.
+		 */
+		rt2x00_bbp_read(rt2x00pci, 13, &reg);
+		reg += 2;
+		if (reg < 0x20)
+			rt2x00_bbp_write(rt2x00pci, 13, reg);
+	}
+}
+
+/*
  * TX descriptor initialization
  */
 static void
@@ -779,6 +814,9 @@ rt2400pci_rxdone(void *data)
 
 			memcpy(skb_put(skb, size), entry->data_addr, size);
 
+			ring->params.rx.ssi =
+				rt2x00_get_field32(rxd->word2, RXD_W2_RSSI);
+
 			__ieee80211_rx(net_dev, skb, &ring->params.rx);
 		}
 
@@ -786,6 +824,11 @@ rt2400pci_rxdone(void *data)
 
 		rt2x00_ring_index_inc(&rt2x00pci->rx);
 	}
+
+	/*
+	 * Tune link for optimal performance.
+	 */
+	rt2400pci_link_tuner(rt2x00pci);
 }
 
 static void
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h
--- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h	2006-04-27 21:36:19.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h	2006-04-27 21:45:08.000000000 +0200
@@ -926,6 +926,11 @@ struct rt2x00_pci{
 	struct workqueue_struct		*workqueue;
 
 	/*
+	 * False CCA count.
+	 */
+	int					false_cca;
+
+	/*
 	 * EEPROM bus width.
 	 */
 	u8					eeprom_width;
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
--- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c	2006-04-27 21:42:29.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c	2006-04-27 21:45:08.000000000 +0200
@@ -661,6 +661,51 @@ rt2500pci_config_rate(struct rt2x00_pci 
 }
 
 /*
+ * Link tuning
+ */
+static void
+rt2500pci_link_tuner(struct rt2x00_pci *rt2x00pci, char rssi)
+{
+	u32			reg;
+	u8			reg_r17;
+
+	/*
+	 * Don't perform any tuning during scan.
+	 */
+	if (rt2x00pci->scan)
+		return;
+
+	rt2x00_register_read(rt2x00pci, CSR0, &reg);
+	rt2x00_bbp_read(rt2x00pci, 17, &reg_r17);
+
+	if (reg < RT2560_VERSION_D)
+		goto dynamic_cca_tune;
+
+	if (rssi < 40) {
+		if (reg_r17 >= 0x41)
+			rt2x00_bbp_write(rt2x00pci, 17, reg_r17);
+		return;
+	} else if (rssi >= 62) {
+		if (reg_r17 != 0x50)
+			rt2x00_bbp_write(rt2x00pci, 17, 0x50);
+		return;
+	} else if (reg_r17 >= 0x41) {
+		rt2x00_bbp_write(rt2x00pci, 17, reg_r17);
+		return;
+	}
+
+dynamic_cca_tune:
+	rt2x00_register_read(rt2x00pci, CNT3, &reg);
+
+	reg = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
+
+	if (reg > 512 && reg_r17 < 0x40)
+		rt2x00_bbp_write(rt2x00pci, 17, ++reg_r17);
+	else if (reg < 100 && reg_r17 > 0x32)
+		rt2x00_bbp_write(rt2x00pci, 17, --reg_r17);
+}
+
+/*
  * TX descriptor initialization
  */
 static void
@@ -819,6 +864,14 @@ rt2500pci_rxdone(void *data)
 	struct sk_buff		*skb;
 	struct rxd		*rxd;
 	u16			size;
+	u8			rssi_count;
+	char			total_rssi;
+
+	/*
+	 * Initialize variable for average RSSI calculation.
+	 */
+	rssi_count = 0;
+	total_rssi = 0;
 
 	while (1) {
 		entry = rt2x00_get_data_entry(ring);
@@ -843,12 +896,24 @@ rt2500pci_rxdone(void *data)
 
 			memcpy(skb_put(skb, size), entry->data_addr, size);
 
+			ring->params.rx.ssi =
+				rt2x00_get_field32(rxd->word2, RXD_W2_RSSI);
+
 			__ieee80211_rx(net_dev, skb, &ring->params.rx);
+
+			rssi_count++;
+			total_rssi += ring->params.rx.ssi;
 		}
 		rt2x00_set_field32(&rxd->word0, RXD_W0_OWNER_NIC, 1);
 
 		rt2x00_ring_index_inc(&rt2x00pci->rx);
 	}
+
+	/*
+	 * Tune link for optimal performance.
+	 */
+	if (total_rssi && rssi_count)
+		rt2500pci_link_tuner(rt2x00pci, total_rssi / rssi_count);
 }
 
 static void
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
--- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c	2006-04-27 21:44:33.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c	2006-04-27 21:45:08.000000000 +0200
@@ -485,6 +485,68 @@ rt2500usb_config_rate(struct rt2x00_usb 
 }
 
 /*
+ * Link tuning
+ */
+static void
+rt2500usb_link_tuner(struct rt2x00_usb *rt2x00usb, char rssi)
+{
+	u16			reg;
+	u8			reg_r17;
+	u8			up_bound;
+	u8			low_bound;
+
+	/*
+	 * Don't perform any tuning during scan.
+	 */
+	if (rt2x00usb->scan)
+		return;
+
+	low_bound = 0x32;
+	if (rssi >= 43)
+		up_bound = 0x40;
+	else
+		up_bound = 0x40 - (43 - rssi);
+	if (up_bound < low_bound)
+		up_bound = low_bound;
+
+	if (rssi > 75) {
+		rt2x00_bbp_write(rt2x00usb, 24, 0x70);
+		rt2x00_bbp_write(rt2x00usb, 25, 0x40);
+		rt2x00_bbp_write(rt2x00usb, 61, 0x6d);
+	} else {
+		rt2x00_bbp_write(rt2x00usb, 24, 0x80);
+		rt2x00_bbp_write(rt2x00usb, 25, 0x50);
+		rt2x00_bbp_write(rt2x00usb, 61, 0x60);
+	}
+
+	rt2x00_bbp_read(rt2x00usb, 17, &reg_r17);
+
+	if (rssi > 80) {
+		if (reg_r17 != 0x60)
+			rt2x00_bbp_write(rt2x00usb, 17, 0x60);
+		return;
+	} else if (rssi >= 62) {
+		if (reg_r17 != 0x48)
+			rt2x00_bbp_write(rt2x00usb, 17, 0x48);
+		return;
+	} else if (rssi >= 46) {
+		if (reg_r17 != 0x41)
+			rt2x00_bbp_write(rt2x00usb, 17, 0x41);
+		return;
+	} else if (reg_r17 > up_bound) {
+		rt2x00_bbp_write(rt2x00usb, 17, up_bound);
+		return;
+	}
+
+	rt2x00_register_read(rt2x00usb, STA_CSR3, &reg);
+
+	if (reg > 512 && reg_r17 < up_bound)
+		rt2x00_bbp_write(rt2x00usb, 17, ++reg_r17);
+	else if (reg < 100 && reg_r17 > low_bound)
+		rt2x00_bbp_write(rt2x00usb, 17, --reg_r17);
+}
+
+/*
  * TX descriptor initialization
  */
 static void
@@ -636,6 +698,14 @@ rt2500usb_rxdone(void *data)
 	struct sk_buff		*skb;
 	struct rxd		*rxd;
 	u16			size;
+	u8			rssi_count;
+	char			total_rssi;
+
+	/*
+	 * Initialize variable for average RSSI calculation.
+	 */
+	rssi_count = 0;
+	total_rssi = 0;
 
 	while (1) {
 		entry = rt2x00_get_data_entry(ring);
@@ -670,13 +740,25 @@ rt2500usb_rxdone(void *data)
 
 			memcpy(skb_put(skb, size), entry->data_addr, size);
 
+			ring->params.rx.ssi =
+				rt2x00_get_field32(rxd->word1, RXD_W1_RSSI);
+
 			__ieee80211_rx(net_dev, skb, &ring->params.rx);
+
+			rssi_count++;
+			total_rssi += ring->params.rx.ssi;
 		}
 
 		usb_submit_urb(entry->urb, GFP_ATOMIC);
 
 		rt2x00_ring_index_inc(ring);
 	}
+
+	/*
+	 * Tune link for optimal performance.
+	 */
+	if (total_rssi && rssi_count)
+		rt2500usb_link_tuner(rt2x00usb, total_rssi / rssi_count);
 }
 
 static void

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

                 reply	other threads:[~2006-04-27 22:02 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=200604280003.05170.IvDoorn@gmail.com \
    --to=ivdoorn@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=rt2x00-devel@lfcorreia.dyndns.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.