]> err.no Git - linux-2.6/commitdiff
[PATCH] bcm43xx: set default attenuation values.
authorMichael Buesch <mbuesch@freenet.de>
Sun, 19 Mar 2006 23:01:04 +0000 (00:01 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 27 Mar 2006 16:19:42 +0000 (11:19 -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_radio.c
drivers/net/wireless/bcm43xx/bcm43xx_radio.h

index 8820012b4b3aac13d6aa256461710751557af6a5..1fca1f9c48feffc0af98de5c667e23223e293ead 100644 (file)
@@ -507,14 +507,23 @@ struct bcm43xx_radioinfo {
        u16 version;
        u8 revision;
 
-       /* 0: baseband attenuation,
-        * 1: radio attenuation, 
-        * 2: tx_CTL1
-        * 3: tx_CTL2
-        */
-       u16 txpower[4];
        /* Desired TX power in dBm Q5.2 */
        u16 txpower_desired;
+       /* TX Power control values. */
+       union {
+               /* B/G PHY */
+               struct {
+                       u16 baseband_atten;
+                       u16 radio_atten;
+                       u16 txctl1;
+                       u16 txctl2;
+               };
+               /* A PHY */
+               struct {
+                       u16 txpwr_offset;
+               };
+       };
+
        /* Current Interference Mitigation mode */
        int interfmode;
        /* Stack of saved values from the Interference Mitigation code */
index 12c93d274ae5f9f613af44d895a48c14d711718b..e680d2acc44b2ef518e3308b9b5d2852dbe98fdd 100644 (file)
@@ -560,12 +560,9 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
        radio->revision = revision;
 
        /* Set default attenuation values. */
-       radio->txpower[0] = 2;
-       radio->txpower[1] = 2;
-       if (revision == 1)
-               radio->txpower[2] = 3;
-       else
-               radio->txpower[2] = 0;
+       radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
+       radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
+       radio->txctl1 = bcm43xx_default_txctl1(bcm);
        if (phy->type == BCM43xx_PHYTYPE_A)
                radio->txpower_desired = bcm->sprom.maxpower_aphy;
        else
index 1ce9a45999037fa3084665aba68ce0070b187c35..054c64e462fbc72cf4d3cd0a2e168005c477f49e 100644 (file)
@@ -220,9 +220,9 @@ static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm)
                bcm43xx_radio_write16(bcm, 0x0076,
                                      bcm43xx_radio_read16(bcm, 0x0076) | 0x0084);
        } else {
-               saved_batt = radio->txpower[0];
-               saved_ratt = radio->txpower[1];
-               saved_txctl1 = radio->txpower[2];
+               saved_batt = radio->baseband_atten;
+               saved_ratt = radio->radio_atten;
+               saved_txctl1 = radio->txctl1;
                if ((radio->revision >= 6) && (radio->revision <= 8)
                    && /*FIXME: incomplete specs for 5 < revision < 9 */ 0)
                        bcm43xx_radio_set_txpower_bg(bcm, 0xB, 0x1F, 0);
@@ -1039,7 +1039,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
                bcm43xx_radio_write16(bcm, 0x0078, radio->initval);
                bcm43xx_radio_write16(bcm, 0x0052,
                                      (bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0)
-                                     | radio->txpower[3]);
+                                     | radio->txctl2);
        }
 
        if (phy->connected) {
@@ -1259,7 +1259,6 @@ struct bcm43xx_lopair * bcm43xx_find_lopair(struct bcm43xx_private *bcm,
        if (baseband_attenuation > 6)
                baseband_attenuation = 6;
        assert(radio_attenuation < 10);
-       assert(tx == 0 || tx == 3);
 
        if (tx == 3) {
                return bcm43xx_get_lopair(phy,
@@ -1275,9 +1274,9 @@ struct bcm43xx_lopair * bcm43xx_current_lopair(struct bcm43xx_private *bcm)
        struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
 
        return bcm43xx_find_lopair(bcm,
-                                  radio->txpower[0],
-                                  radio->txpower[1],
-                                  radio->txpower[2]);
+                                  radio->baseband_atten,
+                                  radio->radio_atten,
+                                  radio->txctl1);
 }
 
 /* Adjust B/G LO */
@@ -1311,7 +1310,7 @@ static void bcm43xx_phy_lo_g_measure_txctl2(struct bcm43xx_private *bcm)
                        txctl2 = i;
                }
        }
-       radio->txpower[3] = txctl2;
+       radio->txctl2 = txctl2;
 }
 
 static
@@ -1530,8 +1529,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
                                r31 = 0;
                        }
                        bcm43xx_radio_write16(bcm, 0x43, i);
-                       bcm43xx_radio_write16(bcm, 0x52,
-                                             radio->txpower[3]);
+                       bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
                        udelay(10);
 
                        bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
@@ -1573,7 +1571,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
                        }
                        bcm43xx_radio_write16(bcm, 0x43, i - 9);
                        bcm43xx_radio_write16(bcm, 0x52,
-                                             radio->txpower[3]
+                                             radio->txctl2
                                              | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above?
                        udelay(10);
 
@@ -1780,9 +1778,9 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
                }
 
                /* Calculate the new attenuation values. */
-               baseband_attenuation = radio->txpower[0];
+               baseband_attenuation = radio->baseband_atten;
                baseband_attenuation += baseband_att_delta;
