You mentioned I couldn't use Linus's repository, so Where can I get a 
revised kernel with these changes already in place (I'm running 2.6.24.3 
from kernel.org)?
kurt

----Original Message Follows----
From: Larry Finger <[EMAIL PROTECTED]>
To: Broadcom Linux <bcm43xx-dev@lists.berlios.de>,  Stefano Brivio 
<[EMAIL PROTECTED]>
CC: KURT PETERS <[EMAIL PROTECTED]>, Michael Buesch <[EMAIL PROTECTED]>
Subject: [PATCH RFT V2] b43legacy: Fix TX power adjustments
Date: Sat, 05 Apr 2008 10:25:00 -0500

The calculation of TX power has recently been improved in b43.
This patch implements those improvements in b43legacy.

With this patch, the estimated power out calculation becomes
quite stable. After the initial settling, the estimate varies by
0.25 dBm, or less.

This patch is meant to apply to the wireless-testing tree. To
apply to -stable, or the 2.6.25-rcX code, delete the hunk that changes
drivers/net/wireless/b43legacy/main.c, as it will not apply to those
trees.

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;
@@ -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),



The calculation of TX power has recently been improved in b43.
This patch implements those improvements in b43legacy.

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;
@@ -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
Bcm43xx-dev@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to