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

Reply via email to