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 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.