]> err.no Git - linux-2.6/blobdiff - drivers/net/wireless/bcm43xx/bcm43xx_radio.c
[PATCH] bcm43xx: MANUALWLAN fixes
[linux-2.6] / drivers / net / wireless / bcm43xx / bcm43xx_radio.c
index 63aae43ba838ab39b44b1d1cbf9641368131d53d..ee1e7a2afc08ee78c63b281c0b2ff50e1e0dcb17 100644 (file)
@@ -782,41 +782,30 @@ void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm)
 {
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
        struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-       s16 threshold;
+       s32 threshold;
        s32 a, b;
-       int tmp;
        s16 tmp16;
        u16 tmp_u16;
 
        switch (phy->type) {
        case BCM43xx_PHYTYPE_B: {
-               int radiotype = 0;
-
-               if (phy->rev < 2)
-                       return;
                if (radio->version != 0x2050)
                        return;
                if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI))
                        return;
 
-               tmp = radio->revision;
-               if ((radio->manufact == 0x175 && tmp == 5) ||
-                    (radio->manufact == 0x17F && (tmp == 3 || tmp == 4)))
-                       radiotype = 1;
-
-               if (radiotype == 1) {
+               if (radio->revision >= 6) {
+                       threshold = (radio->nrssi[1] - radio->nrssi[0]) * 32;
+                       threshold += 20 * (radio->nrssi[0] + 1);
+                       threshold /= 40;
+               } else
                        threshold = radio->nrssi[1] - 5;
-               } else {
-                       threshold = 40 * radio->nrssi[0];
-                       threshold += 33 * (radio->nrssi[1] - radio->nrssi[0]);
-                       threshold += 20;
-                       threshold /= 10;
-               }
+
                threshold = limit_value(threshold, 0, 0x3E);
                bcm43xx_phy_read(bcm, 0x0020); /* dummy read */
                bcm43xx_phy_write(bcm, 0x0020, (((u16)threshold) << 8) | 0x001C);
 
-               if (radiotype == 1) {
+               if (radio->revision >= 6) {
                        bcm43xx_phy_write(bcm, 0x0087, 0x0E0D);
                        bcm43xx_phy_write(bcm, 0x0086, 0x0C0B);
                        bcm43xx_phy_write(bcm, 0x0085, 0x0A09);
@@ -844,33 +833,38 @@ void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm)
                                                   & 0xF000) | 0x0AED);
                        }
                } else {
-                       tmp = radio->interfmode;
-                       if (tmp == BCM43xx_RADIO_INTERFMODE_NONWLAN) {
-                               a = -13;
-                               b = -17;
-                       } else if (tmp == BCM43xx_RADIO_INTERFMODE_NONE &&
-                                  !radio->aci_enable) {
-                               a = -13;
-                               b = -10;
+                       if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN) {
+                               a = 0xE;
+                               b = 0xA;
+                       } else if (!radio->aci_wlan_automatic && radio->aci_enable) {
+                               a = 0x13;
+                               b = 0x12;
                        } else {
-                               a = -8;
-                               b = -9;
+                               a = 0xE;
+                               b = 0x11;
                        }
-                       a += 0x1B;
-                       a *= radio->nrssi[1] - radio->nrssi[0];
-                       a += radio->nrssi[0] * 0x40;
-                       a /= 64;
-                       b += 0x1B;
-                       b *= radio->nrssi[1] - radio->nrssi[0];
-                       b += radio->nrssi[0] * 0x40;
-                       b /= 64;
 
+                       a = a * (radio->nrssi[1] - radio->nrssi[0]);
+                       a += (radio->nrssi[0] << 6);
+                       if (a < 32)
+                               a += 31;
+                       else
+                               a += 32;
+                       a = a >> 6;
                        a = limit_value(a, -31, 31);
+
+                       b = b * (radio->nrssi[1] - radio->nrssi[0]);
+                       b += (radio->nrssi[0] << 6);
+                       if (b < 32)
+                               b += 31;
+                       else
+                               b += 32;
+                       b = b >> 6;
                        b = limit_value(b, -31, 31);
 
                        tmp_u16 = bcm43xx_phy_read(bcm, 0x048A) & 0xF000;
-                       tmp_u16 |= ((u32)a & 0x003F);
-                       tmp_u16 |= (((u32)b & 0x003F) << 6);
+                       tmp_u16 |= ((u32)b & 0x0000003F);
+                       tmp_u16 |= (((u32)a & 0x0000003F) << 6);
                        bcm43xx_phy_write(bcm, 0x048A, tmp_u16);
                }
                break;
