[PATCH] bcm43xx: fix txpower reporting in WE.
authorMichael Buesch <mbuesch@freenet.de>
Sun, 5 Feb 2006 14:28:20 +0000 (15:28 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 27 Mar 2006 16:18:30 +0000 (11:18 -0500)
Signed-off-by: Michael Buesch <mbuesch@freenet.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/bcm43xx/bcm43xx.h
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
drivers/net/wireless/bcm43xx/bcm43xx_wx.c

index 7b97d8b..981d563 100644 (file)
@@ -525,6 +525,8 @@ struct bcm43xx_radioinfo {
         * 3: tx_CTL2
         */
        u16 txpower[4];
+       /* Desired TX power in dBm Q5.2 */
+       u16 txpower_desired;
        /* Current Interference Mitigation mode */
        int interfmode;
        /* Stack of saved values from the Interference Mitigation code */
index 1051a49..8e08c41 100644 (file)
@@ -793,6 +793,10 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
                bcm->current_core->radio->txpower[2] = 3;
        else
                bcm->current_core->radio->txpower[2] = 0;
+       if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A)
+               bcm->current_core->radio->txpower_desired = bcm->sprom.maxpower_aphy;
+       else
+               bcm->current_core->radio->txpower_desired = bcm->sprom.maxpower_bgphy;
 
        /* Initialize the in-memory nrssi Lookup Table. */
        for (i = 0; i < 64; i++)
index d90f207..d3c2fc1 100644 (file)
@@ -1768,14 +1768,9 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
                        where REG is the max power as per the regulatory domain
                */
 
-               /*TODO: Get desired_pwr from wx_handlers or the stack
-               limit_value(desired_pwr, 0, max_pwr);
-               */
-
-               desired_pwr = max_pwr; /* remove this when we have a real desired_pwr */
-
+               desired_pwr = limit_value(radio->txpower_desired, 0, max_pwr);
+               /* Check if we need to adjust the current power. */
                pwr_adjust = desired_pwr - estimated_pwr;
-
                radio_att_delta = -(pwr_adjust + 7) >> 3;
                baseband_att_delta = -(pwr_adjust >> 1) - (4 * radio_att_delta);
                if ((radio_att_delta == 0) && (baseband_att_delta == 0)) {
index c1d788d..bed7cfb 100644 (file)
@@ -484,21 +484,40 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
                                    char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+       struct bcm43xx_radioinfo *radio;
+       struct bcm43xx_phyinfo *phy;
        unsigned long flags;
        int err = -ENODEV;
+       u16 maxpower;
 
        wx_enter();
 
+       if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) {
+               printk(PFX KERN_ERR "TX power not in dBm.\n");
+               return -EOPNOTSUPP;
+       }
+
        spin_lock_irqsave(&bcm->lock, flags);
        if (!bcm->initialized)
                goto out_unlock;
-       if (data->power.disabled != (!(bcm->current_core->radio->enabled))) {
-               if (data->power.disabled)
+       radio = bcm->current_core->radio;
+       phy = bcm->current_core->phy;
+       if (data->txpower.disabled != (!(radio->enabled))) {
+               if (data->txpower.disabled)
                        bcm43xx_radio_turn_off(bcm);
                else
                        bcm43xx_radio_turn_on(bcm);
        }
-       //TODO: set txpower.
+       if (data->txpower.value > 0) {
+               /* desired and maxpower dBm values are in Q5.2 */
+               if (phy->type == BCM43xx_PHYTYPE_A)
+                       maxpower = bcm->sprom.maxpower_aphy;
+               else
+                       maxpower = bcm->sprom.maxpower_bgphy;
+               radio->txpower_desired = limit_value(data->txpower.value << 2,
+                                                    0, maxpower);
+               bcm43xx_phy_xmitpower(bcm);
+       }
        err = 0;
 
 out_unlock:
@@ -513,18 +532,27 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
                                    char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+       struct bcm43xx_radioinfo *radio;
        unsigned long flags;
+       int err = -ENODEV;
 
        wx_enter();
 
        spin_lock_irqsave(&bcm->lock, flags);
-//TODO data->power.value = ???
-       data->power.fixed = 1;
-       data->power.flags = IW_TXPOW_DBM;
-       data->power.disabled = !(bcm->current_core->radio->enabled);
+       if (!bcm->initialized)
+               goto out_unlock;
+       radio = bcm->current_core->radio;
+       /* desired dBm value is in Q5.2 */
+       data->txpower.value = radio->txpower_desired >> 2;
+       data->txpower.fixed = 1;
+       data->txpower.flags = IW_TXPOW_DBM;
+       data->txpower.disabled = !(radio->enabled);
+
+       err = 0;
+out_unlock:
        spin_unlock_irqrestore(&bcm->lock, flags);
 
-       return 0;
+       return err;
 }
 
 static int bcm43xx_wx_set_retry(struct net_device *net_dev,