From: Stefano Brivio <stefano.brivio@polimi.it>
To: bcm43xx-dev@lists.berlios.de, linux-wireless@vger.kernel.org
Subject: [RFT] [PATCH] bcm43xx: ACI fixes
Date: Mon, 12 Mar 2007 01:04:20 +0100 [thread overview]
Message-ID: <20070312010420.353a59c0@localhost> (raw)
Please test the following patch. It syncs ACI (Adjacent Channels
Interference) code to specs. I can't test it right now. Will port to
mac80211 branch ASAP.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
----
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 95ff175..7023327 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -398,6 +398,9 @@
#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
+/* Statscounter offsets. */
+#define BCM43xx_SC_ACI 0x2E
+
/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
#define RX_RSSI_MAX 60
@@ -550,7 +553,11 @@ struct bcm43xx_phyinfo {
u8 connected:1,
calibrated:1,
is_locked:1, /* used in bcm43xx_phy_{un}lock() */
- dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */
+ dyn_tssi_tbl:1, /* used in bcm43xx_phy_init_tssi2dbm_table() */
+ g_interfmode:1; /* bit 4000 in PHY_G_CRS, used in periodic tasks */
+ u8 g_interfmode_timer; /* how much time ago g_interfmode was unset */
+ u16 g_sc_saved; /* used in periodic tasks for ACI */
+
/* LO Measurement Data.
* Use bcm43xx_get_lopair() to get a value.
*/
@@ -629,7 +636,9 @@ struct bcm43xx_radioinfo {
/* ACI (adjacent channel interference) flags. */
u8 aci_enable:1,
aci_wlan_automatic:1,
- aci_hw_rssi:1;
+ aci_hw_rssi:1,
+ aci_delay:5;
+ u8 aci_start;
};
/* Data structures for DMA transmission, per 80211 core. */
@@ -699,6 +708,18 @@ struct bcm43xx_noise_calculation {
s8 samples[8][4];
};
+/* Statscounter data (currently ACI only). */
+struct bcm43xx_statscounter_saved {
+ u16 aci;
+};
+
+/* Values for ACI moving average calculation. */
+struct bcm43xx_aci_saved {
+ u16 value[8];
+ u8 next:3,
+ set:3;
+};
+
struct bcm43xx_stats {
u8 noise;
struct iw_statistics wstats;
@@ -812,6 +833,10 @@ struct bcm43xx_private {
u32 irq_savedstate;
/* Link Quality calculation context. */
struct bcm43xx_noise_calculation noisecalc;
+ /* Statscounter tracking. */
+ struct bcm43xx_statscounter_saved sc;
+ /* ACI tracking. */
+ struct bcm43xx_aci_saved aci;
/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
int mac_suspended;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index e594af4..27ec519 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -3059,6 +3059,44 @@ static void bcm43xx_pcie_mdio_write(stru
bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0);
}
+/* We don't use any statscounter other than ACI for now */
+static u16 bcm43xx_sc_read(struct bcm43xx_private *bcm)
+{
+ struct bcm43xx_statscounter_saved *sc = &bcm->sc;
+ u16 tmp;
+
+ tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x80 + BCM43xx_SC_ACI)
+ - sc->aci;
+ if (tmp)
+ sc->aci += tmp;
+
+ return tmp;
+}
+
+static u16 bcm43xx_aci_moving_average(struct bcm43xx_private *bcm)
+{
+ struct bcm43xx_aci_saved *aci = &bcm->aci;
+
+ u8 i;
+ u16 avg;
+ u32 sum = 0;
+
+ aci->value[aci->next] = bcm43xx_sc_read(bcm);
+ if (unlikely(aci->set < 7))
+ aci->set++;
+ for (i = 0; i < aci->set; i++)
+ sum += aci->value[i];
+ avg = sum / (u16)8;
+ if ((sum % 8) > 3)
+ avg++;
+ if (aci->next < 7)
+ aci->next++;
+ else
+ aci->next = 0;
+
+ return avg;
+}
+
/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
* To enable core 0, pass a core_mask of 1<<0
*/
@@ -3182,6 +3220,8 @@ static void bcm43xx_periodic_every1sec(s
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
int radio_hw_enable;
+ unsigned long phylock_flags;
+ u16 tmp;
/* check if radio hardware enabled status changed */
radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
@@ -3191,27 +3231,56 @@ static void bcm43xx_periodic_every1sec(s
(radio_hw_enable == 0) ? "disabled" : "enabled");
bcm43xx_leds_update(bcm, 0);
}
+
if (phy->type == BCM43xx_PHYTYPE_G) {
- //TODO: update_aci_moving_average
- if (radio->aci_enable && radio->aci_wlan_automatic) {
+
+ if (radio->aci_start < 60)
+ radio->aci_start++;
+ if (radio->aci_delay)
+ radio->aci_delay--;
+ if (phy->g_interfmode && phy->g_interfmode_timer < 30)
+ phy->g_interfmode_timer++;
+
+ if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_AUTOWLAN &&
+ !radio->aci_delay) {
bcm43xx_mac_suspend(bcm);
- if (!radio->aci_enable && 1 /*TODO: not scanning? */) {
- if (0 /*TODO: bunch of conditions*/) {
- bcm43xx_radio_set_interference_mitigation(bcm,
- BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
- }
- } else if (1/*TODO*/) {
- /*
- if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) {
- bcm43xx_radio_set_interference_mitigation(bcm,
- BCM43xx_RADIO_INTERFMODE_NONE);
+ if (!radio->aci_enable)
+ {
+ if (bcm43xx_aci_moving_average(bcm) < 200) {
+ if (bcm43xx_radio_aci_scan(bcm)) {
+ bcm43xx_radio_set_interference_mitigation(bcm,
+ BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
+ radio->aci_start = 0;
+ } else
+ radio->aci_delay = 20;
}
- */
+ } else if (radio->aci_start == 60) {
+ if (bcm43xx_aci_moving_average(bcm) > 1000)
+ if (!bcm43xx_radio_aci_scan(bcm))
+ bcm43xx_radio_set_interference_mitigation(bcm,
+ BCM43xx_RADIO_INTERFMODE_NONE);
}
bcm43xx_mac_enable(bcm);
} else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN &&
- phy->rev == 1) {
- //TODO: implement rev1 workaround
+ phy->rev == 1) {
+ tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x00AE);
+ if (phy->g_interfmode) {
+ if (tmp && ((tmp - phy->g_sc_saved) > 1500)) {
+ bcm43xx_phy_lock(bcm, phylock_flags);
+ bcm43xx_phy_write(bcm, 0x00AE,
+ bcm43xx_phy_read(bcm, 0x00AE) & ~0x4000);
+ bcm43xx_phy_unlock(bcm, phylock_flags);
+ phy->g_interfmode = 1;
+ phy->g_interfmode_timer = 0;
+ }
+ } else if (phy->g_interfmode_timer == 30) {
+ bcm43xx_phy_lock(bcm, phylock_flags);
+ bcm43xx_phy_write(bcm, 0x00AE,
+ bcm43xx_phy_read(bcm, 0x00AE & 0x4000));
+ bcm43xx_phy_unlock(bcm, phylock_flags);
+ phy->g_interfmode = 0;
+ }
+ phy->g_sc_saved = tmp;
}
}
}
@@ -3297,10 +3366,16 @@ void bcm43xx_periodic_tasks_delete(struc
void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
{
struct delayed_work *work = &bcm->periodic_work;
+ struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler);
schedule_delayed_work(work, 0);
+
+ if (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x4000)
+ phy->g_interfmode = 1;
+ else
+ phy->g_interfmode = 0;
}
static void bcm43xx_security_init(struct bcm43xx_private *bcm)
@@ -3429,6 +3504,8 @@ static void prepare_radiodata_for_init(s
radio->aci_enable = 0;
radio->aci_wlan_automatic = 0;
radio->aci_hw_rssi = 0;
+ radio->aci_start = 0;
+ radio->aci_delay = 0;
}
static void prepare_priv_for_init(struct bcm43xx_private *bcm)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
next reply other threads:[~2007-03-12 0:08 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-12 0:04 Stefano Brivio [this message]
2007-03-12 3:29 ` [RFT] [PATCH] bcm43xx: ACI fixes Larry Finger
2007-03-12 5:51 ` Larry Finger
2007-03-12 6:05 ` Stefano Brivio
2007-03-12 20:28 ` Larry Finger
2007-03-12 20:53 ` Michael Buesch
2007-03-12 21:14 ` Larry Finger
2007-03-14 5:14 ` Larry Finger
2007-03-14 6:41 ` Stefano Brivio
2007-03-14 14:17 ` Michael Buesch
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=20070312010420.353a59c0@localhost \
--to=stefano.brivio@polimi.it \
--cc=bcm43xx-dev@lists.berlios.de \
--cc=linux-wireless@vger.kernel.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 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).