@@ -888,10 +882,10 @@ static void _stack_save(u32 *_stackptr, size_t *stackidx,
 {
        u32 *stackptr = &(_stackptr[*stackidx]);
 
-       assert((offset & 0xF000) == 0x0000);
-       assert((id & 0xF0) == 0x00);
+       assert((offset & 0xE000) == 0x0000);
+       assert((id & 0xF8) == 0x00);
        *stackptr = offset;
-       *stackptr |= ((u32)id) << 12;
+       *stackptr |= ((u32)id) << 13;
        *stackptr |= ((u32)value) << 16;
        (*stackidx)++;
        assert(*stackidx < BCM43xx_INTERFSTACK_SIZE);
@@ -902,12 +896,12 @@ static u16 _stack_restore(u32 *stackptr,
 {
        size_t i;
 
-       assert((offset & 0xF000) == 0x0000);
-       assert((id & 0xF0) == 0x00);
+       assert((offset & 0xE000) == 0x0000);
+       assert((id & 0xF8) == 0x00);
        for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) {
-               if ((*stackptr & 0x00000FFF) != offset)
+               if ((*stackptr & 0x00001FFF) != offset)
                        continue;
-               if (((*stackptr & 0x0000F000) >> 12) != id)
+               if (((*stackptr & 0x00007000) >> 13) != id)
                        continue;
                return ((*stackptr & 0xFFFF0000) >> 16);
        }
@@ -1399,11 +1393,12 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
        backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
 
        // Initialization
-       if (phy->version == 0) {
+       if (phy->analog == 0) {
                bcm43xx_write16(bcm, 0x03E6, 0x0122);
        } else {
-               if (phy->version >= 2)
-                       bcm43xx_write16(bcm, 0x03E6, 0x0040);
+               if (phy->analog >= 2)
+                       bcm43xx_phy_write(bcm, 0x0003, (bcm43xx_phy_read(bcm, 0x0003)
+                                       & 0xFFBF) | 0x0040);
                bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
                                (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000));
        }
@@ -1411,7 +1406,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
        ret = bcm43xx_radio_calibrationvalue(bcm);
 
        if (phy->type == BCM43xx_PHYTYPE_B)
-               bcm43xx_radio_write16(bcm, 0x0078, 0x0003);
+               bcm43xx_radio_write16(bcm, 0x0078, 0x0026);
 
        bcm43xx_phy_write(bcm, 0x0015, 0xBFAF);
        bcm43xx_phy_write(bcm, 0x002B, 0x1403);
@@ -1422,7 +1417,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
                              (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004));
        bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
        bcm43xx_radio_write16(bcm, 0x0043,
-                             bcm43xx_radio_read16(bcm, 0x0043) | 0x0009);
+                             (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0) | 0x0009);
        bcm43xx_phy_write(bcm, 0x0058, 0x0000);
 
        for (i = 0; i < 16; i++) {
@@ -1494,7 +1489,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
        bcm43xx_phy_write(bcm, 0x0059, backup[17]);
        bcm43xx_phy_write(bcm, 0x0058, backup[18]);
        bcm43xx_write16(bcm, 0x03E6, backup[11]);
-       if (phy->version != 0)
+       if (phy->analog != 0)
                bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]);
        bcm43xx_phy_write(bcm, 0x0035, backup[10]);
        bcm43xx_radio_selectchannel(bcm, radio->channel, 1);
@@ -1600,11 +1595,11 @@ int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm,
        u16 r8, tmp;
        u16 freq;
 
+       if (!ieee80211_is_valid_channel(bcm->ieee, channel))
+               return -EINVAL;
        if ((radio->manufact == 0x17F) &&
            (radio->version == 0x2060) &&
            (radio->revision == 1)) {
-               if (channel > 200)
-                       return -EINVAL;
                freq = channel2freq_a(channel);
 
                r8 = bcm43xx_radio_read16(bcm, 0x0008);
@@ -1657,9 +1652,6 @@ int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm,
                TODO(); //TODO: TSSI2dbm workaround
                bcm43xx_phy_xmitpower(bcm);//FIXME correct?
        } else {
-               if ((channel < 1) || (channel > 14))
-                       return -EINVAL;
-
                if (synthetic_pu_workaround)
                        bcm43xx_synth_pu_workaround(bcm, channel);
 
@@ -1990,6 +1982,7 @@ void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm)
        }
        radio->enabled = 1;
        dprintk(KERN_INFO PFX "Radio turned on\n");
+       bcm43xx_leds_update(bcm, 0);
 }
        
 void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm)
@@ -2010,6 +2003,7 @@ void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm)
                bcm43xx_phy_write(bcm, 0x0015, 0xAA00);
        radio->enabled = 0;
        dprintk(KERN_INFO PFX "Radio turned off\n");
+       bcm43xx_leds_update(bcm, 0);
 }
 
 void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm)