/*

  Broadcom B43 wireless driver
  IEEE 802.11n PHY support

  Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>

  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 <linux/delay.h>
#include <linux/types.h>

#include "b43.h"
#include "nphy.h"
#include "tables_nphy.h"

#include <linux/delay.h>


void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
{//TODO
}

void b43_nphy_xmitpower(struct b43_wldev *dev)
{//TODO
}

static void b43_chantab_radio_upload(struct b43_wldev *dev,
				     const struct b43_nphy_channeltab_entry *e)
{
	b43_radio_write16(dev, B2055_PLL_REF, e->radio_pll_ref);
	b43_radio_write16(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0);
	b43_radio_write16(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1);
	b43_radio_write16(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail);
	b43_radio_write16(dev, B2055_VCO_CAL1, e->radio_vco_cal1);
	b43_radio_write16(dev, B2055_VCO_CAL2, e->radio_vco_cal2);
	b43_radio_write16(dev, B2055_PLL_LFC1, e->radio_pll_lfc1);
	b43_radio_write16(dev, B2055_PLL_LFR1, e->radio_pll_lfr1);
	b43_radio_write16(dev, B2055_PLL_LFC2, e->radio_pll_lfc2);
	b43_radio_write16(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf);
	b43_radio_write16(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1);
	b43_radio_write16(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2);
	b43_radio_write16(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune);
	b43_radio_write16(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune);
	b43_radio_write16(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1);
	b43_radio_write16(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn);
	b43_radio_write16(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim);
	b43_radio_write16(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune);
	b43_radio_write16(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune);
	b43_radio_write16(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1);
	b43_radio_write16(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn);
	b43_radio_write16(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
}

static void b43_chantab_phy_upload(struct b43_wldev *dev,
				   const struct b43_nphy_channeltab_entry *e)
{
	b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a);
	b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2);
	b43_phy_write(dev, B43_NPHY_BW3, e->phy_bw3);
	b43_phy_write(dev, B43_NPHY_BW4, e->phy_bw4);
	b43_phy_write(dev, B43_NPHY_BW5, e->phy_bw5);
	b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
}

static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
{
	//TODO
}

/* Tune the hardware to a new channel. Don't call this directly.
 * Use b43_radio_selectchannel() */
int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
{
	const struct b43_nphy_channeltab_entry *tabent;

	tabent = b43_nphy_get_chantabent(dev, channel);
	if (!tabent)
		return -ESRCH;

	//FIXME enable/disable band select upper20 in RXCTL
	if (0 /*FIXME 5Ghz*/)
		b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x20);
	else
		b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x50);
	b43_chantab_radio_upload(dev, tabent);
	udelay(50);
	b43_radio_write16(dev, B2055_VCO_CAL10, 5);
	b43_radio_write16(dev, B2055_VCO_CAL10, 45);
	b43_radio_write16(dev, B2055_VCO_CAL10, 65);
	udelay(300);
	if (0 /*FIXME 5Ghz*/)
		b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
	else
		b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
	b43_chantab_phy_upload(dev, tabent);
	b43_nphy_tx_power_fix(dev);

	return 0;
}

static void b43_radio_init2055_pre(struct b43_wldev *dev)
{
	b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
		     ~B43_NPHY_RFCTL_CMD_PORFORCE);
	b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
		    B43_NPHY_RFCTL_CMD_CHIP0PU |
		    B43_NPHY_RFCTL_CMD_OEPORFORCE);
	b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
		    B43_NPHY_RFCTL_CMD_PORFORCE);
}

static void b43_radio_init2055_post(struct b43_wldev *dev)
{
	struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
	struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo);
	int i;
	u16 val;

	b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
	msleep(1);
	if ((sprom->revision != 4) || !(sprom->boardflags_hi & 0x0002)) {
		if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) ||
		    (binfo->type != 0x46D) ||
		    (binfo->rev < 0x41)) {
			b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
			b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
			msleep(1);
		}
	}
	b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0x3F, 0x2C);
	msleep(1);
	b43_radio_write16(dev, B2055_CAL_MISC, 0x3C);
	msleep(1);
	b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE);
	msleep(1);
	b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80);
	msleep(1);
	b43_radio_set(dev, B2055_CAL_MISC, 0x1);
	msleep(1);
	b43_radio_set(dev, B2055_CAL_MISC, 0x40);
	msleep(1);
	for (i = 0; i < 100; i++) {
		val = b43_radio_read16(dev, B2055_CAL_COUT2);
		if (val & 0x80)
			break;
		udelay(10);
	}
	msleep(1);
	b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
	msleep(1);
	b43_radio_selectchannel(dev, dev->phy.channel, 0);
	b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9);
	b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9);
	b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
	b43_radio_write16(dev, B2055_C2_RX_BB_MIDACHP, 0x83);
}

