Here's latest version of the GPHY (APHY) init rewrite patch.
I fixed a bunch of bugs, but it's still broken.
It applies to my tree.
Index: bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.c
2007-06-02 17:33:22.000000000 +0200
@@ -0,0 +1,668 @@
+/*
+
+ Broadcom BCM43xx wireless driver
+
+ PHY workarounds.
+
+ Copyright (c) 2005 Martin Langer <[EMAIL PROTECTED]>,
+ Copyright (c) 2005-2007 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_main.h"
+#include "bcm43xx_tables.h"
+#include "bcm43xx_phy.h"
+#include "bcm43xx_wa.h"
+
+static void bcm43xx_wa_papd(struct bcm43xx_wldev *dev)
+{
+ u16 backup;
+
+ backup = bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_PWRDYN2, 0);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_PWRDYN2, 0, 7);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_APHY, 0, 0);
+ bcm43xx_dummy_transmission(dev);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_PWRDYN2, 0, backup);
+}
+
+static void bcm43xx_wa_auxclipthr(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x8E), 0x3800);
+}
+
+static void bcm43xx_wa_afcdac(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, 0x0035, 0x03FF);
+ bcm43xx_phy_write(dev, 0x0036, 0x0400);
+}
+
+static void bcm43xx_wa_txdc_offset(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DC, 0, 0x0051);
+}
+
+void bcm43xx_wa_initgains(struct bcm43xx_wldev *dev)
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+
+ bcm43xx_phy_write(dev, BCM43xx_PHY_LNAHPFCTL, 0x1FF9);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_LPFGAINCTL,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_LPFGAINCTL) & 0xFF0F);
+ if (phy->rev <= 2)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_LPFGAIN, 0,
0x1FBF);
+ bcm43xx_radio_write16(dev, 0x0002, 0x1FBF);
+
+ bcm43xx_phy_write(dev, 0x0024, 0x4680);
+ bcm43xx_phy_write(dev, 0x0020, 0x0003);
+ bcm43xx_phy_write(dev, 0x001D, 0x0F40);
+ bcm43xx_phy_write(dev, 0x001F, 0x1C00);
+ if (phy->rev <= 3)
+ bcm43xx_phy_write(dev, 0x002A,
+ (bcm43xx_phy_read(dev, 0x002A) & 0x00FF) | 0x0400);
+ else if (phy->rev == 5) {
+ bcm43xx_phy_write(dev, 0x002A,
+ (bcm43xx_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00);
+ bcm43xx_phy_write(dev, 0x00CC, 0x2121);
+ }
+ if (phy->rev >= 3)
+ bcm43xx_phy_write(dev, 0x00BA, 0x3ED5);
+}
+
+static void bcm43xx_wa_divider(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, 0x002B, bcm43xx_phy_read(dev, 0x002B) & ~0x0100);
+ bcm43xx_phy_write(dev, 0x008E, 0x58C1);
+}
+
+static void bcm43xx_wa_gt(struct bcm43xx_wldev *dev) /* Gain table. */
+{
+ if (dev->phy.rev <= 2) {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN2, 0, 15);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN2, 1, 31);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN2, 2, 42);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN2, 3, 48);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN2, 4, 58);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 0, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 1, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 2, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 3, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 4, 21);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 5, 21);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 6, 25);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN1, 0, 3);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN1, 1, 3);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN1, 2, 7);
+ } else {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 0, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 1, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 2, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 3, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 4, 21);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 5, 21);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAIN0, 6, 25);
+ }
+}
+
+static void bcm43xx_wa_rssi_lt(struct bcm43xx_wldev *dev) /* RSSI lookup table
*/
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_RSSI, i, i + 8);
+ for (i = 8; i < 16; i++)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_RSSI, i, i - 8);
+}
+
+static void bcm43xx_wa_analog(struct bcm43xx_wldev *dev)
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+
+ if (phy->analog > 2) {
+ if (phy->type == BCM43xx_PHYTYPE_A)
+ bcm43xx_phy_write(dev, BCM43xx_PHY_PWRDOWN, 0x1808);
+ else
+ bcm43xx_phy_write(dev, BCM43xx_PHY_PWRDOWN, 0x1000);
+ } else {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 3, 0x1044);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 4, 0x7201);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 6, 0x0040);
+ }
+}
+
+static void bcm43xx_wa_dac(struct bcm43xx_wldev *dev)
+{
+ if (dev->phy.analog == 1)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 1,
+ (bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_DAC, 1) &
~0x0034) | 0x0008);
+ else
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 1,
+ (bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_DAC, 1) &
~0x0078) | 0x0010);
+}
+
+static void bcm43xx_wa_fft(struct bcm43xx_wldev *dev) /* Fine frequency table
*/
+{
+ int i;
+
+ if (dev->phy.type == BCM43xx_PHYTYPE_A)
+ for (i = 0; i < BCM43xx_TAB_FINEFREQA_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DACRFPABB,
i, bcm43xx_tab_finefreqa[i]);
+ else
+ for (i = 0; i < BCM43xx_TAB_FINEFREQG_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DACRFPABB,
i, bcm43xx_tab_finefreqg[i]);
+}
+
+static void bcm43xx_wa_nft(struct bcm43xx_wldev *dev) /* Noise figure table */
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+ int i;
+
+ if (phy->type == BCM43xx_PHYTYPE_A) {
+ if (phy->rev == 2)
+ for (i = 0; i < BCM43xx_TAB_NOISEA2_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_AGC2, i, bcm43xx_tab_noisea2[i]);
+ else
+ for (i = 0; i < BCM43xx_TAB_NOISEA3_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_AGC2, i, bcm43xx_tab_noisea3[i]);
+ } else {
+ if (phy->rev == 1)
+ for (i = 0; i < BCM43xx_TAB_NOISEG1_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_AGC2, i, bcm43xx_tab_noiseg1[i]);
+ else
+ for (i = 0; i < BCM43xx_TAB_NOISEG2_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_AGC2, i, bcm43xx_tab_noiseg2[i]);
+ }
+}
+
+static void bcm43xx_wa_rt(struct bcm43xx_wldev *dev) /* Rotor table */
+{
+ int i;
+
+ for (i = 0; i < BCM43xx_TAB_ROTOR_SIZE; i++)
+ bcm43xx_ofdmtab_write32(dev, BCM43xx_OFDMTAB_ROTOR, i,
bcm43xx_tab_rotor[i]);
+}
+
+static void bcm43xx_wa_nst(struct bcm43xx_wldev *dev) /* Noise scale table */
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+ int i;
+
+ if (phy->type == BCM43xx_PHYTYPE_A) {
+ if (phy->rev <= 1)
+ for (i = 0; i < BCM43xx_TAB_NOISESCALE_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_NOISESCALE,
+ i, 0);
+ else if (phy->rev == 2)
+ for (i = 0; i < BCM43xx_TAB_NOISESCALE_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_NOISESCALE,
+ i,
bcm43xx_tab_noisescalea2[i]);
+ else if (phy->rev == 3)
+ for (i = 0; i < BCM43xx_TAB_NOISESCALE_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_NOISESCALE,
+ i,
bcm43xx_tab_noisescalea3[i]);
+ else
+ for (i = 0; i < BCM43xx_TAB_NOISESCALE_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_NOISESCALE,
+ i,
bcm43xx_tab_noisescaleg3[i]);
+ } else {
+ if (phy->rev >= 6) {
+ if (bcm43xx_phy_read(dev, BCM43xx_PHY_ENCORE) &
BCM43xx_PHY_ENCORE_EN)
+ for (i = 0; i < BCM43xx_TAB_NOISESCALE_SIZE;
i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_NOISESCALE,
+ i, bcm43xx_tab_noisescaleg3[i]);
+ else
+ for (i = 0; i < BCM43xx_TAB_NOISESCALE_SIZE;
i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_NOISESCALE,
+ i, bcm43xx_tab_noisescaleg2[i]);
+ } else {
+ for (i = 0; i < BCM43xx_TAB_NOISESCALE_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_NOISESCALE,
+ i,
bcm43xx_tab_noisescaleg1[i]);
+ }
+ }
+}
+
+static void bcm43xx_wa_art(struct bcm43xx_wldev *dev) /* ADV retard table */
+{
+ int i;
+
+ for (i = 0; i < BCM43xx_TAB_RETARD_SIZE; i++)
+ bcm43xx_ofdmtab_write32(dev, BCM43xx_OFDMTAB_ADVRETARD,
+ i, bcm43xx_tab_retard[i]);
+}
+
+static void bcm43xx_wa_txlna_gain(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DC, 13, 0x0000);
+}
+
+static void bcm43xx_wa_crs_reset(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, 0x002C, 0x0064);
+}
+
+static void bcm43xx_wa_2060txlna_gain(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_hf_write(dev, bcm43xx_hf_read(dev) |
+ BCM43xx_HF_2060W);
+}
+
+static void bcm43xx_wa_lms(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, 0x0055,
+ (bcm43xx_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004);
+}
+
+static void bcm43xx_wa_mixedsignal(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 1, 3);
+}
+
+static void bcm43xx_wa_msst(struct bcm43xx_wldev *dev) /* Min sigma square
table */
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+ int i;
+ const u16 *tab;
+
+ if (phy->type == BCM43xx_PHYTYPE_A) {
+ tab = bcm43xx_tab_sigmasqr1;
+ } else if (phy->type == BCM43xx_PHYTYPE_G) {
+ tab = bcm43xx_tab_sigmasqr2;
+ } else {
+ assert(0);
+ return;
+ }
+
+ for (i = 0; i < BCM43xx_TAB_SIGMASQR_SIZE; i++) {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_MINSIGSQ,
+ i, tab[i]);
+ }
+}
+
+static void bcm43xx_wa_iqadc(struct bcm43xx_wldev *dev)
+{
+ if (dev->phy.analog == 4)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DAC, 0,
+ bcm43xx_ofdmtab_read16(dev, BCM43xx_OFDMTAB_DAC, 0) &
~0xF000);
+}
+
+static void bcm43xx_wa_crs_ed(struct bcm43xx_wldev *dev)
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+
+ if (phy->rev == 1) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRSTHRES1, 0x4F19);
+ } else if (phy->rev == 2) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRSTHRES1_R1, 0x1861);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRSTHRES2_R1, 0x1861);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_ANTDWELL,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_ANTDWELL)
+ | 0x0800);
+ } else {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRSTHRES1_R1, 0x0098);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRSTHRES2_R1, 0x0070);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xC9), 0x0080);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_ANTDWELL,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_ANTDWELL)
+ | 0x0800);
+ }
+}
+
+static void bcm43xx_wa_crs_thr(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRS0,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_CRS0) & ~0x03C0) |
0xD000);
+}
+
+static void bcm43xx_wa_crs_blank(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x2C), 0x005A);
+}
+
+static void bcm43xx_wa_cck_shiftbits(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CCKSHIFTBITS, 0x0026);
+}
+
+static void bcm43xx_wa_wrssi_offset(struct bcm43xx_wldev *dev)
+{
+ int i;
+
+ if (dev->phy.rev == 1) {
+ for (i = 0; i < 16; i++) {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_WRSSI_R1,
+ i, 0x0020);
+ }
+ } else {
+ for (i = 0; i < 32; i++) {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_WRSSI,
+ i, 0x0820);
+ }
+ }
+}
+
+static void bcm43xx_wa_txpuoff_rxpuon(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_0F, 2, 15);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_0F, 3, 20);
+}
+
+static void bcm43xx_wa_altagc(struct bcm43xx_wldev *dev)
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+
+ if (phy->rev == 1) {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1_R1, 0, 254);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1_R1, 1, 13);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1_R1, 2, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1_R1, 3, 25);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC2, 0, 0x2710);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC2, 1, 0x9B83);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC2, 2, 0x9B83);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC2, 3, 0x0F8D);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_LMS, 4);
+ } else {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 0, 254);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 1, 13);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 2, 19);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 3, 25);
+ }
+
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CCKSHIFTBITS_WA,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_CCKSHIFTBITS_WA) & ~0xFF00)
| 0x5700);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x1A),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x1A)) & ~0x007F) |
0x000F);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x1A),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x1A)) & ~0x3F80) |
0x2B80);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_ANTWRSETT,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_ANTWRSETT) & 0xF0FF) |
0x0300);
+ bcm43xx_radio_write16(dev, 0x7A,
+ bcm43xx_radio_read16(dev, 0x7A) | 0x0008);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_N1P1GAIN,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_N1P1GAIN) & ~0x000F) |
0x0008);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_P1P2GAIN,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_P1P2GAIN) & ~0x0F00) |
0x0600);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_N1N2GAIN,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_N1N2GAIN) & ~0x0F00) |
0x0700);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_N1P1GAIN,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_N1P1GAIN) & ~0x0F00) |
0x0100);
+ if (phy->rev == 1) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_N1N2GAIN,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_N1N2GAIN)
+ & ~0x000F) | 0x0007);
+ }
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x88),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x88)) & ~0x00FF) |
0x001C);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x88),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x88)) & ~0x3F00) |
0x0200);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x96),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x96)) & ~0x00FF) |
0x001C);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x89),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x89)) & ~0x00FF) |
0x0020);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x89),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x89)) & ~0x3F00) |
0x0200);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x82),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x82)) & ~0x00FF) |
0x002E);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x96),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x96)) & ~0xFF00) |
0x1A00);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x81),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x81)) & ~0x00FF) |
0x0028);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x81),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x81)) & ~0xFF00) |
0x2C00);
+ if (phy->rev == 1) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_PEAK_COUNT, 0x092B);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x1B),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x1B)) &
~0x001E) | 0x0002);
+ } else {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x1B),
+ bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x1B)) &
~0x001E);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x1F), 0x287A);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_LPFGAINCTL,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_LPFGAINCTL) &
~0x000F) | 0x0004);
+ if (phy->rev >= 6) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x22), 0x287A);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_LPFGAINCTL,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_LPFGAINCTL)
& ~0xF000) | 0x3000);
+ }
+ }
+ bcm43xx_phy_write(dev, BCM43xx_PHY_DIVSRCHIDX,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_DIVSRCHIDX) & 0x7F7F) |
0x7874);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x8E), 0x1C00);
+ if (phy->rev == 1) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_DIVP1P2GAIN,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_DIVP1P2GAIN) &
~0x0F00) | 0x0600);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x8B), 0x005E);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_ANTWRSETT,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_ANTWRSETT) &
~0x00FF) | 0x001E);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x8D), 0x0002);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3_R1, 0, 0);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3_R1, 1, 7);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3_R1, 2, 16);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3_R1, 3, 28);
+ } else {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3, 0, 0);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3, 1, 7);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3, 2, 16);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC3, 3, 28);
+ }
+ if (phy->rev >= 6) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x26),
+ bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x26)) &
~0x0003);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x26),
+ bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x26)) &
~0x1000);
+ }
+}
+
+static void bcm43xx_wa_tr_ltov(struct bcm43xx_wldev *dev) /* TR Lookup Table
Original Values */
+{
+ bcm43xx_gtab_write(dev, BCM43xx_GTAB_ORIGTR, 0, 0xC480);
+}
+
+static void bcm43xx_wa_cpll_nonpilot(struct bcm43xx_wldev *dev)
+{
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_11, 0, 0);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_11, 1, 0);
+}
+
+static void bcm43xx_wa_rssi_adc(struct bcm43xx_wldev *dev)
+{
+ if (dev->phy.analog == 4)
+ bcm43xx_phy_write(dev, 0x00DC, 0x7454);
+}
+
+static void bcm43xx_wa_boards_a(struct bcm43xx_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+
+ if (bus->board_vendor == SSB_BOARDVENDOR_BCM &&
+ bus->board_type == SSB_BOARD_BU4306 &&
+ bus->board_rev < 0x30) {
+ bcm43xx_phy_write(dev, 0x0010, 0xE000);
+ bcm43xx_phy_write(dev, 0x0013, 0x0140);
+ bcm43xx_phy_write(dev, 0x0014, 0x0280);
+ } else {
+ if (bus->board_type == SSB_BOARD_MP4318 &&
+ bus->board_rev < 0x20) {
+ bcm43xx_phy_write(dev, 0x0013, 0x0210);
+ bcm43xx_phy_write(dev, 0x0014, 0x0840);
+ } else {
+ bcm43xx_phy_write(dev, 0x0013, 0x0140);
+ bcm43xx_phy_write(dev, 0x0014, 0x0280);
+ }
+ if (dev->phy.rev <= 4)
+ bcm43xx_phy_write(dev, 0x0010, 0xE000);
+ else
+ bcm43xx_phy_write(dev, 0x0010, 0x2000);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_DC, 1, 0x0039);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_UNKNOWN_APHY, 7,
0x0040);
+ }
+}
+
+static void bcm43xx_wa_boards_g(struct bcm43xx_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+ struct bcm43xx_phy *phy = &dev->phy;
+
+ if (bus->board_vendor != SSB_BOARDVENDOR_BCM ||
+ bus->board_type != SSB_BOARD_BU4306 ||
+ bus->board_rev != 0x17) {
+ if (phy->rev < 2) {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAINX_R1,
1, 0x0002);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAINX_R1,
2, 0x0001);
+ } else {
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAINX, 1,
0x0002);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_GAINX, 2,
0x0001);
+ if ((bus->sprom.r1.boardflags_lo & BCM43xx_BFL_EXTLNA)
&&
+ (phy->rev >= 7)) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_EXTG(0x11),
+ bcm43xx_phy_read(dev,
BCM43xx_PHY_EXTG(0x11)) & 0xF7FF);
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_GAINX, 0x0020, 0x0001);
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_GAINX, 0x0021, 0x0001);
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_GAINX, 0x0022, 0x0001);
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_GAINX, 0x0023, 0x0000);
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_GAINX, 0x0000, 0x0000);
+ bcm43xx_ofdmtab_write16(dev,
BCM43xx_OFDMTAB_GAINX, 0x0003, 0x0002);
+ }
+ }
+ }
+ if (bus->sprom.r1.boardflags_lo & BCM43xx_BFL_FEM) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_GTABCTL, 0x3120);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_GTABDATA, 0xC480);
+ }
+}
+
+void bcm43xx_wa_all(struct bcm43xx_wldev *dev)
+{
+ struct bcm43xx_phy *phy = &dev->phy;
+
+ if (phy->type == BCM43xx_PHYTYPE_A) {
+ switch (phy->rev) {
+ case 2:
+ bcm43xx_wa_papd(dev);
+ bcm43xx_wa_auxclipthr(dev);
+ bcm43xx_wa_afcdac(dev);
+ bcm43xx_wa_txdc_offset(dev);
+ bcm43xx_wa_initgains(dev);
+ bcm43xx_wa_divider(dev);
+ bcm43xx_wa_gt(dev);
+ bcm43xx_wa_rssi_lt(dev);
+ bcm43xx_wa_analog(dev);
+ bcm43xx_wa_dac(dev);
+ bcm43xx_wa_fft(dev);
+ bcm43xx_wa_nft(dev);
+ bcm43xx_wa_rt(dev);
+ bcm43xx_wa_nst(dev);
+ bcm43xx_wa_art(dev);
+ bcm43xx_wa_txlna_gain(dev);
+ bcm43xx_wa_crs_reset(dev);
+ bcm43xx_wa_2060txlna_gain(dev);
+ bcm43xx_wa_lms(dev);
+ break;
+ case 3:
+ bcm43xx_wa_papd(dev);
+ bcm43xx_wa_mixedsignal(dev);
+ bcm43xx_wa_rssi_lt(dev);
+ bcm43xx_wa_txdc_offset(dev);
+ bcm43xx_wa_initgains(dev);
+ bcm43xx_wa_dac(dev);
+ bcm43xx_wa_nft(dev);
+ bcm43xx_wa_nst(dev);
+ bcm43xx_wa_msst(dev);
+ bcm43xx_wa_analog(dev);
+ bcm43xx_wa_gt(dev);
+ bcm43xx_wa_txpuoff_rxpuon(dev);
+ bcm43xx_wa_txlna_gain(dev);
+ break;
+ case 5:
+ bcm43xx_wa_iqadc(dev);
+ case 6:
+ bcm43xx_wa_papd(dev);
+ bcm43xx_wa_rssi_lt(dev);
+ bcm43xx_wa_txdc_offset(dev);
+ bcm43xx_wa_initgains(dev);
+ bcm43xx_wa_dac(dev);
+ bcm43xx_wa_nft(dev);
+ bcm43xx_wa_nst(dev);
+ bcm43xx_wa_msst(dev);
+ bcm43xx_wa_analog(dev);
+ bcm43xx_wa_gt(dev);
+ bcm43xx_wa_txpuoff_rxpuon(dev);
+ bcm43xx_wa_txlna_gain(dev);
+ break;
+ case 7:
+ bcm43xx_wa_iqadc(dev);
+ bcm43xx_wa_papd(dev);
+ bcm43xx_wa_rssi_lt(dev);
+ bcm43xx_wa_txdc_offset(dev);
+ bcm43xx_wa_initgains(dev);
+ bcm43xx_wa_dac(dev);
+ bcm43xx_wa_nft(dev);
+ bcm43xx_wa_nst(dev);
+ bcm43xx_wa_msst(dev);
+ bcm43xx_wa_analog(dev);
+ bcm43xx_wa_gt(dev);
+ bcm43xx_wa_txpuoff_rxpuon(dev);
+ bcm43xx_wa_txlna_gain(dev);
+ bcm43xx_wa_rssi_adc(dev);
+ default:
+ assert(0);
+ }
+ bcm43xx_wa_boards_a(dev);
+ } else if (phy->type == BCM43xx_PHYTYPE_G) {
+ switch (phy->rev) {
+ case 1://XXX review rev1
+ bcm43xx_wa_crs_ed(dev);
+ bcm43xx_wa_crs_thr(dev);
+ bcm43xx_wa_crs_blank(dev);
+ bcm43xx_wa_cck_shiftbits(dev);
+ bcm43xx_wa_fft(dev);
+ bcm43xx_wa_nft(dev);
+ bcm43xx_wa_rt(dev);
+ bcm43xx_wa_nst(dev);
+ bcm43xx_wa_art(dev);
+ bcm43xx_wa_wrssi_offset(dev);
+ bcm43xx_wa_altagc(dev);
+ break;
+ case 2:
+ case 6:
+ case 7:
+ case 8:
+ bcm43xx_wa_tr_ltov(dev);
+ bcm43xx_wa_crs_ed(dev);
+ bcm43xx_wa_rssi_lt(dev);
+ bcm43xx_wa_nft(dev);
+ bcm43xx_wa_nst(dev);
+ bcm43xx_wa_msst(dev);
+ bcm43xx_wa_wrssi_offset(dev);
+ bcm43xx_wa_altagc(dev);
+ bcm43xx_wa_analog(dev);
+ bcm43xx_wa_txpuoff_rxpuon(dev);
+ break;
+ default:
+ assert(0);
+ }
+ bcm43xx_wa_boards_g(dev);
+ } else { /* No N PHY support so far */
+ assert(0);
+ }
+
+ bcm43xx_wa_cpll_nonpilot(dev);
+}
Index: bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_wa.h
2007-06-02 17:33:22.000000000 +0200
@@ -0,0 +1,7 @@
+#ifndef BCM43xx_WA_H_
+#define BCM43xx_WA_H_
+
+void bcm43xx_wa_initgains(struct bcm43xx_wldev *dev);
+void bcm43xx_wa_all(struct bcm43xx_wldev *dev);
+
+#endif /* BCM43xx_WA_H_ */
Index:
bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_tables.c
===================================================================
---
bu3sch-wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_tables.c
2007-05-24 19:38:54.000000000 +0200
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_tables.c
2007-06-02 17:33:22.000000000 +0200
@@ -230,7 +230,7 @@ const u16 bcm43xx_tab_noisea2[] = {
};
const u16 bcm43xx_tab_noisea3[] = {
- 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
+ 0x5E5E, 0x5E5E, 0x5E5E, 0x3F48,
0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
};
@@ -244,6 +244,26 @@ const u16 bcm43xx_tab_noiseg2[] = {
0x0000, 0x0000, 0x0000, 0x0000,
};
+const u16 bcm43xx_tab_noisescalea2[] = {
+ 0x6767, 0x6767, 0x6767, 0x6767, /* 0 */
+ 0x6767, 0x6767, 0x6767, 0x6767,
+ 0x6767, 0x6767, 0x6767, 0x6767,
+ 0x6767, 0x6700, 0x6767, 0x6767,
+ 0x6767, 0x6767, 0x6767, 0x6767, /* 16 */
+ 0x6767, 0x6767, 0x6767, 0x6767,
+ 0x6767, 0x6767, 0x0067,
+};
+
+const u16 bcm43xx_tab_noisescalea3[] = {
+ 0x2323, 0x2323, 0x2323, 0x2323, /* 0 */
+ 0x2323, 0x2323, 0x2323, 0x2323,
+ 0x2323, 0x2323, 0x2323, 0x2323,
+ 0x2323, 0x2300, 0x2323, 0x2323,
+ 0x2323, 0x2323, 0x2323, 0x2323, /* 16 */
+ 0x2323, 0x2323, 0x2323, 0x2323,
+ 0x2323, 0x2323, 0x0023,
+};
+
const u16 bcm43xx_tab_noisescaleg1[] = {
0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */
0x2F2D, 0x2A2A, 0x2527, 0x1F21,
@@ -255,7 +275,7 @@ const u16 bcm43xx_tab_noisescaleg1[] = {
};
const u16 bcm43xx_tab_noisescaleg2[] = {
- 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */
+ 0xD8DD, 0xCBD4, 0xBCC0, 0xB6B7, /* 0 */
0xB2B0, 0xADAD, 0xA7A9, 0x9FA1,
0x969B, 0x9195, 0x8F8F, 0x8A8A,
0x8A8A, 0x8A00, 0x8A8A, 0x8F8A,
@@ -308,6 +328,27 @@ const u16 bcm43xx_tab_sigmasqr2[] = {
0x00DE,
};
+const u16 bcm43xx_tab_rssiagc1[] = {
+ 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, /* 0 */
+ 0xFFF8, 0xFFF9, 0xFFFC, 0xFFFE,
+ 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8,
+ 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8,
+};
+
+const u16 bcm43xx_tab_rssiagc2[] = {
+ 0x0820, 0x0820, 0x0920, 0x0C38, /* 0 */
+ 0x0820, 0x0820, 0x0820, 0x0820,
+ 0x0820, 0x0820, 0x0920, 0x0A38,
+ 0x0820, 0x0820, 0x0820, 0x0820,
+ 0x0820, 0x0820, 0x0920, 0x0A38, /* 16 */
+ 0x0820, 0x0820, 0x0820, 0x0820,
+ 0x0820, 0x0820, 0x0920, 0x0A38,
+ 0x0820, 0x0820, 0x0820, 0x0820,
+ 0x0820, 0x0820, 0x0920, 0x0A38, /* 32 */
+ 0x0820, 0x0820, 0x0820, 0x0820,
+ 0x0820, 0x0820, 0x0920, 0x0A38,
+ 0x0820, 0x0820, 0x0820, 0x0820,
+};
static inline void assert_sizes(void)
{
@@ -319,34 +360,59 @@ static inline void assert_sizes(void)
BUILD_BUG_ON(BCM43xx_TAB_NOISEA3_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noisea3));
BUILD_BUG_ON(BCM43xx_TAB_NOISEG1_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noiseg1));
BUILD_BUG_ON(BCM43xx_TAB_NOISEG2_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noiseg2));
- BUILD_BUG_ON(BCM43xx_TAB_NOISESCALEG_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noisescaleg1));
- BUILD_BUG_ON(BCM43xx_TAB_NOISESCALEG_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noisescaleg2));
- BUILD_BUG_ON(BCM43xx_TAB_NOISESCALEG_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noisescaleg3));
+ BUILD_BUG_ON(BCM43xx_TAB_NOISESCALE_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noisescaleg1));
+ BUILD_BUG_ON(BCM43xx_TAB_NOISESCALE_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noisescaleg2));
+ BUILD_BUG_ON(BCM43xx_TAB_NOISESCALE_SIZE !=
ARRAY_SIZE(bcm43xx_tab_noisescaleg3));
BUILD_BUG_ON(BCM43xx_TAB_SIGMASQR_SIZE !=
ARRAY_SIZE(bcm43xx_tab_sigmasqr1));
BUILD_BUG_ON(BCM43xx_TAB_SIGMASQR_SIZE !=
ARRAY_SIZE(bcm43xx_tab_sigmasqr2));
+ BUILD_BUG_ON(BCM43xx_TAB_RSSIAGC1_SIZE !=
ARRAY_SIZE(bcm43xx_tab_rssiagc1));
+ BUILD_BUG_ON(BCM43xx_TAB_RSSIAGC2_SIZE !=
ARRAY_SIZE(bcm43xx_tab_rssiagc2));
}
u16 bcm43xx_ofdmtab_read16(struct bcm43xx_wldev *dev, u16 table, u16 offset)
{
- assert_sizes();
+ struct bcm43xx_phy *phy = &dev->phy;
+ u16 addr;
+
+ addr = table + offset;
+ if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 1) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, addr);
+ phy->ofdm_valid = 1;
+ }
+ phy->ofdm_addr = addr;
- bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, table + offset);
return bcm43xx_phy_read(dev, BCM43xx_PHY_OTABLEI);
+ assert_sizes();
}
void bcm43xx_ofdmtab_write16(struct bcm43xx_wldev *dev, u16 table,
u16 offset, u16 value)
{
- bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, table + offset);
+ struct bcm43xx_phy *phy = &dev->phy;
+ u16 addr;
+
+ addr = table + offset;
+ if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 2) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, addr);
+ phy->ofdm_valid = 2;
+ }
+ phy->ofdm_addr = addr;
bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLEI, value);
}
u32 bcm43xx_ofdmtab_read32(struct bcm43xx_wldev *dev, u16 table, u16 offset)
{
+ struct bcm43xx_phy *phy = &dev->phy;
u32 ret;
+ u16 addr;
- bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, table + offset);
+ addr = table + offset;
+ if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 1) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, addr);
+ phy->ofdm_valid = 1;
+ }
+ phy->ofdm_addr = addr;
ret = bcm43xx_phy_read(dev, BCM43xx_PHY_OTABLEQ);
ret <<= 16;
ret |= bcm43xx_phy_read(dev, BCM43xx_PHY_OTABLEI);
@@ -357,9 +423,17 @@ u32 bcm43xx_ofdmtab_read32(struct bcm43x
void bcm43xx_ofdmtab_write32(struct bcm43xx_wldev *dev, u16 table,
u16 offset, u32 value)
{
- bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, table + offset);
- bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLEI, value);
+ struct bcm43xx_phy *phy = &dev->phy;
+ u16 addr;
+
+ addr = table + offset;
+ if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 2) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLECTL, addr);
+ phy->ofdm_valid = 2;
+ }
+ phy->ofdm_addr = addr;
bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLEQ, (value >> 16));
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OTABLEI, value);
}
u16 bcm43xx_gtab_read(struct bcm43xx_wldev *dev, u16 table, u16 offset)
Index: bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx.h
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx.h
2007-06-02 02:09:56.000000000 +0200
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx.h
2007-06-02 17:33:22.000000000 +0200
@@ -591,6 +591,10 @@ struct bcm43xx_phy {
u16 lofcal;
u16 initval;//FIXME rename?
+
+ /* OFDM address read/write caching for hardware auto-increment. */
+ u16 ofdm_addr;
+ u8 ofdm_valid; /* 0: invalid, 1: read, 2: write */
};
/* Data structures for DMA transmission, per 80211 core. */
Index: bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_main.c
===================================================================
---
bu3sch-wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_main.c
2007-06-02 01:56:02.000000000 +0200
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_main.c
2007-06-02 17:33:22.000000000 +0200
@@ -3129,6 +3129,9 @@ static void setup_struct_phy_for_init(st
spin_lock_init(&phy->lock);
phy->interfmode = BCM43xx_INTERFMODE_NONE;
phy->channel = 0xFF;
+
+ /* OFDM address caching. */
+ phy->ofdm_valid = 0;
}
static void setup_struct_wldev_for_init(struct bcm43xx_wldev *dev)
Index: bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.h
===================================================================
---
bu3sch-wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.h
2007-05-24 19:38:54.000000000 +0200
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.h
2007-06-02 17:33:22.000000000 +0200
@@ -28,8 +28,11 @@ struct bcm43xx_wldev;
#define BCM43xx_PHY_PWRDOWN BCM43xx_PHY_OFDM(0x03) /* Powerdown */
#define BCM43xx_PHY_CRSTHRES1 BCM43xx_PHY_OFDM(0x06) /* CRS
Threshold 1 */
#define BCM43xx_PHY_LNAHPFCTL BCM43xx_PHY_OFDM(0x1C) /* LNA/HPF
control */
+#define BCM43xx_PHY_LPFGAINCTL BCM43xx_PHY_OFDM(0x20) /* LPF Gain
control */
#define BCM43xx_PHY_ADIVRELATED BCM43xx_PHY_OFDM(0x27) /*
FIXME rename */
#define BCM43xx_PHY_CRS0 BCM43xx_PHY_OFDM(0x29)
+#define BCM43xx_PHY_CRS0_EN 0x4000
+#define BCM43xx_PHY_PEAK_COUNT BCM43xx_PHY_OFDM(0x30)
#define BCM43xx_PHY_ANTDWELL BCM43xx_PHY_OFDM(0x2B) /* Antenna
dwell */
#define BCM43xx_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX
diversity start antenna */
#define BCM43xx_PHY_ENCORE BCM43xx_PHY_OFDM(0x49) /* "Encore"
(RangeMax / BroadRange) */
@@ -38,6 +41,7 @@ struct bcm43xx_wldev;
#define BCM43xx_PHY_OFDM61 BCM43xx_PHY_OFDM(0x61) /* FIXME rename
*/
#define BCM43xx_PHY_OFDM61_10 0x0010 /* FIXME rename
*/
#define BCM43xx_PHY_IQBAL BCM43xx_PHY_OFDM(0x69) /* I/Q balance
*/
+#define BCM43xx_PHY_BBTXDC_BIAS BCM43xx_PHY_OFDM(0x6B) /*
Baseband TX DC bias */
#define BCM43xx_PHY_OTABLECTL BCM43xx_PHY_OFDM(0x72) /* OFDM table
control (see below) */
#define BCM43xx_PHY_OTABLEOFF 0x03FF /* OFDM table
offset (see below) */
#define BCM43xx_PHY_OTABLENR 0xFC00 /* OFDM table
number (see below) */
@@ -45,6 +49,9 @@ struct bcm43xx_wldev;
#define BCM43xx_PHY_OTABLEI BCM43xx_PHY_OFDM(0x73) /* OFDM table
data I */
#define BCM43xx_PHY_OTABLEQ BCM43xx_PHY_OFDM(0x74) /* OFDM table
data Q */
#define BCM43xx_PHY_HPWR_TSSICTL BCM43xx_PHY_OFDM(0x78) /* Hardware
power TSSI control */
+#define BCM43xx_PHY_ADCCTL BCM43xx_PHY_OFDM(0x7A) /* ADC control
*/
+#define BCM43xx_PHY_IDLE_TSSI BCM43xx_PHY_OFDM(0x7B)
+#define BCM43xx_PHY_A_TEMP_SENSE BCM43xx_PHY_OFDM(0x7C) /* A PHY
temperature sense */
#define BCM43xx_PHY_NRSSITHRES BCM43xx_PHY_OFDM(0x8A) /* NRSSI
threshold */
#define BCM43xx_PHY_ANTWRSETT BCM43xx_PHY_OFDM(0x8C) /* Antenna WR
settle */
#define BCM43xx_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX
diversity enabled */
@@ -55,6 +62,8 @@ struct bcm43xx_wldev;
#define BCM43xx_PHY_N1N2GAIN BCM43xx_PHY_OFDM(0xA2)
#define BCM43xx_PHY_CLIPTHRES BCM43xx_PHY_OFDM(0xA3)
#define BCM43xx_PHY_CLIPN1P2THRES BCM43xx_PHY_OFDM(0xA4)
+#define BCM43xx_PHY_CCKSHIFTBITS_WA BCM43xx_PHY_OFDM(0xA5) /* CCK
shiftbits workaround, FIXME rename */
+#define BCM43xx_PHY_CCKSHIFTBITS BCM43xx_PHY_OFDM(0xA7) /* FIXME rename
*/
#define BCM43xx_PHY_DIVSRCHIDX BCM43xx_PHY_OFDM(0xA8) /* Divider
search gain/index */
#define BCM43xx_PHY_CLIPP2THRES BCM43xx_PHY_OFDM(0xA9)
#define BCM43xx_PHY_CLIPP3THRES BCM43xx_PHY_OFDM(0xAA)
@@ -128,13 +137,14 @@ struct bcm43xx_wldev;
#define BCM43xx_OFDMTAB_DC BCM43xx_OFDMTAB(0x0E, 7)
#define BCM43xx_OFDMTAB_PWRDYN2 BCM43xx_OFDMTAB(0x0E, 12)
#define BCM43xx_OFDMTAB_LNAGAIN BCM43xx_OFDMTAB(0x0E, 13)
-//TODO
+#define BCM43xx_OFDMTAB_UNKNOWN_0F BCM43xx_OFDMTAB(0x0F, 0) //TODO
rename
+#define BCM43xx_OFDMTAB_UNKNOWN_APHY BCM43xx_OFDMTAB(0x0F, 7) //TODO
rename
#define BCM43xx_OFDMTAB_LPFGAIN BCM43xx_OFDMTAB(0x0F, 12)
#define BCM43xx_OFDMTAB_RSSI BCM43xx_OFDMTAB(0x10, 0)
-//TODO
+#define BCM43xx_OFDMTAB_UNKNOWN_11 BCM43xx_OFDMTAB(0x11, 4) //TODO
rename
#define BCM43xx_OFDMTAB_AGC1_R1 BCM43xx_OFDMTAB(0x13, 0)
-#define BCM43xx_OFDMTAB_GAINX_R1 BCM43xx_OFDMTAB(0x14, 0) //TODO
rename
-#define BCM43xx_OFDMTAB_MINSIGSQ BCM43xx_OFDMTAB(0x14, 1)
+#define BCM43xx_OFDMTAB_GAINX_R1 BCM43xx_OFDMTAB(0x14, 0) //TODO
remove!
+#define BCM43xx_OFDMTAB_MINSIGSQ BCM43xx_OFDMTAB(0x14, 0)
#define BCM43xx_OFDMTAB_AGC3_R1 BCM43xx_OFDMTAB(0x15, 0)
#define BCM43xx_OFDMTAB_WRSSI_R1 BCM43xx_OFDMTAB(0x15, 4)
#define BCM43xx_OFDMTAB_TSSI BCM43xx_OFDMTAB(0x15, 0)
Index:
bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_tables.h
===================================================================
---
bu3sch-wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_tables.h
2007-05-24 19:38:54.000000000 +0200
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_tables.h
2007-06-02 17:33:22.000000000 +0200
@@ -17,12 +17,18 @@ extern const u16 bcm43xx_tab_noisea3[];
extern const u16 bcm43xx_tab_noiseg1[];
#define BCM43xx_TAB_NOISEG2_SIZE 8
extern const u16 bcm43xx_tab_noiseg2[];
-#define BCM43xx_TAB_NOISESCALEG_SIZE 27
+#define BCM43xx_TAB_NOISESCALE_SIZE 27
+extern const u16 bcm43xx_tab_noisescalea2[];
+extern const u16 bcm43xx_tab_noisescalea3[];
extern const u16 bcm43xx_tab_noisescaleg1[];
extern const u16 bcm43xx_tab_noisescaleg2[];
extern const u16 bcm43xx_tab_noisescaleg3[];
#define BCM43xx_TAB_SIGMASQR_SIZE 53
extern const u16 bcm43xx_tab_sigmasqr1[];
extern const u16 bcm43xx_tab_sigmasqr2[];
+#define BCM43xx_TAB_RSSIAGC1_SIZE 16
+extern const u16 bcm43xx_tab_rssiagc1[];
+#define BCM43xx_TAB_RSSIAGC2_SIZE 48
+extern const u16 bcm43xx_tab_rssiagc2[];
#endif /* BCM43xx_TABLES_H_ */
Index: bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.c
===================================================================
---
bu3sch-wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.c
2007-06-02 12:24:49.000000000 +0200
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.c
2007-06-02 17:33:22.000000000 +0200
@@ -34,6 +34,7 @@
#include "bcm43xx_tables.h"
#include "bcm43xx_power.h"
#include "bcm43xx_lo.h"
+#include "bcm43xx_wa.h"
static const s8 bcm43xx_tssi2dbm_b_table[] = {
@@ -559,393 +560,96 @@ static void bcm43xx_phy_init_pctl(struct
bcm43xx_shm_clear_tssi(dev);
}
-static void bcm43xx_phy_agcsetup(struct bcm43xx_wldev *dev)
+static void bcm43xx_phy_rssiagc(struct bcm43xx_wldev *dev, u8 enable)
{
- struct bcm43xx_phy *phy = &dev->phy;
- u16 offset = 0x0000;
-
- if (phy->rev == 1)
- offset = 0x4C00;
-
- bcm43xx_ofdmtab_write16(dev, offset, 0, 0x00FE);
- bcm43xx_ofdmtab_write16(dev, offset, 1, 0x000D);
- bcm43xx_ofdmtab_write16(dev, offset, 2, 0x0013);
- bcm43xx_ofdmtab_write16(dev, offset, 3, 0x0019);
-
- if (phy->rev == 1) {
- bcm43xx_ofdmtab_write16(dev, 0x1800, 0, 0x2710);
- bcm43xx_ofdmtab_write16(dev, 0x1801, 0, 0x9B83);
- bcm43xx_ofdmtab_write16(dev, 0x1802, 0, 0x9B83);
- bcm43xx_ofdmtab_write16(dev, 0x1803, 0, 0x0F8D);
- bcm43xx_phy_write(dev, 0x0455, 0x0004);
- }
-
- bcm43xx_phy_write(dev, 0x04A5,
- (bcm43xx_phy_read(dev, 0x04A5)
- & 0x00FF) | 0x5700);
- bcm43xx_phy_write(dev, 0x041A,
- (bcm43xx_phy_read(dev, 0x041A)
- & 0xFF80) | 0x000F);
- bcm43xx_phy_write(dev, 0x041A,
- (bcm43xx_phy_read(dev, 0x041A)
- & 0xC07F) | 0x2B80);
- bcm43xx_phy_write(dev, 0x048C,
- (bcm43xx_phy_read(dev, 0x048C)
- & 0xF0FF) | 0x0300);
-
- bcm43xx_radio_write16(dev, 0x007A,
- bcm43xx_radio_read16(dev, 0x007A)
- | 0x0008);
-
- bcm43xx_phy_write(dev, 0x04A0,
- (bcm43xx_phy_read(dev, 0x04A0)
- & 0xFFF0) | 0x0008);
- bcm43xx_phy_write(dev, 0x04A1,
- (bcm43xx_phy_read(dev, 0x04A1)
- & 0xF0FF) | 0x0600);
- bcm43xx_phy_write(dev, 0x04A2,
- (bcm43xx_phy_read(dev, 0x04A2)
- & 0xF0FF) | 0x0700);
- bcm43xx_phy_write(dev, 0x04A0,
- (bcm43xx_phy_read(dev, 0x04A0)
- & 0xF0FF) | 0x0100);
-
- if (phy->rev == 1) {
- bcm43xx_phy_write(dev, 0x04A2,
- (bcm43xx_phy_read(dev, 0x04A2)
- & 0xFFF0) | 0x0007);
- }
-
- bcm43xx_phy_write(dev, 0x0488,
- (bcm43xx_phy_read(dev, 0x0488)
- & 0xFF00) | 0x001C);
- bcm43xx_phy_write(dev, 0x0488,
- (bcm43xx_phy_read(dev, 0x0488)
- & 0xC0FF) | 0x0200);
- bcm43xx_phy_write(dev, 0x0496,
- (bcm43xx_phy_read(dev, 0x0496)
- & 0xFF00) | 0x001C);
- bcm43xx_phy_write(dev, 0x0489,
- (bcm43xx_phy_read(dev, 0x0489)
- & 0xFF00) | 0x0020);
- bcm43xx_phy_write(dev, 0x0489,
- (bcm43xx_phy_read(dev, 0x0489)
- & 0xC0FF) | 0x0200);
- bcm43xx_phy_write(dev, 0x0482,
- (bcm43xx_phy_read(dev, 0x0482)
- & 0xFF00) | 0x002E);
- bcm43xx_phy_write(dev, 0x0496,
- (bcm43xx_phy_read(dev, 0x0496)
- & 0x00FF) | 0x1A00);
- bcm43xx_phy_write(dev, 0x0481,
- (bcm43xx_phy_read(dev, 0x0481)
- & 0xFF00) | 0x0028);
- bcm43xx_phy_write(dev, 0x0481,
- (bcm43xx_phy_read(dev, 0x0481)
- & 0x00FF) | 0x2C00);
-
- if (phy->rev == 1) {
- bcm43xx_phy_write(dev, 0x0430, 0x092B);
- bcm43xx_phy_write(dev, 0x041B,
- (bcm43xx_phy_read(dev, 0x041B)
- & 0xFFE1) | 0x0002);
- } else {
- bcm43xx_phy_write(dev, 0x041B,
- bcm43xx_phy_read(dev, 0x041B)
- & 0xFFE1);
- bcm43xx_phy_write(dev, 0x041F, 0x287A);
- bcm43xx_phy_write(dev, 0x0420,
- (bcm43xx_phy_read(dev, 0x0420)
- & 0xFFF0) | 0x0004);
- }
-
- if (phy->rev >= 6) {
- bcm43xx_phy_write(dev, 0x0422, 0x287A);
- bcm43xx_phy_write(dev, 0x0420,
- (bcm43xx_phy_read(dev, 0x0420)
- & 0x0FFF) | 0x3000);
- }
-
- bcm43xx_phy_write(dev, 0x04A8,
- (bcm43xx_phy_read(dev, 0x04A8)
- & 0x8080) | 0x7874);
- bcm43xx_phy_write(dev, 0x048E, 0x1C00);
-
- offset = 0x0800;
- if (phy->rev == 1) {
- offset = 0x5400;
- bcm43xx_phy_write(dev, 0x04AB,
- (bcm43xx_phy_read(dev, 0x04AB)
- & 0xF0FF) | 0x0600);
- bcm43xx_phy_write(dev, 0x048B, 0x005E);
- bcm43xx_phy_write(dev, 0x048C,
- (bcm43xx_phy_read(dev, 0x048C)
- & 0xFF00) | 0x001E);
- bcm43xx_phy_write(dev, 0x048D, 0x0002);
- }
- bcm43xx_ofdmtab_write16(dev, offset, 0, 0x00);
- bcm43xx_ofdmtab_write16(dev, offset, 1, 0x07);
- bcm43xx_ofdmtab_write16(dev, offset, 2, 0x10);
- bcm43xx_ofdmtab_write16(dev, offset, 3, 0x1C);
-
- if (phy->rev >= 6) {
- bcm43xx_phy_write(dev, 0x0426,
- bcm43xx_phy_read(dev, 0x0426)
- & 0xFFFC);
- bcm43xx_phy_write(dev, 0x0426,
- bcm43xx_phy_read(dev, 0x0426)
- & 0xEFFF);
- }
-}
-
-static void bcm43xx_phy_setupg(struct bcm43xx_wldev *dev)
-{
- struct ssb_bus *bus = dev->dev->bus;
- struct bcm43xx_phy *phy = &dev->phy;
- u16 i;
-
- assert(phy->type == BCM43xx_PHYTYPE_G);
- if (phy->rev == 1) {
- bcm43xx_phy_write(dev, 0x0406, 0x4F19);
- bcm43xx_phy_write(dev, BCM43xx_PHY_G_CRS,
- (bcm43xx_phy_read(dev, BCM43xx_PHY_G_CRS) &
0xFC3F) | 0x0340);
- bcm43xx_phy_write(dev, 0x042C, 0x005A);
- bcm43xx_phy_write(dev, 0x0427, 0x001A);
-
- for (i = 0; i < BCM43xx_TAB_FINEFREQG_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x5800, i,
bcm43xx_tab_finefreqg[i]);
- for (i = 0; i < BCM43xx_TAB_NOISEG1_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x1800, i,
bcm43xx_tab_noiseg1[i]);
- for (i = 0; i < BCM43xx_TAB_ROTOR_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x2000, i,
bcm43xx_tab_rotor[i]);
- } else {
- /* nrssi values are signed 6-bit values. Not sure why we write
0x7654 here... */
- bcm43xx_nrssi_hw_write(dev, 0xBA98, (s16)0x7654);
-
- if (phy->rev == 2) {
- bcm43xx_phy_write(dev, 0x04C0, 0x1861);
- bcm43xx_phy_write(dev, 0x04C1, 0x0271);
- } else if (phy->rev > 2) {
- bcm43xx_phy_write(dev, 0x04C0, 0x0098);
- bcm43xx_phy_write(dev, 0x04C1, 0x0070);
- bcm43xx_phy_write(dev, 0x04C9, 0x0080);
- }
- bcm43xx_phy_write(dev, 0x042B, bcm43xx_phy_read(dev, 0x042B) |
0x800);
-
- for (i = 0; i < 64; i++)
- bcm43xx_ofdmtab_write16(dev, 0x4000, i, i);
- for (i = 0; i < BCM43xx_TAB_NOISEG2_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x1800, i,
bcm43xx_tab_noiseg2[i]);
- }
-
- if (phy->rev <= 2)
- for (i = 0; i < BCM43xx_TAB_NOISESCALEG_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x1400, i,
bcm43xx_tab_noisescaleg1[i]);
- else if ((phy->rev >= 7) && (bcm43xx_phy_read(dev, 0x0449) & 0x0200))
- for (i = 0; i < BCM43xx_TAB_NOISESCALEG_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x1400, i,
bcm43xx_tab_noisescaleg3[i]);
- else
- for (i = 0; i < BCM43xx_TAB_NOISESCALEG_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x1400, i,
bcm43xx_tab_noisescaleg2[i]);
-
- if (phy->rev == 2)
- for (i = 0; i < BCM43xx_TAB_SIGMASQR_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x5000, i,
bcm43xx_tab_sigmasqr1[i]);
- else if ((phy->rev > 2) && (phy->rev <= 8))
- for (i = 0; i < BCM43xx_TAB_SIGMASQR_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x5000, i,
bcm43xx_tab_sigmasqr2[i]);
-
- if (phy->rev == 1) {
- for (i = 0; i < BCM43xx_TAB_RETARD_SIZE; i++)
- bcm43xx_ofdmtab_write32(dev, 0x2400, i,
bcm43xx_tab_retard[i]);
- for (i = 0; i < 4; i++) {
- bcm43xx_ofdmtab_write16(dev, 0x5404, i, 0x0020);
- bcm43xx_ofdmtab_write16(dev, 0x5408, i, 0x0020);
- bcm43xx_ofdmtab_write16(dev, 0x540C, i, 0x0020);
- bcm43xx_ofdmtab_write16(dev, 0x5410, i, 0x0020);
- }
- bcm43xx_phy_agcsetup(dev);
-
- if ((bus->board_vendor == SSB_BOARDVENDOR_BCM) &&
- (bus->board_type == SSB_BOARD_BU4306) &&
- (bus->board_rev == 0x17))
- return;
-
- bcm43xx_ofdmtab_write16(dev, 0x5001, 0, 0x0002);
- bcm43xx_ofdmtab_write16(dev, 0x5002, 0, 0x0001);
- } else {
- for (i = 0; i <= 0x2F; i++)
- bcm43xx_ofdmtab_write16(dev, 0x1000, i, 0x0820);
- bcm43xx_phy_agcsetup(dev);
- bcm43xx_phy_read(dev, 0x0400); /* dummy read */
- bcm43xx_phy_write(dev, 0x0403, 0x1000);
- bcm43xx_ofdmtab_write16(dev, 0x3C02, 0, 0x000F);
- bcm43xx_ofdmtab_write16(dev, 0x3C03, 0, 0x0014);
-
- if ((bus->board_vendor == SSB_BOARDVENDOR_BCM) &&
- (bus->board_type == SSB_BOARD_BU4306) &&
- (bus->board_rev == 0x17))
- return;
-
- bcm43xx_ofdmtab_write16(dev, 0x0401, 0, 0x0002);
- bcm43xx_ofdmtab_write16(dev, 0x0402, 0, 0x0001);
- }
-}
-
-/* Initialize the noisescaletable for APHY */
-static void bcm43xx_phy_init_noisescaletbl(struct bcm43xx_wldev *dev)
-{
- struct bcm43xx_phy *phy = &dev->phy;
int i;
- for (i = 0; i < 12; i++) {
- if (phy->rev == 2)
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x6767);
+ if (dev->phy.rev < 3) {
+ if (enable)
+ for (i = 0; i < BCM43xx_TAB_RSSIAGC1_SIZE; i++) {
+ bcm43xx_ofdmtab_write16(dev,
+ BCM43xx_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8);
+ bcm43xx_ofdmtab_write16(dev,
+ BCM43xx_OFDMTAB_WRSSI, i, 0xFFF8);
+ }
else
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x2323);
- }
- if (phy->rev == 2)
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x6700);
- else
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x2300);
- for (i = 0; i < 11; i++) {
- if (phy->rev == 2)
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x6767);
+ for (i = 0; i < BCM43xx_TAB_RSSIAGC1_SIZE; i++) {
+ bcm43xx_ofdmtab_write16(dev,
+ BCM43xx_OFDMTAB_LNAHPFGAIN1, i,
bcm43xx_tab_rssiagc1[i]);
+ bcm43xx_ofdmtab_write16(dev,
+ BCM43xx_OFDMTAB_WRSSI, i,
bcm43xx_tab_rssiagc1[i]);
+ }
+ } else {
+ if (enable)
+ for (i = 0; i < BCM43xx_TAB_RSSIAGC1_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
+ BCM43xx_OFDMTAB_WRSSI, i, 0x0820);
else
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x2323);
+ for (i = 0; i < BCM43xx_TAB_RSSIAGC2_SIZE; i++)
+ bcm43xx_ofdmtab_write16(dev,
+ BCM43xx_OFDMTAB_WRSSI, i,
bcm43xx_tab_rssiagc2[i]);
}
- if (phy->rev == 2)
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x0067);
- else
- bcm43xx_ofdmtab_write16(dev, 0x1400, i, 0x0023);
}
-static void bcm43xx_phy_setupa(struct bcm43xx_wldev *dev)
+static void bcm43xx_phy_ww(struct bcm43xx_wldev *dev)
{
- struct bcm43xx_phy *phy = &dev->phy;
- u16 i;
-
- assert(phy->type == BCM43xx_PHYTYPE_A);
- switch (phy->rev) {
- case 2:
- bcm43xx_phy_write(dev, 0x008E, 0x3800);
- bcm43xx_phy_write(dev, 0x0035, 0x03FF);
- bcm43xx_phy_write(dev, 0x0036, 0x0400);
-
- bcm43xx_ofdmtab_write16(dev, 0x3807, 0, 0x0051);
-
- bcm43xx_phy_write(dev, 0x001C, 0x0FF9);
- bcm43xx_phy_write(dev, 0x0020, bcm43xx_phy_read(dev, 0x0020) &
0xFF0F);
- bcm43xx_ofdmtab_write16(dev, 0x3C0C, 0, 0x07BF);
- bcm43xx_radio_write16(dev, 0x0002, 0x07BF);
-
- bcm43xx_phy_write(dev, 0x0024, 0x4680);
- bcm43xx_phy_write(dev, 0x0020, 0x0003);
- bcm43xx_phy_write(dev, 0x001D, 0x0F40);
- bcm43xx_phy_write(dev, 0x001F, 0x1C00);
-
- bcm43xx_phy_write(dev, 0x002A,
- (bcm43xx_phy_read(dev, 0x002A)
- & 0x00FF) | 0x0400);
- bcm43xx_phy_write(dev, 0x002B,
- bcm43xx_phy_read(dev, 0x002B)
- & 0xFBFF);
- bcm43xx_phy_write(dev, 0x008E, 0x58C1);
-
- bcm43xx_ofdmtab_write16(dev, 0x0803, 0, 0x000F);
- bcm43xx_ofdmtab_write16(dev, 0x0804, 0, 0x001F);
- bcm43xx_ofdmtab_write16(dev, 0x0805, 0, 0x002A);
- bcm43xx_ofdmtab_write16(dev, 0x0805, 0, 0x0030);
- bcm43xx_ofdmtab_write16(dev, 0x0807, 0, 0x003A);
-
- bcm43xx_ofdmtab_write16(dev, 0x0000, 0, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0000, 1, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0000, 2, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0000, 3, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0000, 4, 0x0015);
- bcm43xx_ofdmtab_write16(dev, 0x0000, 5, 0x0015);
- bcm43xx_ofdmtab_write16(dev, 0x0000, 6, 0x0019);
-
- bcm43xx_ofdmtab_write16(dev, 0x0404, 0, 0x0003);
- bcm43xx_ofdmtab_write16(dev, 0x0405, 0, 0x0003);
- bcm43xx_ofdmtab_write16(dev, 0x0406, 0, 0x0007);
-
- for (i = 0; i < 16; i++)
- bcm43xx_ofdmtab_write16(dev, 0x4000, i, (0x8 + i) &
0x000F);
-
- bcm43xx_ofdmtab_write16(dev, 0x3003, 0, 0x1044);
- bcm43xx_ofdmtab_write16(dev, 0x3004, 0, 0x7201);
- bcm43xx_ofdmtab_write16(dev, 0x3006, 0, 0x0040);
- bcm43xx_ofdmtab_write16(dev, 0x3001, 0,
(bcm43xx_ofdmtab_read16(dev, 0x3001, 0) & 0x0010) | 0x0008);
-
- for (i = 0; i < BCM43xx_TAB_FINEFREQA_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x5800, i,
bcm43xx_tab_finefreqa[i]);
- for (i = 0; i < BCM43xx_TAB_NOISEA2_SIZE; i++)
- bcm43xx_ofdmtab_write16(dev, 0x1800, i,
bcm43xx_tab_noisea2[i]);
- for (i = 0; i < BCM43xx_TAB_ROTOR_SIZE; i++)
- bcm43xx_ofdmtab_write32(dev, 0x2000, i,
bcm43xx_tab_rotor[i]);
- bcm43xx_phy_init_noisescaletbl(dev);
- for (i = 0; i < BCM43xx_TAB_RETARD_SIZE; i++)
- bcm43xx_ofdmtab_write32(dev, 0x2400, i,
bcm43xx_tab_retard[i]);
- break;
- case 3:
- for (i = 0; i < 64; i++)
- bcm43xx_ofdmtab_write16(dev, 0x4000, i, i);
-
- bcm43xx_ofdmtab_write16(dev, 0x3807, 0, 0x0051);
-
- bcm43xx_phy_write(dev, 0x001C, 0x0FF9);
- bcm43xx_phy_write(dev, 0x0020,
- bcm43xx_phy_read(dev, 0x0020) & 0xFF0F);
- bcm43xx_radio_write16(dev, 0x0002, 0x07BF);
-
- bcm43xx_phy_write(dev, 0x0024, 0x4680);
- bcm43xx_phy_write(dev, 0x0020, 0x0003);
- bcm43xx_phy_write(dev, 0x001D, 0x0F40);
- bcm43xx_phy_write(dev, 0x001F, 0x1C00);
- bcm43xx_phy_write(dev, 0x002A,
- (bcm43xx_phy_read(dev, 0x002A)
- & 0x00FF) | 0x0400);
-
- bcm43xx_ofdmtab_write16(dev, 0x3000, 1,
- (bcm43xx_ofdmtab_read16(dev, 0x3000, 1)
- & 0x0010) | 0x0008);
- for (i = 0; i < BCM43xx_TAB_NOISEA3_SIZE; i++) {
- bcm43xx_ofdmtab_write16(dev, 0x1800, i,
- bcm43xx_tab_noisea3[i]);
- }
- bcm43xx_phy_init_noisescaletbl(dev);
- for (i = 0; i < BCM43xx_TAB_SIGMASQR_SIZE; i++) {
- bcm43xx_ofdmtab_write16(dev, 0x5000, i,
- bcm43xx_tab_sigmasqr1[i]);
- }
-
- bcm43xx_phy_write(dev, 0x0003, 0x1808);
-
- bcm43xx_ofdmtab_write16(dev, 0x0803, 0, 0x000F);
- bcm43xx_ofdmtab_write16(dev, 0x0804, 0, 0x001F);
- bcm43xx_ofdmtab_write16(dev, 0x0805, 0, 0x002A);
- bcm43xx_ofdmtab_write16(dev, 0x0805, 0, 0x0030);
- bcm43xx_ofdmtab_write16(dev, 0x0807, 0, 0x003A);
-
- bcm43xx_ofdmtab_write16(dev, 0x0000, 0, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0001, 0, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0002, 0, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0003, 0, 0x0013);
- bcm43xx_ofdmtab_write16(dev, 0x0004, 0, 0x0015);
- bcm43xx_ofdmtab_write16(dev, 0x0005, 0, 0x0015);
- bcm43xx_ofdmtab_write16(dev, 0x0006, 0, 0x0019);
-
- bcm43xx_ofdmtab_write16(dev, 0x0404, 0, 0x0003);
- bcm43xx_ofdmtab_write16(dev, 0x0405, 0, 0x0003);
- bcm43xx_ofdmtab_write16(dev, 0x0406, 0, 0x0007);
+ u16 b, curr_s, best_s = 0xFFFF;
+ int i;
- bcm43xx_ofdmtab_write16(dev, 0x3C02, 0, 0x000F);
- bcm43xx_ofdmtab_write16(dev, 0x3C03, 0, 0x0014);
- break;
- default:
- assert(0);
- }
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRS0,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_CRS0) & ~BCM43xx_PHY_CRS0_EN);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x1B),
+ bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x1B)) | 0x1000);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x82),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x82)) & 0xF0FF) |
0x0300);
+ bcm43xx_radio_write16(dev, 0x0009,
+ bcm43xx_radio_read16(dev, 0x0009) | 0x0080);
+ bcm43xx_radio_write16(dev, 0x0012,
+ (bcm43xx_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
+ bcm43xx_wa_initgains(dev);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xBA), 0x3ED5);
+ b = bcm43xx_phy_read(dev, BCM43xx_PHY_PWRDOWN);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
+ bcm43xx_radio_write16(dev, 0x0004,
+ bcm43xx_radio_read16(dev, 0x0004) | 0x0004);
+ for (i = 0x10; i <= 0x20; i++) {
+ bcm43xx_radio_write16(dev, 0x0013, i);
+ curr_s = bcm43xx_phy_read(dev, BCM43xx_PHY_OTABLEQ) & 0x00FF;
+ if (!curr_s) {
+ best_s = 0x0000;
+ break;
+ } else if (curr_s >= 0x0080)
+ curr_s = 0x0100 - curr_s;
+ if (curr_s < best_s)
+ best_s = curr_s;
+ }
+ bcm43xx_phy_write(dev, BCM43xx_PHY_PWRDOWN, b);
+ bcm43xx_radio_write16(dev, 0x0004,
+ bcm43xx_radio_read16(dev, 0x0004) & 0xFFFB);
+ bcm43xx_radio_write16(dev, 0x0013, best_s);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1_R1, 0, 0xFFEC);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xB7), 0x1E80);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xB6), 0x1C00);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xB5), 0x0EC0);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xB2), 0x00C0);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xB9), 0x1FFF);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0xBB),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0xBB)) & 0xF000) |
0x0053);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM61,
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM61 & 0xFE1F)) | 0x0120);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x13),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x13)) & 0x0FFF) |
0x3000);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x14),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x14)) & 0x0FFF) |
0x3000);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 6, 0x0017);
+ for (i = 0; i < 6; i++)
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, i, 0x000F);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 0x0D, 0x000E);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 0x0E, 0x0011);
+ bcm43xx_ofdmtab_write16(dev, BCM43xx_OFDMTAB_AGC1, 0x0F, 0x0013);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x33), 0x5030);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRS0,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_CRS0) | BCM43xx_PHY_CRS0_EN);
}
/* Initialize APHY. This is also called for the GPHY in some cases. */
@@ -953,60 +657,52 @@ static void bcm43xx_phy_inita(struct bcm
{
struct ssb_bus *bus = dev->dev->bus;
struct bcm43xx_phy *phy = &dev->phy;
- u16 tval;
- if (phy->type == BCM43xx_PHYTYPE_A) {
- bcm43xx_phy_setupa(dev);
- } else {
- bcm43xx_phy_setupg(dev);
- if (phy->gmode &&
- (dev->dev->bus->sprom.r1.boardflags_lo &
BCM43xx_BFL_PACTRL))
- bcm43xx_phy_write(dev, 0x046E, 0x03CF);
- return;
+ if (phy->rev >= 6) {
+ if (phy->type == BCM43xx_PHYTYPE_A)
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x1B),
+ bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x1B)) &
~0x1000);
+ if (bcm43xx_phy_read(dev, BCM43xx_PHY_ENCORE) &
BCM43xx_PHY_ENCORE_EN)
+ bcm43xx_phy_write(dev, BCM43xx_PHY_ENCORE,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_ENCORE) |
0x0010);
+ else
+ bcm43xx_phy_write(dev, BCM43xx_PHY_ENCORE,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_ENCORE) &
~0x1010);
}
+ bcm43xx_wa_all(dev);
- bcm43xx_phy_write(dev, BCM43xx_PHY_A_CRS,
- (bcm43xx_phy_read(dev, BCM43xx_PHY_A_CRS) & 0xF83C) |
0x0340);
- bcm43xx_phy_write(dev, 0x0034, 0x0001);
-
- TODO();//TODO: RSSI AGC
- bcm43xx_phy_write(dev, BCM43xx_PHY_A_CRS,
- bcm43xx_phy_read(dev, BCM43xx_PHY_A_CRS) | (1 << 14));
- bcm43xx_radio_init2060(dev);
+ if (phy->type == BCM43xx_PHYTYPE_A) {
+ if (phy->gmode &&
+ (phy->rev < 3))
+ bcm43xx_phy_write(dev, 0x0034,
+ bcm43xx_phy_read(dev, 0x0034) | 0x0001);
- if ((bus->board_vendor == SSB_BOARDVENDOR_BCM) &&
- ((bus->board_type == SSB_BOARD_BU4306) ||
- (bus->board_type == SSB_BOARD_BU4309))) {
- if (phy->lofcal == 0xFFFF) {
- TODO();//TODO: LOF Cal
- bcm43xx_radio_set_tx_iq(dev);
- } else
- bcm43xx_radio_write16(dev, 0x001E, phy->lofcal);
- }
+ bcm43xx_phy_rssiagc(dev, 0);
- bcm43xx_phy_write(dev, 0x007A, 0xF111);
+ bcm43xx_phy_write(dev, BCM43xx_PHY_CRS0,
+ bcm43xx_phy_read(dev, BCM43xx_PHY_CRS0) |
BCM43xx_PHY_CRS0_EN);
- if (phy->cur_idle_tssi == 0) {
- bcm43xx_radio_write16(dev, 0x0019, 0x0000);
- bcm43xx_radio_write16(dev, 0x0017, 0x0020);
+ bcm43xx_radio_init2060(dev);
- tval = bcm43xx_ofdmtab_read16(dev, 0x3001, 0);
- if (phy->rev == 1) {
- bcm43xx_ofdmtab_write16(dev, 0x3001, 0,
- (bcm43xx_ofdmtab_read16(dev, 0x3001,
0) & 0xFF87)
- | 0x0058);
- } else {
- bcm43xx_ofdmtab_write16(dev, 0x3001, 0,
- (bcm43xx_ofdmtab_read16(dev, 0x3001,
0) & 0xFFC3)
- | 0x002C);
+ if ((bus->board_vendor == SSB_BOARDVENDOR_BCM) &&
+ ((bus->board_type == SSB_BOARD_BU4306) ||
+ (bus->board_type == SSB_BOARD_BU4309))) {
+ ; //TODO: A PHY LO
}
- bcm43xx_dummy_transmission(dev);
- phy->cur_idle_tssi = bcm43xx_phy_read(dev, BCM43xx_PHY_A_PCTL);
- bcm43xx_ofdmtab_write16(dev, 0x3001, 0, tval);
- bcm43xx_radio_set_txpower_a(dev, 0x0018);
+ if (phy->rev >= 3)
+ bcm43xx_phy_ww(dev);
+
+ hardware_pctl_init_aphy(dev);
+
+ //TODO: radar detection
+ }
+ if ((phy->type == BCM43xx_PHYTYPE_G) &&
+ (dev->dev->bus->sprom.r1.boardflags_lo & BCM43xx_BFL_PACTRL)) {
+ bcm43xx_phy_write(dev, BCM43xx_PHY_OFDM(0x6E),
+ (bcm43xx_phy_read(dev, BCM43xx_PHY_OFDM(0x6E))
+ & 0xE000) | 0x3CF);
}
- bcm43xx_shm_clear_tssi(dev);
}
static void bcm43xx_phy_initb2(struct bcm43xx_wldev *dev)
Index: bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/Makefile
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/Makefile
2007-05-24 19:38:54.000000000 +0200
+++ bu3sch-wireless-dev/drivers/net/wireless/mac80211/bcm43xx/Makefile
2007-06-02 17:33:22.000000000 +0200
@@ -15,4 +15,5 @@ bcm43xx-mac80211-objs := bcm43xx_main.o
bcm43xx_leds.o \
bcm43xx_xmit.o \
bcm43xx_lo.o \
+ bcm43xx_wa.o \
$(bcm43xx-mac80211-obj-y)
--
Greetings Michael.
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev