From: Ivo van Doorn <ivdoorn@gmail.com>
To: John Linville <linville@tuxdriver.com>
Cc: "linux-wireless" <linux-wireless@vger.kernel.org>,
rt2400-devel@lists.sourceforge.net
Subject: [PATCH 3/15] rt2x00: Reduce calls to bbp_read()
Date: Sat, 20 Dec 2008 10:54:22 +0100 [thread overview]
Message-ID: <200812201054.22904.IvDoorn@gmail.com> (raw)
In-Reply-To: <200812201053.29348.IvDoorn@gmail.com>
The link_tuner() function will always call bbp_read()
at the start of the function. Because this is an
indirect register access has some costs attached
to it (especially for USB hardware).
We already store the value read from the register
into the vgc_level value inside the link structure.
Instead of reading from the register we can read that
field directly and base the tuner on that value.
This reduces the time the registers are locked with
the csr_mutex and speeds up the link_tuner processing.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 27 ++++++++--------
drivers/net/wireless/rt2x00/rt2500pci.c | 50 +++++++++++++++---------------
drivers/net/wireless/rt2x00/rt2x00.h | 9 ++++-
drivers/net/wireless/rt2x00/rt61pci.c | 49 +++++++++++++----------------
drivers/net/wireless/rt2x00/rt73usb.c | 52 ++++++++++++++----------------
5 files changed, 92 insertions(+), 95 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 031cb0a..a186e4b 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -600,35 +600,36 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = bbp;
}
+static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
+ rt2x00dev->link.vgc_level = vgc_level;
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+}
+
static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt2400pci_bbp_write(rt2x00dev, 13, 0x08);
- rt2x00dev->link.vgc_level = 0x08;
+ rt2400pci_set_vgc(rt2x00dev, 0x08);
}
static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- u8 reg;
+ struct link *link = &rt2x00dev->link;
/*
* The link tuner should not run longer then 60 seconds,
* and should run once every 2 seconds.
*/
- if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1))
+ if (link->count > 60 || !(link->count & 1))
return;
/*
* Base r13 link tuning on the false cca count.
*/
- rt2400pci_bbp_read(rt2x00dev, 13, ®);
-
- if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
- rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
- rt2x00dev->link.vgc_level = reg;
- } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
- rt2400pci_bbp_write(rt2x00dev, 13, --reg);
- rt2x00dev->link.vgc_level = reg;
- }
+ if ((link->qual.false_cca > 512) && (link->vgc_level < 0x20))
+ rt2400pci_set_vgc(rt2x00dev, ++link->vgc_level);
+ else if ((link->qual.false_cca < 100) && (link->vgc_level > 0x08))
+ rt2400pci_set_vgc(rt2x00dev, --link->vgc_level);
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 780c96b..dd1f2c0 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -639,16 +639,23 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
}
+static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ if (rt2x00dev->link.vgc_level_reg != vgc_level) {
+ rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+ }
+}
+
static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt2500pci_bbp_write(rt2x00dev, 17, 0x48);
- rt2x00dev->link.vgc_level = 0x48;
+ rt2500pci_set_vgc(rt2x00dev, 0x48);
}
static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ struct link *link = &rt2x00dev->link;
+ int rssi = rt2x00_get_link_rssi(link);
/*
* To prevent collisions with MAC ASIC on chipsets
@@ -656,12 +663,9 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* seconds while being associated.
*/
if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
- rt2x00dev->intf_associated &&
- rt2x00dev->link.count > 20)
+ rt2x00dev->intf_associated && link->count > 20)
return;
- rt2500pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Chipset versions C and lower should directly continue
* to the dynamic CCA tuning. Chipset version D and higher
@@ -677,11 +681,9 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* then corrupt the R17 tuning. To remidy this the tuning should
* be stopped (While making sure the R17 value will not exceed limits)
*/
- if (rssi < -80 && rt2x00dev->link.count > 20) {
- if (r17 >= 0x41) {
- r17 = rt2x00dev->link.vgc_level;
- rt2500pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if (rssi < -80 && link->count > 20) {
+ if (link->vgc_level_reg >= 0x41)
+ rt2500pci_set_vgc(rt2x00dev, link->vgc_level);
return;
}
@@ -689,8 +691,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special big-R17 for short distance
*/
if (rssi >= -58) {
- if (r17 != 0x50)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x50);
+ rt2500pci_set_vgc(rt2x00dev, 0x50);
return;
}
@@ -698,8 +699,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special mid-R17 for middle distance
*/
if (rssi >= -74) {
- if (r17 != 0x41)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x41);
+ rt2500pci_set_vgc(rt2x00dev, 0x41);
return;
}
@@ -707,8 +707,8 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Leave short or middle distance condition, restore r17
* to the dynamic tuning range.
*/
- if (r17 >= 0x41) {
- rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level);
+ if (link->vgc_level_reg >= 0x41) {
+ rt2500pci_set_vgc(rt2x00dev, link->vgc_level);
return;
}
@@ -718,12 +718,12 @@ dynamic_cca_tune:
* R17 is inside the dynamic tuning range,
* start tuning the link based on the false cca counter.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
- rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
- rt2x00dev->link.vgc_level = r17;
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
- rt2500pci_bbp_write(rt2x00dev, 17, --r17);
- rt2x00dev->link.vgc_level = r17;
+ if (link->qual.false_cca > 512 && link->vgc_level_reg < 0x40) {
+ rt2500pci_set_vgc(rt2x00dev, ++link->vgc_level_reg);
+ link->vgc_level = link->vgc_level_reg;
+ } else if (link->qual.false_cca < 100 && link->vgc_level_reg > 0x32) {
+ rt2500pci_set_vgc(rt2x00dev, --link->vgc_level_reg);
+ link->vgc_level = link->vgc_level_reg;
}
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 19c0687..8935f2c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -286,9 +286,14 @@ struct link {
struct link_ant ant;
/*
- * Active VGC level
+ * Active VGC level (for false cca tuning)
*/
- int vgc_level;
+ u8 vgc_level;
+
+ /*
+ * VGC level as configured in register
+ */
+ u8 vgc_level_reg;
/*
* Work structure for scheduling periodic link tuning.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 3f91a6e..abd7b43 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1046,21 +1046,27 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
+static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ if (rt2x00dev->link.vgc_level != vgc_level) {
+ rt61pci_bbp_write(rt2x00dev, 17, vgc_level);
+ rt2x00dev->link.vgc_level = vgc_level;
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+ }
+}
+
static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt61pci_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ rt61pci_set_vgc(rt2x00dev, 0x20);
}
static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ struct link *link = &rt2x00dev->link;
+ int rssi = rt2x00_get_link_rssi(link);
u8 up_bound;
u8 low_bound;
- rt61pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
@@ -1091,8 +1097,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special big-R17 for very short distance
*/
if (rssi >= -35) {
- if (r17 != 0x60)
- rt61pci_bbp_write(rt2x00dev, 17, 0x60);
+ rt61pci_set_vgc(rt2x00dev, 0x60);
return;
}
@@ -1100,8 +1105,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special big-R17 for short distance
*/
if (rssi >= -58) {
- if (r17 != up_bound)
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ rt61pci_set_vgc(rt2x00dev, up_bound);
return;
}
@@ -1109,9 +1113,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special big-R17 for middle-short distance
*/
if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ rt61pci_set_vgc(rt2x00dev, low_bound + 0x10);
return;
}
@@ -1119,9 +1121,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special mid-R17 for middle distance
*/
if (rssi >= -74) {
- low_bound += 0x08;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ rt61pci_set_vgc(rt2x00dev, low_bound + 0x08);
return;
}
@@ -1133,8 +1133,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ if (link->vgc_level > up_bound) {
+ rt61pci_set_vgc(rt2x00dev, up_bound);
return;
}
@@ -1144,15 +1144,10 @@ dynamic_cca_tune:
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- if (++r17 > up_bound)
- r17 = up_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- if (--r17 < low_bound)
- r17 = low_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
+ rt61pci_set_vgc(rt2x00dev, ++link->vgc_level);
+ else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
+ rt61pci_set_vgc(rt2x00dev, --link->vgc_level);
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 8a365c9..49fd42a 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -924,21 +924,27 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
+static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ if (rt2x00dev->link.vgc_level != vgc_level) {
+ rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
+ rt2x00dev->link.vgc_level = vgc_level;
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+ }
+}
+
static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt73usb_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ rt73usb_set_vgc(rt2x00dev, 0x20);
}
static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ struct link *link = &rt2x00dev->link;
+ int rssi = rt2x00_get_link_rssi(link);
u8 up_bound;
u8 low_bound;
- rt73usb_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
@@ -979,8 +985,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special big-R17 for very short distance
*/
if (rssi > -35) {
- if (r17 != 0x60)
- rt73usb_bbp_write(rt2x00dev, 17, 0x60);
+ rt73usb_set_vgc(rt2x00dev, 0x60);
return;
}
@@ -988,8 +993,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special big-R17 for short distance
*/
if (rssi >= -58) {
- if (r17 != up_bound)
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ rt73usb_set_vgc(rt2x00dev, up_bound);
return;
}
@@ -997,9 +1001,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special big-R17 for middle-short distance
*/
if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt73usb_bbp_write(rt2x00dev, 17, low_bound);
+ rt73usb_set_vgc(rt2x00dev, low_bound + 0x10);
return;
}
@@ -1007,8 +1009,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special mid-R17 for middle distance
*/
if (rssi >= -74) {
- if (r17 != (low_bound + 0x10))
- rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08);
+ rt73usb_set_vgc(rt2x00dev, low_bound + 0x08);
return;
}
@@ -1020,8 +1021,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ if (link->vgc_level > up_bound) {
+ rt73usb_set_vgc(rt2x00dev, up_bound);
return;
}
@@ -1031,17 +1032,12 @@ dynamic_cca_tune:
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- r17 += 4;
- if (r17 > up_bound)
- r17 = up_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- r17 -= 4;
- if (r17 < low_bound)
- r17 = low_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
+ rt73usb_set_vgc(rt2x00dev,
+ min_t(u8, link->vgc_level + 4, up_bound));
+ else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
+ rt73usb_set_vgc(rt2x00dev,
+ max_t(u8, link->vgc_level - 4, low_bound));
}
/*
--
1.5.6.1
next prev parent reply other threads:[~2008-12-20 10:01 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-20 9:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2008-12-20 9:52 ` [PATCH 1/15] rt2x00: Implement Powersaving Ivo van Doorn
2008-12-20 9:53 ` [PATCH 2/15] rt2x00: Move link tuning into seperate file Ivo van Doorn
2008-12-20 9:54 ` Ivo van Doorn [this message]
2008-12-20 9:54 ` [PATCH 4/15] rt2x00: Restrict interface between rt2x00link and drivers Ivo van Doorn
2008-12-20 9:55 ` [PATCH 5/15] rt2x00: Add mesh support Ivo van Doorn
2008-12-20 9:55 ` [PATCH 6/15] rt2x00: Add RFKILL support to rt2500usb and rt73usb Ivo van Doorn
2008-12-20 9:56 ` [PATCH 7/15] rt2x00: Rename CONFIG_CRYPTO_COPY_IV Ivo van Doorn
2008-12-20 9:57 ` [PATCH 8/15] rt2x00: Implement WDS support Ivo van Doorn
2008-12-20 9:57 ` [PATCH 9/15] rt2x00: Split EEPROM_NIC_TX_RX_FIXED Ivo van Doorn
2008-12-20 9:58 ` [PATCH 10/15] rt2x00: Move code into seperate functions Ivo van Doorn
2008-12-20 9:59 ` [PATCH 11/15] rt2x00: Remove ENTRY_TXD_OFDM_RATE Ivo van Doorn
2008-12-20 9:59 ` [PATCH 12/15] Allow drivers to pass the noise value during rxdone Ivo van Doorn
2008-12-20 9:59 ` [PATCH 13/15] rt2x00: Introduce RXDONE_SIGNAL_MASK mask Ivo van Doorn
2008-12-20 10:00 ` [PATCH 14/15] rt2x00: Fix segementation fault Ivo van Doorn
2008-12-20 10:00 ` [PATCH 15/15] rt2x00: Release rt2x00 2.3.0 Ivo van Doorn
2008-12-23 12:19 ` [PATCH 10/15] rt2x00: Move code into seperate functions David Shwatrz
2008-12-21 10:37 ` [PATCH 8/15] rt2x00: Implement WDS support Johannes Berg
2008-12-21 12:07 ` Ivo van Doorn
2008-12-21 17:53 ` [PATCH 1/15] rt2x00: Implement Powersaving David Shwatrz
2008-12-22 7:34 ` Holger Schurig
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=200812201054.22904.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=rt2400-devel@lists.sourceforge.net \
/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;
as well as URLs for NNTP newsgroup(s).