/* Initialize a Broadcom 2055 N-radio */
static void b43_radio_init2055(struct b43_wldev *dev)
{
	b43_radio_init2055_pre(dev);
	if (b43_status(dev) < B43_STAT_INITIALIZED)
		b2055_upload_inittab(dev, 0, 1);
	else
		b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0);
	b43_radio_init2055_post(dev);
}

void b43_nphy_radio_turn_on(struct b43_wldev *dev)
{
	b43_radio_init2055(dev);
}

void b43_nphy_radio_turn_off(struct b43_wldev *dev)
{
	b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
		     ~B43_NPHY_RFCTL_CMD_EN);
}

#define ntab_upload(dev, offset, data) do { \
		unsigned int i;						\
		for (i = 0; i < (offset##_SIZE); i++)			\
			b43_ntab_write(dev, (offset) + i, (data)[i]);	\
	} while (0)

/* Upload the N-PHY tables. */
static void b43_nphy_tables_init(struct b43_wldev *dev)
{
	/* Static tables */
	ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
	ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
	ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
	ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
	ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
	ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
	ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
	ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
	ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
	ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
	ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
	ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
	ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
	ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);

	/* Volatile tables */
	ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
	ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
	ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
	ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
	ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
	ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
	ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
	ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
	ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
	ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
	ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
	ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
}

static void b43_nphy_workarounds(struct b43_wldev *dev)
{
	struct b43_phy *phy = &dev->phy;
	unsigned int i;

	b43_phy_set(dev, B43_NPHY_IQFLIP,
		    B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
	//FIXME the following condition is different in the specs.
	if (1 /* FIXME band is 2.4GHz */) {
		b43_phy_set(dev, B43_NPHY_CLASSCTL,
			    B43_NPHY_CLASSCTL_CCKEN);
	} else {
		b43_phy_mask(dev, B43_NPHY_CLASSCTL,
			     ~B43_NPHY_CLASSCTL_CCKEN);
	}
	b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
	b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8);

	/* Fixup some tables */
	b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA);
	b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA);
	b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
	b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
	b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0);
	b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0);
	b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
	b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
	b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800);
	b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800);

	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);

	//TODO set RF sequence

	/* Set narrowband clip threshold */
	b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66);
	b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66);

	/* Set wideband clip 2 threshold */
	b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
			~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
			21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT);
	b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
			~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
			21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT);

	/* Set Clip 2 detect */
	b43_phy_set(dev, B43_NPHY_C1_CGAINI,
		    B43_NPHY_C1_CGAINI_CL2DETECT);
	b43_phy_set(dev, B43_NPHY_C2_CGAINI,
		    B43_NPHY_C2_CGAINI_CL2DETECT);

	if (0 /*FIXME*/) {
		/* Set dwell lengths */
		b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43);
		b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43);
		b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9);
		b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9);

		/* Set gain backoff */
		b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
				~B43_NPHY_C1_CGAINI_GAINBKOFF,
				1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT);
		b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
				~B43_NPHY_C2_CGAINI_GAINBKOFF,
				1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT);

		/* Set HPVGA2 index */
		b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
				~B43_NPHY_C1_INITGAIN_HPVGA2,
				6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
		b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
				~B43_NPHY_C2_INITGAIN_HPVGA2,
				6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);

		//FIXME verify that the specs really mean to use autoinc here.
		for (i = 0; i < 3; i++)
			b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673);
	}

	/* Set minimum gain value */
	b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN,
			~B43_NPHY_C1_MINGAIN,
			23 << B43_NPHY_C1_MINGAIN_SHIFT);
	b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN,
			~B43_NPHY_C2_MINGAIN,
			23 << B43_NPHY_C2_MINGAIN_SHIFT);

	if (phy->rev < 2) {
		b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
			     ~B43_NPHY_SCRAM_SIGCTL_SCM);
	}

	/* Set phase track alpha and beta */
	b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
	b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
	b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
	b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
	b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
	b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
}

static void b43_nphy_reset_cca(struct b43_wldev *dev)
{
	u16 bbcfg;

	ssb_write32(dev->dev, SSB_TMSLOW,
		    ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC);
	bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
	b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA);
	b43_phy_write(dev, B43_NPHY_BBCFG,
		      bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
	ssb_write32(dev->dev, SSB_TMSLOW,
		    ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC);
}

