The calculation of TX power has recently been improved in b43.
This patch implements those improvements in b43legacy, and may
help with association/authentication with distant APs.
With this patch, the estimated power out calculation becomes
quite stable. After the initial settling, the estimate varies by
0.25 dBm, or less.
Signed-off-by: Larry Finger <[EMAIL PROTECTED]>
---
Index: wireless-testing/drivers/net/wireless/b43legacy/phy.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43legacy/phy.c
+++ wireless-testing/drivers/net/wireless/b43legacy/phy.c
@@ -1766,6 +1766,58 @@ static s8 b43legacy_phy_estimate_power_o
return dbm;
}
+void b43legacy_put_attenuation_into_ranges(int *_bbatt, int *_rfatt)
+{
+ int rfatt = *_rfatt;
+ int bbatt = *_bbatt;
+
+ /* Get baseband and radio attenuation values into their permitted
+ * ranges. Radio attenuation affects power level 4 times as much as
+ * baseband. */
+
+ /* Range constants */
+ const int rf_min = 0;
+ const int rf_max = 9;
+ const int bb_min = 0;
+ const int bb_max = 8;
+
+ while (1) {
+ if (rfatt > rf_max && bbatt > bb_max - 4)
+ break; /* Can not get it into ranges */
+ if (rfatt < rf_min && bbatt < bb_min + 4)
+ break; /* Can not get it into ranges */
+ if (bbatt > bb_max && rfatt > rf_max - 1)
+ break; /* Can not get it into ranges */
+ if (bbatt < bb_min && rfatt < rf_min + 1)
+ break; /* Can not get it into ranges */
+
+ if (bbatt > bb_max) {
+ bbatt -= 4;
+ rfatt += 1;
+ continue;
+ }
+ if (bbatt < bb_min) {
+ bbatt += 4;
+ rfatt -= 1;
+ continue;
+ }
+ if (rfatt > rf_max) {
+ rfatt -= 1;
+ bbatt += 4;
+ continue;
+ }
+ if (rfatt < rf_min) {
+ rfatt += 1;
+ bbatt -= 4;
+ continue;
+ }
+ break;
+ }
+
+ *_rfatt = limit_value(rfatt, rf_min, rf_max);
+ *_bbatt = limit_value(bbatt, bb_min, bb_max);
+}
+
/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */
void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
{
@@ -1783,8 +1835,8 @@ void b43legacy_phy_xmitpower(struct b43l
s16 pwr_adjust;
s16 radio_att_delta;
s16 baseband_att_delta;
- s16 radio_attenuation;
- s16 baseband_attenuation;
+ int radio_attenuation;
+ int baseband_attenuation;
if (phy->savedpctlreg == 0xFFFF)
return;
@@ -1833,7 +1885,8 @@ void b43legacy_phy_xmitpower(struct b43l
estimated_pwr = b43legacy_phy_estimate_power_out(dev, average);
- max_pwr = dev->dev->bus->sprom.maxpwr_bg;
+ max_pwr = dev->dev->bus->sprom.maxpwr_bg
+ - dev->dev->bus->sprom.antenna_gain.ghz24.a0;
if ((dev->dev->bus->sprom.boardflags_lo
& B43legacy_BFL_PACTRL) &&
@@ -1846,28 +1899,23 @@ void b43legacy_phy_xmitpower(struct b43l
dev->dev->bus->sprom.maxpwr_bg = max_pwr;
}
- /* Use regulatory information to get the maximum power.
- * In the absence of such data from mac80211, we will use 20 dBm, which
- * is the value for the EU, US, Canada, and most of the world.
- * The regulatory maximum is reduced by the antenna gain (from sprom)
- * and 1.5 dBm (a safety factor??). The result is in Q5.2 format
- * which accounts for the factor of 4 */
-#define REG_MAX_PWR 20
- max_pwr = min(REG_MAX_PWR * 4
- - dev->dev->bus->sprom.antenna_gain.ghz24.a0
- - 0x6, max_pwr);
-
- /* find the desired power in Q5.2 - power_level is in dBm
- * and limit it - max_pwr is already in Q5.2 */
- desired_pwr = limit_value(phy->power_level << 2, 0, max_pwr);
+ /* Get desired power (in Q5.2) */
+ desired_pwr = phy->power_level << 2;
+ if (unlikely(desired_pwr <= 0)) {
+ b43legacywarn(dev->wl, "Invalid power_level\n");
+ phy->power_level = 15;
+ desired_pwr = phy->power_level << 2;
+ }
+ /* And limit it. max_pwr already is Q5.2 */
+ desired_pwr = limit_value(desired_pwr, 0, max_pwr);
+
if (b43legacy_debug(dev, B43legacy_DBG_XMITPOWER))
b43legacydbg(dev->wl, "Current TX power output: " Q52_FMT
" dBm, Desired TX power output: " Q52_FMT
" dBm\n", Q52_ARG(estimated_pwr),
Q52_ARG(desired_pwr));
- /* Check if we need to adjust the current power. The factor of 2 is
- * for damping */
- pwr_adjust = (desired_pwr - estimated_pwr) / 2;
+ /* Check if we need to adjust the current power */
+ pwr_adjust = desired_pwr - estimated_pwr;
/* RF attenuation delta
* The minus sign is because lower attenuation => more power */
radio_att_delta = -(pwr_adjust + 7) >> 3;
@@ -1876,7 +1924,6 @@ void b43legacy_phy_xmitpower(struct b43l
/* Do we need to adjust anything? */
if ((radio_att_delta == 0) && (baseband_att_delta == 0)) {
b43legacy_phy_lo_mark_current_used(dev);
- return;
}
/* Calculate the new attenuation values. */
@@ -1885,28 +1932,9 @@ void b43legacy_phy_xmitpower(struct b43l
radio_attenuation = phy->rfatt;
radio_attenuation += radio_att_delta;
- /* Get baseband and radio attenuation values into permitted ranges.
- * baseband 0-11, radio 0-9.
- * Radio attenuation affects power level 4 times as much as baseband.
- */
- if (radio_attenuation < 0) {
- baseband_attenuation -= (4 * -radio_attenuation);
- radio_attenuation = 0;
- } else if (radio_attenuation > 9) {
- baseband_attenuation += (4 * (radio_attenuation - 9));
- radio_attenuation = 9;
- } else {
- while (baseband_attenuation < 0 && radio_attenuation > 0) {
- baseband_attenuation += 4;
- radio_attenuation--;
- }
- while (baseband_attenuation > 11 && radio_attenuation < 9) {
- baseband_attenuation -= 4;
- radio_attenuation++;
- }
- }
- baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
-
+ /* Get baseband and radio attenuation values into permitted ranges. */
+ b43legacy_put_attenuation_into_ranges(&baseband_attenuation,
+ &radio_attenuation);
txpower = phy->txctl1;
if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) {
if (radio_attenuation <= 1) {
@@ -1933,8 +1961,8 @@ void b43legacy_phy_xmitpower(struct b43l
}
/* Save the control values */
phy->txctl1 = txpower;
- baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
- radio_attenuation = limit_value(radio_attenuation, 0, 9);
+ b43legacy_put_attenuation_into_ranges(&baseband_attenuation,
+ &radio_attenuation);
phy->rfatt = radio_attenuation;
phy->bbatt = baseband_attenuation;
Index: wireless-testing/drivers/net/wireless/b43legacy/phy.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43legacy/phy.h
+++ wireless-testing/drivers/net/wireless/b43legacy/phy.h
@@ -160,8 +160,6 @@ void b43legacy_put_attenuation_into_rang
#define B43legacy_PHY_DC_LTBASE B43legacy_PHY_OFDM(0x3A0)
/* DC
lookup table base */
#define B43legacy_PHY_GAIN_LTBASE B43legacy_PHY_OFDM(0x3C0) /* Gain
lookup table base */
-void b43legacy_put_attenuation_into_ranges(int *_bbatt, int *_rfatt);
-
/* Masks for the different PHY versioning registers. */
#define B43legacy_PHYVER_ANALOG 0xF000
#define B43legacy_PHYVER_ANALOG_SHIFT 12
Index: wireless-testing/drivers/net/wireless/b43legacy/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43legacy/main.c
+++ wireless-testing/drivers/net/wireless/b43legacy/main.c
@@ -127,6 +127,7 @@ static struct ieee80211_rate __b43legacy
{ \
.center_freq = (_freq), \
.hw_value = (_chanid), \
+ .max_power = 30, \
}
static struct ieee80211_channel b43legacy_bg_chantable[] = {
CHANTAB_ENT(1, 2412),
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev