This introduces code for 802.11a LocalOscillator support.

TODO: keep up to date with specs.


Signed-off-by: Stefano Brivio <[EMAIL PROTECTED]>
---

Index: wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_lo_a.c
===================================================================
--- /dev/null
+++ wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_lo_a.c
@@ -0,0 +1,188 @@
+/*
+
+  Broadcom BCM43xx wireless driver
+
+  A PHY LO (LocalOscillator) Measuring and Control routines
+
+  Copyright (c) 2005 Martin Langer <[EMAIL PROTECTED]>,
+  Copyright (c) 2005, 2006 Stefano Brivio <[EMAIL PROTECTED]>
+  Copyright (c) 2005-2007 Michael Buesch <[EMAIL PROTECTED]>
+  Copyright (c) 2005, 2006 Danny van Dyk <[EMAIL PROTECTED]>
+  Copyright (c) 2005, 2006 Andreas Jaggi <[EMAIL PROTECTED]>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "bcm43xx.h"
+#include "bcm43xx_lo.h"
+#include "bcm43xx_phy.h"
+#include "bcm43xx_main.h"
+
+#include <linux/delay.h>
+
+static const u8 q_vos[] = {0x0, 0x4, 0x8, 0x9, 0xD,};
+static const u8 i_vos[] = {0x0, 0x1, 0x5, 0x6, 0xA,};
+
+struct lo_a_saved_values {
+       u8 channel;
+
+       u16 reg_03F4;
+
+       u16 ofdmreg_10;
+       u16 ofdmreg_11;
+       u16 ofdmreg_7A;
+       u16 ofdmreg_6E;
+       u16 ofdmreg_7C;
+       u16 ofdmreg_6B;
+
+       u16 ofdmtab_0F_07;
+       u16 ofdmtab_0F_09;
+       u16 ofdmtab_0F_0A;
+       u16 ofdmtab_0F_0B;
+       u16 ofdmtab_0C_01;
+
+       u16 radio_09;
+       u16 radio_17;
+       u16 radio_19;
+}
+
+static void lo_a_setup(struct bcm43xx_wldev *dev, struct lo_g_saved_values 
*sav)
+{
+       struct bcm43xx_phy *phy = &dev->phy;
+
+       sav->channel = phy->channel;
+       bcm43xx_radio_selectchannel(dev, 64, 0);
+       sav->reg_03F4 = bcm43xx_read16(dev, 0x03F4);
+       sav->ofdmreg_10 = bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x10));
+       sav->ofdmreg_11 = bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x11));
+       sav->ofdmtab_0F_07 = bcm43xx_ofdmtab_read16(dev, 
BCM43xx_OFDMTAB_UNKNOWN_APHY, 0);
+       sav->ofdmtab_0F_09 = bcm43xx_ofdmtab_read16(dev, 
BCM43xx_OFDMTAB_UNKNOWN_APHY, 2);
+       sav->ofdmtab_0F_0A = bcm43xx_ofdmtab_read16(dev, 
BCM43xx_OFDMTAB_UNKNOWN_APHY, 3);
+       sav->ofdmtab_0F_0B = bcm43xx_ofdmtab_read16(dev, 
BCM43xx_OFDMTAB_UNKNOWN_APHY, 4);
+       sav->radio_17 = bcm43xx_radio_read16(dev, 0x0017);
+       sav->radio_19 = bcm43xx_radio_read16(dev, 0x0019);
+       sav->radio_09 = bcm43xx_radio_read16(dev, 0x0009);
+       sav->ofdmtab_0C_01 = bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_DAC, 
1);
+       bcm43xx_radio_write16(dev, 0x0009,
+               bcm43xx_radio_read16(dev, 0x0009) & 0xFFBF);
+}
+
+static void find_tssi(struct bcm43xx_wldev *dev)
+{
+       s16 tmp;
+
+       bcm43xx_dummy_transmission(dev);
+       tmp = bcm43xx_phy_read(dev, BCM43xx_PHY_IDLE_TSSI) & 0x00FF;
+       if (tmp >= 0x80)
+               tmp -= 0x100;
+       return tmp;
+}
+
+static u16 find_vos(struct bcm43xx_wldev *dev)
+{
+       struct bcm43xx_phy *phy = &dev->phy;
+       int i, j;
+       u16 radioval, radiosav_i[5], radiosav_q[5], radiosav_c, curr_tssi,
+           min_tssi = 0xFFFF;
+
+       bcm43xx_radio_write16(dev, 0x1E, 0x0000);
+       bcm43xx_phy_write(dev, BCM43xx_PHY_CRS0,
+               bcm43xx_phy_read(dev, BCM43xx_PHY_CRS0) & ~BCM43xx_PHY_CRS0_EN);
+       bcm43xx_write16(dev, 0x03F4, 0x0001);
+       bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x10),
+               bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x10) | 0x0C08);
+       bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x11),
+               (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x11)) & 0xF3F7) | 
0x0408);
+       bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_APHY, 0
+               bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_DC, 1));
+       bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_APHY, 2, 0x0001);
+       bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_APHY, 3, 0x0001);
+       bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_APHY, 4, 0x0001);
+       bcm43xx_phy_write(dev, BCM43xx_PHY_ADCCTL, 0xC111);
+       bcm43xx_phy_write(dev, BCM43xx_PHY_A_TEMP_SENSE, 0x0002);
+       if (phy->rev <= 2)
+               bcm43xx_wa_rssi_lt(dev);
+       bcm43xx_phy_write(dev, BCM43xx_PHY_BBTXDC_BIAS, 0x0000);
+       bcm43xx_radio_write16(dev, 0x0017, 0x0026);
+       if (phy->analog == 1)
+               bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 1
+                       (bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_DAC, 1)) & 
0xFF87 | 0x0010);
+       else
+               bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 1
+                       (bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_DAC, 1)) & 
0xFFC3 | 0x0008);
+       bcm43xx_radio_write16(dev, 0x0019, 0x0060);
+
+       for (i = 0; i < 5; i++) {
+               radioval = (bcm43xx_radio_read16(dev, 0x001E) & 0x00F0) | 
i_vos[i] << 4;
+               bcm43xx_radio_write16(dev, 0x001E, radioval_i);
+               curr_tssi = find_tssi(dev);
+               if (curr_tssi < min_tssi) {
+                       for (j = 0; j < i; j++)
+                               radiosav_i[j] = 0xFFFF;
+                       min_tssi = curr_tssi;
+                       radiosav_i[i] = radioval;
+               }
+               else if (curr_tssi == min_tssi)
+                       radiosav_i[i] = radioval;
+               else if (curr_tssi > min_tssi)
+                       radiosav_i[i] = 0xFFFF;
+       }
+       for (i = 0; i < 5; i++)
+               if (radiosav_i[i] != 0xFFFF) {
+                       bcm43xx_radio_write16(dev, 0x001E, radiosav_i[i]);
+                       break;
+               }
+
+       for (i = 0; i < 5; i++) {
+               radioval = (bcm43xx_radio_read16(dev, 0x001E) & 0x00F0) | 
q_vos[i];
+               bcm43xx_radio_write16(dev, 0x001E, radioval_q);
+               curr_tssi = find_tssi(dev);
+               if (curr_tssi < min_tssi) {
+                       for (j = 0; j < i; j++)
+                               radiosav_q[j] = 0xFFFF;
+                       min_tssi = curr_tssi;
+                       radiosav_q[i] = radioval;
+               }
+               else if (curr_tssi == min_tssi)
+                       radiosav_q[i] = radioval;
+               else if (curr_tssi > min_tssi)
+                       radiosav_q[i] = 0xFFFF;
+       }
+       for (i = 0; i < 5; i++)
+               if (radiosav_q[i] != 0xFFFF) {
+                       bcm43xx_radio_write16(dev, 0x001E, radiosav_q[i]);
+                       break;
+               }
+
+       min_tssi = 0xFFFF;
+       for (i = 0; i < 5; i++)
+               if (radiosav_i[i] != 0xFFFF)
+                       for (j = 0; j < 5; j++)
+                               if (radiosav_q[j] != 0xFFFF) {
+                                       radioval = (radiosav_q[j] & 0xF) |
+                                                   (radiosav_i[i] & 0xF0);
+                                       bcm43xx_radio_write16(dev, 0x001E,
+                                               radioval);
+                                       udelay(5);
+                                       curr_tssi = find_tssi(dev);
+                                       if (curr_tssi < min_tssi)
+                                               radiosav_c = radioval;
+                               }
+       bcm43xx_radio_write16(dev, 0x001E, radiosav_c);
+
+       return radiosav_c;
+}
Index: wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.c
+++ wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.c
@@ -122,7 +122,7 @@ static void bcm43xx_wa_gt(struct bcm43xx
        }
 }
 
-static void bcm43xx_wa_rssi_lt(struct bcm43xx_wldev *dev) /* RSSI lookup table 
*/
+void bcm43xx_wa_rssi_lt(struct bcm43xx_wldev *dev) /* RSSI lookup table */
 {
        int i;
 
Index: wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.h
+++ wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.h
@@ -2,6 +2,7 @@
 #define BCM43xx_WA_H_
 
 void bcm43xx_wa_initgains(struct bcm43xx_wldev *dev);
+void bcm43xx_wa_rssi_lt(struct bcm43xx_wldev *dev);
 void bcm43xx_wa_all(struct bcm43xx_wldev *dev);
 
 #endif /* BCM43xx_WA_H_ */
_______________________________________________
Bcm43xx-dev mailing list
Bcm43xx-dev@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to