enum b43_nphy_rf_sequence {
	B43_RFSEQ_RX2TX,
	B43_RFSEQ_TX2RX,
	B43_RFSEQ_RESET2RX,
	B43_RFSEQ_UPDATE_GAINH,
	B43_RFSEQ_UPDATE_GAINL,
	B43_RFSEQ_UPDATE_GAINU,
};

static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
				       enum b43_nphy_rf_sequence seq)
{
	static const u16 trigger[] = {
		[B43_RFSEQ_RX2TX]		= B43_NPHY_RFSEQTR_RX2TX,
		[B43_RFSEQ_TX2RX]		= B43_NPHY_RFSEQTR_TX2RX,
		[B43_RFSEQ_RESET2RX]		= B43_NPHY_RFSEQTR_RST2RX,
		[B43_RFSEQ_UPDATE_GAINH]	= B43_NPHY_RFSEQTR_UPGH,
		[B43_RFSEQ_UPDATE_GAINL]	= B43_NPHY_RFSEQTR_UPGL,
		[B43_RFSEQ_UPDATE_GAINU]	= B43_NPHY_RFSEQTR_UPGU,
	};
	int i;

	B43_WARN_ON(seq >= ARRAY_SIZE(trigger));

	b43_phy_set(dev, B43_NPHY_RFSEQMODE,
		    B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER);
	b43_phy_set(dev, B43_NPHY_RFSEQTR, trigger[seq]);
	for (i = 0; i < 200; i++) {
		if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & trigger[seq]))
			goto ok;
		msleep(1);
	}
	b43err(dev->wl, "RF sequence status timeout\n");
ok:
	b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
		     ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER));
}

static void b43_nphy_bphy_init(struct b43_wldev *dev)
{
	unsigned int i;
	u16 val;

	val = 0x1E1F;
	for (i = 0; i < 14; i++) {
		b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
		val -= 0x202;
	}
	val = 0x3E3F;
	for (i = 0; i < 16; i++) {
		b43_phy_write(dev, B43_PHY_N_BMODE(0x97 + i), val);
		val -= 0x202;
	}
	b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
}

/* RSSI Calibration */
static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type)
{
	//TODO
}

int b43_phy_initn(struct b43_wldev *dev)
{
	struct b43_phy *phy = &dev->phy;
	u16 tmp;

	//TODO: Spectral management
	b43_nphy_tables_init(dev);

	/* Clear all overrides */
	b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0);
	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0);
	b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0);
	b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0);
	b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
		     ~(B43_NPHY_RFSEQMODE_CAOVER |
		       B43_NPHY_RFSEQMODE_TROVER));
	b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0);

	tmp = (phy->rev < 2) ? 64 : 59;
	b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
			~B43_NPHY_BPHY_CTL3_SCALE,
			tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT);

	b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
	b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);

	b43_phy_write(dev, B43_NPHY_TXREALFD, 184);
	b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 200);
	b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 80);
	b43_phy_write(dev, B43_NPHY_C2_BCLIPBKOFF, 511);

	//TODO MIMO-Config
	//TODO Update TX/RX chain

	if (phy->rev < 2) {
		b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
		b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4);
	}
	b43_nphy_workarounds(dev);
	b43_nphy_reset_cca(dev);

	ssb_write32(dev->dev, SSB_TMSLOW,
		    ssb_read32(dev->dev, SSB_TMSLOW) | B43_TMSLOW_MACPHYCLKEN);
	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);

	b43_phy_read(dev, B43_NPHY_CLASSCTL); /* dummy read */
	//TODO read core1/2 clip1 thres regs

	if (1 /* FIXME Band is 2.4GHz */)
		b43_nphy_bphy_init(dev);
	//TODO disable TX power control
	//TODO Fix the TX power settings
	//TODO Init periodic calibration with reason 3
	b43_nphy_rssi_cal(dev, 2);
	b43_nphy_rssi_cal(dev, 0);
	b43_nphy_rssi_cal(dev, 1);
	//TODO get TX gain
	//TODO init superswitch
	//TODO calibrate LO
	//TODO idle TSSI TX pctl
	//TODO TX power control power setup
	//TODO table writes
	//TODO TX power control coefficients
	//TODO enable TX power control
	//TODO control antenna selection
	//TODO init radar detection
	//TODO reset channel if changed

	b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
	return 0;
}