-               radio_attenuation = radio->txpower[1];
+               radio_attenuation = radio->radio_atten;
                radio_attenuation += radio_att_delta;
 
                /* Get baseband and radio attenuation values into their permitted ranges.
@@ -1807,7 +1805,7 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
                }
                baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
 
-               txpower = radio->txpower[2];
+               txpower = radio->txctl1;
                if ((radio->version == 0x2050) && (radio->revision == 2)) {
                        if (radio_attenuation <= 1) {
                                if (txpower == 0) {
@@ -1829,7 +1827,7 @@ void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
                                }
                        }
                }
-               radio->txpower[2] = txpower;
+               radio->txctl1 = txpower;
                baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
                radio_attenuation = limit_value(radio_attenuation, 0, 9);
 
index cac604bc09552c0a1a0281390ff66e87c5496131..4e8d8c936ab45d6b785ba8464c3534a422849707 100644 (file)
@@ -1652,7 +1652,7 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower)
 
        bcm43xx_ilt_write(bcm, 0x3001, dac);
 
-       radio->txpower[0] = txpower;
+       radio->txpwr_offset = txpower;
 
        TODO();
        //TODO: FuncPlaceholder (Adjust BB loft cancel)
@@ -1666,17 +1666,14 @@ void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
 
        if (baseband_attenuation == 0xFFFF)
-               baseband_attenuation = radio->txpower[0];
-       else
-               radio->txpower[0] = baseband_attenuation;
+               baseband_attenuation = radio->baseband_atten;
        if (radio_attenuation == 0xFFFF)
-               radio_attenuation = radio->txpower[1];
-       else
-               radio->txpower[1] = radio_attenuation;
+               radio_attenuation = radio->radio_atten;
        if (txpower == 0xFFFF)
-               txpower = radio->txpower[2];
-       else
-               radio->txpower[2] = txpower;
+               txpower = radio->txctl1;
+       radio->baseband_atten = baseband_attenuation;
+       radio->radio_atten = radio_attenuation;
+       radio->txctl1 = txpower;
 
        assert(/*baseband_attenuation >= 0 &&*/ baseband_attenuation <= 11);
        if (radio->revision < 6)
@@ -1693,10 +1690,124 @@ void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
                                      (bcm43xx_radio_read16(bcm, 0x0052) & ~0x0070)
                                       | ((txpower << 4) & 0x0070));
        }
+       //FIXME: The spec is very weird and unclear here.
        if (phy->type == BCM43xx_PHYTYPE_G)
                bcm43xx_phy_lo_adjust(bcm, 0);
 }
 
+u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm)
+{
+       struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
+
+       if (radio->version == 0x2050 && radio->revision < 6)
+               return 0;
+       return 2;
+}
+
+u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm)
+{
+       struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
+       struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
+       u16 att = 0xFFFF;
+
+       if (phy->type == BCM43xx_PHYTYPE_A)
+               return 0x60;
+
+       switch (radio->version) {
+       case 0x2053:
+               switch (radio->revision) {
+               case 1:
+                       att = 6;
+                       break;
+               }
+               break;
+       case 0x2050:
+               switch (radio->revision) {
+               case 0:
+                       att = 5;
+                       break;
+               case 1:
+                       if (phy->type == BCM43xx_PHYTYPE_G) {
+                               if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
+                                   bcm->board_type == 0x421 &&
+                                   bcm->board_revision >= 30)
+                                       att = 3;
+                               else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
+                                        bcm->board_type == 0x416)
+                                       att = 3;
+                               else
+                                       att = 1;
+                       } else {
+                               if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
+                                   bcm->board_type == 0x421 &&
+                                   bcm->board_revision >= 30)
+                                       att = 7;
+                               else
+                                       att = 6;
+                       }
+                       break;
+               case 2:
+                       if (phy->type == BCM43xx_PHYTYPE_G) {
+                               if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
+                                   bcm->board_type == 0x421 &&
+                                   bcm->board_revision >= 30)
+                                       att = 3;
+                               else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
+                                        bcm->board_type == 0x416)
+                                       att = 5;
+                               else if (bcm->chip_id == 0x4320)
+                                       att = 4;
+                               else
+                                       att = 3;
+                       } else
+                               att = 6;
+                       break;
+               case 3:
+                       att = 5;
+                       break;
+               case 4:
+               case 5:
+                       att = 1;
+                       break;
+               case 6:
+               case 7:
+                       att = 5;
+                       break;
+               case 8:
+                       att = 0x1A;
+                       break;
+               case 9:
+               default:
+                       att = 5;
+               }
+       }
+       if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
+           bcm->board_type == 0x421) {
+               if (bcm->board_revision < 0x43)
+                       att = 2;
+               else if (bcm->board_revision < 0x51)
+                       att = 3;
+       }
+       if (att == 0xFFFF)
+               att = 5;
+
+       return att;
+}
+
+u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm)
+{
+       struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
+
+       if (radio->version != 0x2050)
+               return 0;
+       if (radio->revision == 1)
+               return 3;
+       if (radio->revision < 6)
+               return 2;
+       if (radio->revision == 8)
+               return 1;
+       return 0;
+}
 
 void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm)
 {
index a5d2e10d5d98a7d23cd977b2ba604d7f94497db8..9ed18039fa3e2f6ff0cc20157d609a72df769d3e 100644 (file)
@@ -72,6 +72,11 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower);
 void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
                                u16 baseband_attenuation, u16 attenuation,
                               u16 txpower);
+
+u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm);
+u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm);
+u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm);
+
 void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val);
 
 void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm);