X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/ee77183476f16696a05a6bf0e34a34e812c7613a..0e9ca337996b5b4ef392bc92cde7f4bc9699b3ea:/package/b43/src/phy.c?ds=inline diff --git a/package/b43/src/phy.c b/package/b43/src/phy.c index 3d4ed647c..305d4cd6f 100644 --- a/package/b43/src/phy.c +++ b/package/b43/src/phy.c @@ -3,7 +3,7 @@ Broadcom B43 wireless driver Copyright (c) 2005 Martin Langer , - Copyright (c) 2005, 2006 Stefano Brivio + Copyright (c) 2005-2007 Stefano Brivio Copyright (c) 2005, 2006 Michael Buesch Copyright (c) 2005, 2006 Danny van Dyk Copyright (c) 2005, 2006 Andreas Jaggi @@ -28,12 +28,16 @@ #include #include #include +#include #include "b43.h" #include "phy.h" +#include "nphy.h" #include "main.h" #include "tables.h" #include "lo.h" +#include "wa.h" + static const s8 b43_tssi2dbm_b_table[] = { 0x4D, 0x4C, 0x4B, 0x4A, @@ -80,25 +84,9 @@ const u8 b43_radio_channel_codes_bg[] = { 72, 84, }; +#define bitrev4(tmp) (bitrev8(tmp) >> 4) static void b43_phy_initg(struct b43_wldev *dev); -/* Reverse the bits of a 4bit value. - * Example: 1101 is flipped 1011 - */ -static u16 flip_4bit(u16 value) -{ - u16 flipped = 0x0000; - - B43_WARN_ON(value & ~0x000F); - - flipped |= (value & 0x0001) << 3; - flipped |= (value & 0x0002) << 1; - flipped |= (value & 0x0004) >> 1; - flipped |= (value & 0x0008) >> 3; - - return flipped; -} - static void generate_rfatt_list(struct b43_wldev *dev, struct b43_rfatt_list *list) { @@ -142,8 +130,7 @@ static void generate_rfatt_list(struct b43_wldev *dev, {.att = 9,.with_padmix = 1,}, }; - if ((phy->type == B43_PHYTYPE_A && phy->rev < 5) || - (phy->type == B43_PHYTYPE_G && phy->rev < 6)) { + if (!b43_has_hardware_pctl(phy)) { /* Software pctl */ list->list = rfatt_0; list->len = ARRAY_SIZE(rfatt_0); @@ -155,7 +142,7 @@ static void generate_rfatt_list(struct b43_wldev *dev, /* Hardware pctl */ list->list = rfatt_1; list->len = ARRAY_SIZE(rfatt_1); - list->min_val = 2; + list->min_val = 0; list->max_val = 14; return; } @@ -225,42 +212,30 @@ static void b43_shm_clear_tssi(struct b43_wldev *dev) } } -void b43_raw_phy_lock(struct b43_wldev *dev) +/* Lock the PHY registers against concurrent access from the microcode. + * This lock is nonrecursive. */ +void b43_phy_lock(struct b43_wldev *dev) { - struct b43_phy *phy = &dev->phy; - - B43_WARN_ON(!irqs_disabled()); - - /* We had a check for MACCTL==0 here, but I think that doesn't - * make sense, as MACCTL is never 0 when this is called. - * --mb */ - B43_WARN_ON(b43_read32(dev, B43_MMIO_MACCTL) == 0); +#if B43_DEBUG + B43_WARN_ON(dev->phy.phy_locked); + dev->phy.phy_locked = 1; +#endif + B43_WARN_ON(dev->dev->id.revision < 3); - if (dev->dev->id.revision < 3) { - b43_mac_suspend(dev); - spin_lock(&phy->lock); - } else { - if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP)) - b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); - } - phy->locked = 1; + if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP)) + b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); } -void b43_raw_phy_unlock(struct b43_wldev *dev) +void b43_phy_unlock(struct b43_wldev *dev) { - struct b43_phy *phy = &dev->phy; +#if B43_DEBUG + B43_WARN_ON(!dev->phy.phy_locked); + dev->phy.phy_locked = 0; +#endif + B43_WARN_ON(dev->dev->id.revision < 3); - B43_WARN_ON(!irqs_disabled()); - if (dev->dev->id.revision < 3) { - if (phy->locked) { - spin_unlock(&phy->lock); - b43_mac_enable(dev); - } - } else { - if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP)) - b43_power_saving_ctl_bits(dev, 0); - } - phy->locked = 0; + if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP)) + b43_power_saving_ctl_bits(dev, 0); } /* Different PHYs require different register routing flags. @@ -271,15 +246,30 @@ static inline u16 adjust_phyreg_for_phytype(struct b43_phy *phy, { if (phy->type == B43_PHYTYPE_A) { /* OFDM registers are base-registers for the A-PHY. */ - offset &= ~B43_PHYROUTE_OFDM_GPHY; + if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) { + offset &= ~B43_PHYROUTE; + offset |= B43_PHYROUTE_BASE; + } } - if (offset & B43_PHYROUTE_EXT_GPHY) { + +#if B43_DEBUG + if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) { /* Ext-G registers are only available on G-PHYs */ if (phy->type != B43_PHYTYPE_G) { - b43dbg(dev->wl, "EXT-G PHY access at " - "0x%04X on %u type PHY\n", offset, phy->type); + b43err(dev->wl, "Invalid EXT-G PHY access at " + "0x%04X on PHY type %u\n", offset, phy->type); + dump_stack(); } } + if ((offset & B43_PHYROUTE) == B43_PHYROUTE_N_BMODE) { + /* N-BMODE registers are only available on N-PHYs */ + if (phy->type != B43_PHYTYPE_N) { + b43err(dev->wl, "Invalid N-BMODE PHY access at " + "0x%04X on PHY type %u\n", offset, phy->type); + dump_stack(); + } + } +#endif /* B43_DEBUG */ return offset; } @@ -299,11 +289,26 @@ void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val) offset = adjust_phyreg_for_phytype(phy, offset, dev); b43_write16(dev, B43_MMIO_PHY_CONTROL, offset); - mmiowb(); b43_write16(dev, B43_MMIO_PHY_DATA, val); } -static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower); +void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask) +{ + b43_phy_write(dev, offset, + b43_phy_read(dev, offset) & mask); +} + +void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set) +{ + b43_phy_write(dev, offset, + b43_phy_read(dev, offset) | set); +} + +void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set) +{ + b43_phy_write(dev, offset, + (b43_phy_read(dev, offset) & mask) | set); +} /* Adjust the transmission power output (G-PHY) */ void b43_set_txpower_g(struct b43_wldev *dev, @@ -325,6 +330,7 @@ void b43_set_txpower_g(struct b43_wldev *dev, /* Save the values for later */ phy->tx_control = tx_control; memcpy(&phy->rfatt, rfatt, sizeof(*rfatt)); + phy->rfatt.with_padmix = !!(tx_control & B43_TXCTL_TXMIX); memcpy(&phy->bbatt, bbatt, sizeof(*bbatt)); if (b43_debug(dev, B43_DBG_XMITPOWER)) { @@ -538,11 +544,6 @@ static void b43_gphy_gain_lt_init(struct b43_wldev *dev) u16 tmp; u8 rf, bb; - if (!lo->lo_measured) { - b43_phy_write(dev, 0x3FF, 0); - return; - } - for (rf = 0; rf < lo->rfatt_list.len; rf++) { for (bb = 0; bb < lo->bbatt_list.len; bb++) { if (nr_written >= 0x40) @@ -560,42 +561,6 @@ static void b43_gphy_gain_lt_init(struct b43_wldev *dev) } } -/* GPHY_DC_Lookup_Table */ -void b43_gphy_dc_lt_init(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - struct b43_txpower_lo_control *lo = phy->lo_control; - struct b43_loctl *loctl0; - struct b43_loctl *loctl1; - int i; - int rf_offset, bb_offset; - u16 tmp; - - for (i = 0; i < lo->rfatt_list.len + lo->bbatt_list.len; i += 2) { - rf_offset = i / lo->rfatt_list.len; - bb_offset = i % lo->rfatt_list.len; - - loctl0 = b43_get_lo_g_ctl(dev, &lo->rfatt_list.list[rf_offset], - &lo->bbatt_list.list[bb_offset]); - if (i + 1 < lo->rfatt_list.len * lo->bbatt_list.len) { - rf_offset = (i + 1) / lo->rfatt_list.len; - bb_offset = (i + 1) % lo->rfatt_list.len; - - loctl1 = - b43_get_lo_g_ctl(dev, - &lo->rfatt_list.list[rf_offset], - &lo->bbatt_list.list[bb_offset]); - } else - loctl1 = loctl0; - - tmp = ((u16) loctl0->q & 0xF); - tmp |= ((u16) loctl0->i & 0xF) << 4; - tmp |= ((u16) loctl1->q & 0xF) << 8; - tmp |= ((u16) loctl1->i & 0xF) << 12; //FIXME? - b43_phy_write(dev, 0x3A0 + (i / 2), tmp); - } -} - static void hardware_pctl_init_aphy(struct b43_wldev *dev) { //TODO @@ -622,7 +587,7 @@ static void hardware_pctl_init_gphy(struct b43_wldev *dev) b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) & 0xFFBF); - b43_gphy_dc_lt_init(dev); + b43_gphy_dc_lt_init(dev, 1); } /* HardwarePowerControl init for A and G PHY */ @@ -763,366 +728,96 @@ static void b43_phy_init_pctl(struct b43_wldev *dev) b43_shm_clear_tssi(dev); } -static void b43_phy_agcsetup(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - u16 offset = 0x0000; - - if (phy->rev == 1) - offset = 0x4C00; - - b43_ofdmtab_write16(dev, offset, 0, 0x00FE); - b43_ofdmtab_write16(dev, offset, 1, 0x000D); - b43_ofdmtab_write16(dev, offset, 2, 0x0013); - b43_ofdmtab_write16(dev, offset, 3, 0x0019); - - if (phy->rev == 1) { - b43_ofdmtab_write16(dev, 0x1800, 0, 0x2710); - b43_ofdmtab_write16(dev, 0x1801, 0, 0x9B83); - b43_ofdmtab_write16(dev, 0x1802, 0, 0x9B83); - b43_ofdmtab_write16(dev, 0x1803, 0, 0x0F8D); - b43_phy_write(dev, 0x0455, 0x0004); - } - - b43_phy_write(dev, 0x04A5, (b43_phy_read(dev, 0x04A5) - & 0x00FF) | 0x5700); - b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A) - & 0xFF80) | 0x000F); - b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A) - & 0xC07F) | 0x2B80); - b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C) - & 0xF0FF) | 0x0300); - - b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) - | 0x0008); - - b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0) - & 0xFFF0) | 0x0008); - b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1) - & 0xF0FF) | 0x0600); - b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2) - & 0xF0FF) | 0x0700); - b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0) - & 0xF0FF) | 0x0100); - - if (phy->rev == 1) { - b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2) - & 0xFFF0) | 0x0007); - } - - b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488) - & 0xFF00) | 0x001C); - b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488) - & 0xC0FF) | 0x0200); - b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496) - & 0xFF00) | 0x001C); - b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489) - & 0xFF00) | 0x0020); - b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489) - & 0xC0FF) | 0x0200); - b43_phy_write(dev, 0x0482, (b43_phy_read(dev, 0x0482) - & 0xFF00) | 0x002E); - b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496) - & 0x00FF) | 0x1A00); - b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481) - & 0xFF00) | 0x0028); - b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481) - & 0x00FF) | 0x2C00); - - if (phy->rev == 1) { - b43_phy_write(dev, 0x0430, 0x092B); - b43_phy_write(dev, 0x041B, (b43_phy_read(dev, 0x041B) - & 0xFFE1) | 0x0002); - } else { - b43_phy_write(dev, 0x041B, b43_phy_read(dev, 0x041B) - & 0xFFE1); - b43_phy_write(dev, 0x041F, 0x287A); - b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420) - & 0xFFF0) | 0x0004); - } - - if (phy->rev >= 6) { - b43_phy_write(dev, 0x0422, 0x287A); - b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420) - & 0x0FFF) | 0x3000); - } - - b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8) - & 0x8080) | 0x7874); - b43_phy_write(dev, 0x048E, 0x1C00); - - offset = 0x0800; - if (phy->rev == 1) { - offset = 0x5400; - b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB) - & 0xF0FF) | 0x0600); - b43_phy_write(dev, 0x048B, 0x005E); - b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C) - & 0xFF00) | 0x001E); - b43_phy_write(dev, 0x048D, 0x0002); - } - b43_ofdmtab_write16(dev, offset, 0, 0x00); - b43_ofdmtab_write16(dev, offset, 1, 0x07); - b43_ofdmtab_write16(dev, offset, 2, 0x10); - b43_ofdmtab_write16(dev, offset, 3, 0x1C); - - if (phy->rev >= 6) { - b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426) - & 0xFFFC); - b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426) - & 0xEFFF); - } -} - -static void b43_phy_setupg(struct b43_wldev *dev) +static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable) { - struct ssb_bus *bus = dev->dev->bus; - struct b43_phy *phy = &dev->phy; - u16 i; - - B43_WARN_ON(phy->type != B43_PHYTYPE_G); - if (phy->rev == 1) { - b43_phy_write(dev, 0x0406, 0x4F19); - b43_phy_write(dev, B43_PHY_G_CRS, - (b43_phy_read(dev, B43_PHY_G_CRS) & 0xFC3F) | - 0x0340); - b43_phy_write(dev, 0x042C, 0x005A); - b43_phy_write(dev, 0x0427, 0x001A); - - for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5800, i, - b43_tab_finefreqg[i]); - for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg1[i]); - for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) - b43_ofdmtab_write16(dev, 0x2000, i, b43_tab_rotor[i]); - } else { - /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */ - b43_nrssi_hw_write(dev, 0xBA98, (s16) 0x7654); - - if (phy->rev == 2) { - b43_phy_write(dev, 0x04C0, 0x1861); - b43_phy_write(dev, 0x04C1, 0x0271); - } else if (phy->rev > 2) { - b43_phy_write(dev, 0x04C0, 0x0098); - b43_phy_write(dev, 0x04C1, 0x0070); - b43_phy_write(dev, 0x04C9, 0x0080); - } - b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x800); - - for (i = 0; i < 64; i++) - b43_ofdmtab_write16(dev, 0x4000, i, i); - for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg2[i]); - } - - if (phy->rev <= 2) - for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1400, i, - b43_tab_noisescaleg1[i]); - else if ((phy->rev >= 7) && (b43_phy_read(dev, 0x0449) & 0x0200)) - for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1400, i, - b43_tab_noisescaleg3[i]); - else - for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1400, i, - b43_tab_noisescaleg2[i]); - - if (phy->rev == 2) - for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5000, i, - b43_tab_sigmasqr1[i]); - else if ((phy->rev > 2) && (phy->rev <= 8)) - for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5000, i, - b43_tab_sigmasqr2[i]); - - if (phy->rev == 1) { - for (i = 0; i < B43_TAB_RETARD_SIZE; i++) - b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]); - for (i = 4; i < 20; i++) - b43_ofdmtab_write16(dev, 0x5400, i, 0x0020); - b43_phy_agcsetup(dev); - - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type == SSB_BOARD_BU4306) && - (bus->boardinfo.rev == 0x17)) - return; - - b43_ofdmtab_write16(dev, 0x5001, 0, 0x0002); - b43_ofdmtab_write16(dev, 0x5002, 0, 0x0001); - } else { - for (i = 0; i < 0x20; i++) - b43_ofdmtab_write16(dev, 0x1000, i, 0x0820); - b43_phy_agcsetup(dev); - b43_phy_read(dev, 0x0400); /* dummy read */ - b43_phy_write(dev, 0x0403, 0x1000); - b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014); - - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type == SSB_BOARD_BU4306) && - (bus->boardinfo.rev == 0x17)) - return; - - b43_ofdmtab_write16(dev, 0x0401, 0, 0x0002); - b43_ofdmtab_write16(dev, 0x0402, 0, 0x0001); - } -} - -/* Initialize the noisescaletable for APHY */ -static void b43_phy_init_noisescaletbl(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; int i; - for (i = 0; i < 12; i++) { - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x6767); + if (dev->phy.rev < 3) { + if (enable) + for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) { + b43_ofdmtab_write16(dev, + B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8); + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, 0xFFF8); + } else - b43_ofdmtab_write16(dev, 0x1400, i, 0x2323); - } - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x6700); - else - b43_ofdmtab_write16(dev, 0x1400, i, 0x2300); - for (i = 0; i < 11; i++) { - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x6767); + for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) { + b43_ofdmtab_write16(dev, + B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]); + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]); + } + } else { + if (enable) + for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, 0x0820); else - b43_ofdmtab_write16(dev, 0x1400, i, 0x2323); + for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++) + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]); } - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x0067); - else - b43_ofdmtab_write16(dev, 0x1400, i, 0x0023); } -static void b43_phy_setupa(struct b43_wldev *dev) +static void b43_phy_ww(struct b43_wldev *dev) { - struct b43_phy *phy = &dev->phy; - u16 i; - - B43_WARN_ON(phy->type != B43_PHYTYPE_A); - switch (phy->rev) { - case 2: - b43_phy_write(dev, 0x008E, 0x3800); - b43_phy_write(dev, 0x0035, 0x03FF); - b43_phy_write(dev, 0x0036, 0x0400); - - b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051); - - b43_phy_write(dev, 0x001C, 0x0FF9); - b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F); - b43_ofdmtab_write16(dev, 0x3C0C, 0, 0x07BF); - b43_radio_write16(dev, 0x0002, 0x07BF); - - b43_phy_write(dev, 0x0024, 0x4680); - b43_phy_write(dev, 0x0020, 0x0003); - b43_phy_write(dev, 0x001D, 0x0F40); - b43_phy_write(dev, 0x001F, 0x1C00); - - b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A) - & 0x00FF) | 0x0400); - b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) - & 0xFBFF); - b43_phy_write(dev, 0x008E, 0x58C1); - - b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030); - b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A); - - b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 1, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 2, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 3, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 4, 0x0015); - b43_ofdmtab_write16(dev, 0x0000, 5, 0x0015); - b43_ofdmtab_write16(dev, 0x0000, 6, 0x0019); - - b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007); - - for (i = 0; i < 16; i++) - b43_ofdmtab_write16(dev, 0x4000, i, (0x8 + i) & 0x000F); - - b43_ofdmtab_write16(dev, 0x3003, 0, 0x1044); - b43_ofdmtab_write16(dev, 0x3004, 0, 0x7201); - b43_ofdmtab_write16(dev, 0x3006, 0, 0x0040); - b43_ofdmtab_write16(dev, 0x3001, 0, - (b43_ofdmtab_read16(dev, 0x3001, 0) & - 0x0010) | 0x0008); - - for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5800, i, - b43_tab_finefreqa[i]); - for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea2[i]); - for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) - b43_ofdmtab_write32(dev, 0x2000, i, b43_tab_rotor[i]); - b43_phy_init_noisescaletbl(dev); - for (i = 0; i < B43_TAB_RETARD_SIZE; i++) - b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]); - break; - case 3: - for (i = 0; i < 64; i++) - b43_ofdmtab_write16(dev, 0x4000, i, i); - - b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051); - - b43_phy_write(dev, 0x001C, 0x0FF9); - b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F); - b43_radio_write16(dev, 0x0002, 0x07BF); - - b43_phy_write(dev, 0x0024, 0x4680); - b43_phy_write(dev, 0x0020, 0x0003); - b43_phy_write(dev, 0x001D, 0x0F40); - b43_phy_write(dev, 0x001F, 0x1C00); - b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A) - & 0x00FF) | 0x0400); - - b43_ofdmtab_write16(dev, 0x3000, 1, - (b43_ofdmtab_read16(dev, 0x3000, 1) - & 0x0010) | 0x0008); - for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) { - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea3[i]); - } - b43_phy_init_noisescaletbl(dev); - for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) { - b43_ofdmtab_write16(dev, 0x5000, i, - b43_tab_sigmasqr1[i]); - } - - b43_phy_write(dev, 0x0003, 0x1808); - - b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030); - b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A); - - b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0001, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0002, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0003, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0004, 0, 0x0015); - b43_ofdmtab_write16(dev, 0x0005, 0, 0x0015); - b43_ofdmtab_write16(dev, 0x0006, 0, 0x0019); - - b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007); + u16 b, curr_s, best_s = 0xFFFF; + int i; - b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014); - break; - default: - B43_WARN_ON(1); - } + b43_phy_write(dev, B43_PHY_CRS0, + b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN); + b43_phy_write(dev, B43_PHY_OFDM(0x1B), + b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000); + b43_phy_write(dev, B43_PHY_OFDM(0x82), + (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300); + b43_radio_write16(dev, 0x0009, + b43_radio_read16(dev, 0x0009) | 0x0080); + b43_radio_write16(dev, 0x0012, + (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002); + b43_wa_initgains(dev); + b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5); + b = b43_phy_read(dev, B43_PHY_PWRDOWN); + b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005); + b43_radio_write16(dev, 0x0004, + b43_radio_read16(dev, 0x0004) | 0x0004); + for (i = 0x10; i <= 0x20; i++) { + b43_radio_write16(dev, 0x0013, i); + curr_s = b43_phy_read(dev, B43_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; + } + b43_phy_write(dev, B43_PHY_PWRDOWN, b); + b43_radio_write16(dev, 0x0004, + b43_radio_read16(dev, 0x0004) & 0xFFFB); + b43_radio_write16(dev, 0x0013, best_s); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC); + b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80); + b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00); + b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0); + b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0); + b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF); + b43_phy_write(dev, B43_PHY_OFDM(0xBB), + (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053); + b43_phy_write(dev, B43_PHY_OFDM61, + (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120); + b43_phy_write(dev, B43_PHY_OFDM(0x13), + (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000); + b43_phy_write(dev, B43_PHY_OFDM(0x14), + (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017); + for (i = 0; i < 6; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013); + b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030); + b43_phy_write(dev, B43_PHY_CRS0, + b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); } /* Initialize APHY. This is also called for the GPHY in some cases. */ @@ -1130,167 +825,54 @@ static void b43_phy_inita(struct b43_wldev *dev) { struct ssb_bus *bus = dev->dev->bus; struct b43_phy *phy = &dev->phy; - u16 tval; might_sleep(); - if (phy->type == B43_PHYTYPE_A) { - b43_phy_setupa(dev); - } else { - b43_phy_setupg(dev); - if (phy->gmode && - (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL)) - b43_phy_write(dev, 0x046E, 0x03CF); - return; + if (phy->rev >= 6) { + if (phy->type == B43_PHYTYPE_A) + b43_phy_write(dev, B43_PHY_OFDM(0x1B), + b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000); + if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) + b43_phy_write(dev, B43_PHY_ENCORE, + b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010); + else + b43_phy_write(dev, B43_PHY_ENCORE, + b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010); } - b43_phy_write(dev, B43_PHY_A_CRS, - (b43_phy_read(dev, B43_PHY_A_CRS) & 0xF83C) | 0x0340); - b43_phy_write(dev, 0x0034, 0x0001); + b43_wa_all(dev); - //TODO: RSSI AGC - b43_phy_write(dev, B43_PHY_A_CRS, - b43_phy_read(dev, B43_PHY_A_CRS) | (1 << 14)); - b43_radio_init2060(dev); + if (phy->type == B43_PHYTYPE_A) { + if (phy->gmode && (phy->rev < 3)) + b43_phy_write(dev, 0x0034, + b43_phy_read(dev, 0x0034) | 0x0001); + b43_phy_rssiagc(dev, 0); - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - ((bus->boardinfo.type == SSB_BOARD_BU4306) || - (bus->boardinfo.type == SSB_BOARD_BU4309))) { - if (phy->lofcal == 0xFFFF) { - //TODO: LOF Cal - b43_radio_set_tx_iq(dev); - } else - b43_radio_write16(dev, 0x001E, phy->lofcal); - } + b43_phy_write(dev, B43_PHY_CRS0, + b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); - b43_phy_write(dev, 0x007A, 0xF111); + b43_radio_init2060(dev); - if (phy->cur_idle_tssi == 0) { - b43_radio_write16(dev, 0x0019, 0x0000); - b43_radio_write16(dev, 0x0017, 0x0020); - - tval = b43_ofdmtab_read16(dev, 0x3001, 0); - if (phy->rev == 1) { - b43_ofdmtab_write16(dev, 0x3001, 0, - (b43_ofdmtab_read16(dev, 0x3001, 0) - & 0xFF87) - | 0x0058); - } else { - b43_ofdmtab_write16(dev, 0x3001, 0, - (b43_ofdmtab_read16(dev, 0x3001, 0) - & 0xFFC3) - | 0x002C); + if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && + ((bus->boardinfo.type == SSB_BOARD_BU4306) || + (bus->boardinfo.type == SSB_BOARD_BU4309))) { + ; //TODO: A PHY LO } - b43_dummy_transmission(dev); - phy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_A_PCTL); - b43_ofdmtab_write16(dev, 0x3001, 0, tval); - - b43_radio_set_txpower_a(dev, 0x0018); - } - b43_shm_clear_tssi(dev); -} - -static void b43_phy_initb2(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - u16 offset, val; - b43_write16(dev, 0x03EC, 0x3F22); - b43_phy_write(dev, 0x0020, 0x301C); - b43_phy_write(dev, 0x0026, 0x0000); - b43_phy_write(dev, 0x0030, 0x00C6); - b43_phy_write(dev, 0x0088, 0x3E00); - val = 0x3C3D; - for (offset = 0x0089; offset < 0x00A7; offset++) { - b43_phy_write(dev, offset, val); - val -= 0x0202; - } - b43_phy_write(dev, 0x03E4, 0x3000); - b43_radio_selectchannel(dev, phy->channel, 0); - if (phy->radio_ver != 0x2050) { - b43_radio_write16(dev, 0x0075, 0x0080); - b43_radio_write16(dev, 0x0079, 0x0081); - } - b43_radio_write16(dev, 0x0050, 0x0020); - b43_radio_write16(dev, 0x0050, 0x0023); - if (phy->radio_ver == 0x2050) { - b43_radio_write16(dev, 0x0050, 0x0020); - b43_radio_write16(dev, 0x005A, 0x0070); - b43_radio_write16(dev, 0x005B, 0x007B); - b43_radio_write16(dev, 0x005C, 0x00B0); - b43_radio_write16(dev, 0x007A, 0x000F); - b43_phy_write(dev, 0x0038, 0x0677); - b43_radio_init2050(dev); - } - b43_phy_write(dev, 0x0014, 0x0080); - b43_phy_write(dev, 0x0032, 0x00CA); - b43_phy_write(dev, 0x0032, 0x00CC); - b43_phy_write(dev, 0x0035, 0x07C2); - b43_lo_b_measure(dev); - b43_phy_write(dev, 0x0026, 0xCC00); - if (phy->radio_ver != 0x2050) - b43_phy_write(dev, 0x0026, 0xCE00); - b43_write16(dev, B43_MMIO_CHANNEL_EXT, 0x1000); - b43_phy_write(dev, 0x002A, 0x88A3); - if (phy->radio_ver != 0x2050) - b43_phy_write(dev, 0x002A, 0x88C2); - b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control); - b43_phy_init_pctl(dev); -} + if (phy->rev >= 3) + b43_phy_ww(dev); -static void b43_phy_initb4(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - u16 offset, val; + hardware_pctl_init_aphy(dev); - b43_write16(dev, 0x03EC, 0x3F22); - b43_phy_write(dev, 0x0020, 0x301C); - b43_phy_write(dev, 0x0026, 0x0000); - b43_phy_write(dev, 0x0030, 0x00C6); - b43_phy_write(dev, 0x0088, 0x3E00); - val = 0x3C3D; - for (offset = 0x0089; offset < 0x00A7; offset++) { - b43_phy_write(dev, offset, val); - val -= 0x0202; + //TODO: radar detection } - b43_phy_write(dev, 0x03E4, 0x3000); - b43_radio_selectchannel(dev, phy->channel, 0); - if (phy->radio_ver != 0x2050) { - b43_radio_write16(dev, 0x0075, 0x0080); - b43_radio_write16(dev, 0x0079, 0x0081); - } - b43_radio_write16(dev, 0x0050, 0x0020); - b43_radio_write16(dev, 0x0050, 0x0023); - if (phy->radio_ver == 0x2050) { - b43_radio_write16(dev, 0x0050, 0x0020); - b43_radio_write16(dev, 0x005A, 0x0070); - b43_radio_write16(dev, 0x005B, 0x007B); - b43_radio_write16(dev, 0x005C, 0x00B0); - b43_radio_write16(dev, 0x007A, 0x000F); - b43_phy_write(dev, 0x0038, 0x0677); - b43_radio_init2050(dev); - } - b43_phy_write(dev, 0x0014, 0x0080); - b43_phy_write(dev, 0x0032, 0x00CA); - if (phy->radio_ver == 0x2050) - b43_phy_write(dev, 0x0032, 0x00E0); - b43_phy_write(dev, 0x0035, 0x07C2); - - b43_lo_b_measure(dev); - b43_phy_write(dev, 0x0026, 0xCC00); - if (phy->radio_ver == 0x2050) - b43_phy_write(dev, 0x0026, 0xCE00); - b43_write16(dev, B43_MMIO_CHANNEL_EXT, 0x1100); - b43_phy_write(dev, 0x002A, 0x88A3); - if (phy->radio_ver == 0x2050) - b43_phy_write(dev, 0x002A, 0x88C2); - b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) { - b43_calc_nrssi_slope(dev); - b43_calc_nrssi_threshold(dev); + if ((phy->type == B43_PHYTYPE_G) && + (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { + b43_phy_write(dev, B43_PHY_OFDM(0x6E), + (b43_phy_read(dev, B43_PHY_OFDM(0x6E)) + & 0xE000) | 0x3CF); } - b43_phy_init_pctl(dev); } static void b43_phy_initb5(struct b43_wldev *dev) @@ -1433,7 +1015,7 @@ static void b43_phy_initb6(struct b43_wldev *dev) b43_radio_write16(dev, 0x5A, 0x88); b43_radio_write16(dev, 0x5B, 0x6B); b43_radio_write16(dev, 0x5C, 0x0F); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_ALTIQ) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { b43_radio_write16(dev, 0x5D, 0xFA); b43_radio_write16(dev, 0x5E, 0xD8); } else { @@ -1518,19 +1100,9 @@ static void b43_phy_initb6(struct b43_wldev *dev) b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0) | 0x0004); } - if (phy->type == B43_PHYTYPE_B) { - b43_write16(dev, 0x03E6, 0x8140); - b43_phy_write(dev, 0x0016, 0x0410); - b43_phy_write(dev, 0x0017, 0x0820); - b43_phy_write(dev, 0x0062, 0x0007); - b43_radio_init2050(dev); - b43_lo_g_measure(dev); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) { - b43_calc_nrssi_slope(dev); - b43_calc_nrssi_threshold(dev); - } - b43_phy_init_pctl(dev); - } else if (phy->type == B43_PHYTYPE_G) + if (phy->type == B43_PHYTYPE_B) + B43_WARN_ON(1); + else if (phy->type == B43_PHYTYPE_G) b43_write16(dev, 0x03E6, 0x0); } @@ -1552,14 +1124,14 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) backup_phy[4] = b43_phy_read(dev, B43_PHY_ANALOGOVER); backup_phy[5] = b43_phy_read(dev, B43_PHY_ANALOGOVERVAL); } - backup_phy[6] = b43_phy_read(dev, B43_PHY_BASE(0x5A)); - backup_phy[7] = b43_phy_read(dev, B43_PHY_BASE(0x59)); - backup_phy[8] = b43_phy_read(dev, B43_PHY_BASE(0x58)); - backup_phy[9] = b43_phy_read(dev, B43_PHY_BASE(0x0A)); - backup_phy[10] = b43_phy_read(dev, B43_PHY_BASE(0x03)); + backup_phy[6] = b43_phy_read(dev, B43_PHY_CCK(0x5A)); + backup_phy[7] = b43_phy_read(dev, B43_PHY_CCK(0x59)); + backup_phy[8] = b43_phy_read(dev, B43_PHY_CCK(0x58)); + backup_phy[9] = b43_phy_read(dev, B43_PHY_CCK(0x0A)); + backup_phy[10] = b43_phy_read(dev, B43_PHY_CCK(0x03)); backup_phy[11] = b43_phy_read(dev, B43_PHY_LO_MASK); backup_phy[12] = b43_phy_read(dev, B43_PHY_LO_CTL); - backup_phy[13] = b43_phy_read(dev, B43_PHY_BASE(0x2B)); + backup_phy[13] = b43_phy_read(dev, B43_PHY_CCK(0x2B)); backup_phy[14] = b43_phy_read(dev, B43_PHY_PGACTL); backup_phy[15] = b43_phy_read(dev, B43_PHY_LO_LEAKAGE); backup_bband = phy->bbatt.att; @@ -1601,12 +1173,12 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) (b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFCF) | 0x10); - b43_phy_write(dev, B43_PHY_BASE(0x5A), 0x0780); - b43_phy_write(dev, B43_PHY_BASE(0x59), 0xC810); - b43_phy_write(dev, B43_PHY_BASE(0x58), 0x000D); + b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780); + b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810); + b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D); - b43_phy_write(dev, B43_PHY_BASE(0x0A), - b43_phy_read(dev, B43_PHY_BASE(0x0A)) | 0x2000); + b43_phy_write(dev, B43_PHY_CCK(0x0A), + b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000); if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */ b43_phy_write(dev, B43_PHY_ANALOGOVER, b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004); @@ -1614,8 +1186,8 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_read(dev, B43_PHY_ANALOGOVERVAL) & 0xFFFB); } - b43_phy_write(dev, B43_PHY_BASE(0x03), - (b43_phy_read(dev, B43_PHY_BASE(0x03)) + b43_phy_write(dev, B43_PHY_CCK(0x03), + (b43_phy_read(dev, B43_PHY_CCK(0x03)) & 0xFF9F) | 0x40); if (phy->radio_rev == 8) { @@ -1633,11 +1205,11 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020); b43_phy_write(dev, B43_PHY_LO_CTL, 0); - b43_phy_write(dev, B43_PHY_BASE(0x2B), - (b43_phy_read(dev, B43_PHY_BASE(0x2B)) + b43_phy_write(dev, B43_PHY_CCK(0x2B), + (b43_phy_read(dev, B43_PHY_CCK(0x2B)) & 0xFFC0) | 0x01); - b43_phy_write(dev, B43_PHY_BASE(0x2B), - (b43_phy_read(dev, B43_PHY_BASE(0x2B)) + b43_phy_write(dev, B43_PHY_CCK(0x2B), + (b43_phy_read(dev, B43_PHY_CCK(0x2B)) & 0xC0FF) | 0x800); b43_phy_write(dev, B43_PHY_RFOVER, @@ -1645,7 +1217,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { if (phy->rev >= 7) { b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) @@ -1708,14 +1280,14 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_ANALOGOVER, backup_phy[4]); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, backup_phy[5]); } - b43_phy_write(dev, B43_PHY_BASE(0x5A), backup_phy[6]); - b43_phy_write(dev, B43_PHY_BASE(0x59), backup_phy[7]); - b43_phy_write(dev, B43_PHY_BASE(0x58), backup_phy[8]); - b43_phy_write(dev, B43_PHY_BASE(0x0A), backup_phy[9]); - b43_phy_write(dev, B43_PHY_BASE(0x03), backup_phy[10]); + b43_phy_write(dev, B43_PHY_CCK(0x5A), backup_phy[6]); + b43_phy_write(dev, B43_PHY_CCK(0x59), backup_phy[7]); + b43_phy_write(dev, B43_PHY_CCK(0x58), backup_phy[8]); + b43_phy_write(dev, B43_PHY_CCK(0x0A), backup_phy[9]); + b43_phy_write(dev, B43_PHY_CCK(0x03), backup_phy[10]); b43_phy_write(dev, B43_PHY_LO_MASK, backup_phy[11]); b43_phy_write(dev, B43_PHY_LO_CTL, backup_phy[12]); - b43_phy_write(dev, B43_PHY_BASE(0x2B), backup_phy[13]); + b43_phy_write(dev, B43_PHY_CCK(0x2B), backup_phy[13]); b43_phy_write(dev, B43_PHY_PGACTL, backup_phy[14]); b43_phy_set_baseband_attenuation(dev, backup_bband); @@ -1793,45 +1365,42 @@ static void b43_phy_initg(struct b43_wldev *dev) else b43_radio_write16(dev, 0x0078, phy->initval); } - if (phy->lo_control->tx_bias == 0xFF) { - b43_lo_g_measure(dev); + b43_lo_g_init(dev); + if (has_tx_magnification(phy)) { + b43_radio_write16(dev, 0x52, + (b43_radio_read16(dev, 0x52) & 0xFF00) + | phy->lo_control->tx_bias | phy-> + lo_control->tx_magn); } else { - if (has_tx_magnification(phy)) { - b43_radio_write16(dev, 0x52, - (b43_radio_read16(dev, 0x52) & 0xFF00) - | phy->lo_control->tx_bias | phy-> - lo_control->tx_magn); - } else { - b43_radio_write16(dev, 0x52, - (b43_radio_read16(dev, 0x52) & 0xFFF0) - | phy->lo_control->tx_bias); - } - if (phy->rev >= 6) { - b43_phy_write(dev, B43_PHY_BASE(0x36), - (b43_phy_read(dev, B43_PHY_BASE(0x36)) - & 0x0FFF) | (phy->lo_control-> - tx_bias << 12)); - } - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL) - b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8075); - else - b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x807F); - if (phy->rev < 2) - b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x101); - else - b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x202); + b43_radio_write16(dev, 0x52, + (b43_radio_read16(dev, 0x52) & 0xFFF0) + | phy->lo_control->tx_bias); } + if (phy->rev >= 6) { + b43_phy_write(dev, B43_PHY_CCK(0x36), + (b43_phy_read(dev, B43_PHY_CCK(0x36)) + & 0x0FFF) | (phy->lo_control-> + tx_bias << 12)); + } + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) + b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); + else + b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); + if (phy->rev < 2) + b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x101); + else + b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x202); if (phy->gmode || phy->rev >= 2) { b43_lo_g_adjust(dev); b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); } - if (!(dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI)) { + if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { /* The specs state to update the NRSSI LT with * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. * Essentially, what we do here is resetting all NRSSI LT - * entries to -32 (see the limit_value() in nrssi_hw_update()) + * entries to -32 (see the clamp_val() in nrssi_hw_update()) */ b43_nrssi_hw_update(dev, 0xFFFF); //FIXME? b43_calc_nrssi_threshold(dev); @@ -1893,13 +1462,13 @@ static s8 b43_phy_estimate_power_out(struct b43_wldev *dev, s8 tssi) switch (phy->type) { case B43_PHYTYPE_A: tmp += 0x80; - tmp = limit_value(tmp, 0x00, 0xFF); + tmp = clamp_val(tmp, 0x00, 0xFF); dbm = phy->tssi2dbm[tmp]; //TODO: There's a FIXME on the specs break; case B43_PHYTYPE_B: case B43_PHYTYPE_G: - tmp = limit_value(tmp, 0x00, 0x3F); + tmp = clamp_val(tmp, 0x00, 0x3F); dbm = phy->tssi2dbm[tmp]; break; default: @@ -1958,8 +1527,8 @@ void b43_put_attenuation_into_ranges(struct b43_wldev *dev, break; } - *_rfatt = limit_value(rfatt, rf_min, rf_max); - *_bbatt = limit_value(bbatt, bb_min, bb_max); + *_rfatt = clamp_val(rfatt, rf_min, rf_max); + *_bbatt = clamp_val(bbatt, bb_min, bb_max); } /* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */ @@ -1995,7 +1564,6 @@ void b43_phy_xmitpower(struct b43_wldev *dev) int rfatt_delta, bbatt_delta; int rfatt, bbatt; u8 tx_control; - unsigned long phylock_flags; tmp = b43_shm_read16(dev, B43_SHM_SHARED, 0x0058); v0 = (s8) (tmp & 0x00FF); @@ -2036,16 +1604,15 @@ void b43_phy_xmitpower(struct b43_wldev *dev) estimated_pwr = b43_phy_estimate_power_out(dev, average); - max_pwr = dev->dev->bus->sprom.r1.maxpwr_bg; - if ((dev->dev->bus->sprom.r1. - boardflags_lo & B43_BFL_PACTRL) - && (phy->type == B43_PHYTYPE_G)) + max_pwr = dev->dev->bus->sprom.maxpwr_bg; + if ((dev->dev->bus->sprom.boardflags_lo + & B43_BFL_PACTRL) && (phy->type == B43_PHYTYPE_G)) max_pwr -= 0x3; if (unlikely(max_pwr <= 0)) { b43warn(dev->wl, "Invalid max-TX-power value in SPROM.\n"); max_pwr = 60; /* fake it */ - dev->dev->bus->sprom.r1.maxpwr_bg = max_pwr; + dev->dev->bus->sprom.maxpwr_bg = max_pwr; } /*TODO: @@ -2056,7 +1623,7 @@ void b43_phy_xmitpower(struct b43_wldev *dev) /* Get desired power (in Q5.2) */ desired_pwr = INT_TO_Q52(phy->power_level); /* And limit it. max_pwr already is Q5.2 */ - desired_pwr = limit_value(desired_pwr, 0, max_pwr); + desired_pwr = clamp_val(desired_pwr, 0, max_pwr); if (b43_debug(dev, B43_DBG_XMITPOWER)) { b43dbg(dev->wl, "Current TX power output: " Q52_FMT @@ -2082,10 +1649,8 @@ void b43_phy_xmitpower(struct b43_wldev *dev) bbatt_delta -= 4 * rfatt_delta; /* So do we finally need to adjust something? */ - if ((rfatt_delta == 0) && (bbatt_delta == 0)) { - b43_lo_g_ctl_mark_cur_used(dev); + if ((rfatt_delta == 0) && (bbatt_delta == 0)) return; - } /* Calculate the new attenuation values. */ bbatt = phy->bbatt.att; @@ -2103,7 +1668,7 @@ void b43_phy_xmitpower(struct b43_wldev *dev) B43_TXCTL_TXMIX; rfatt += 2; bbatt += 2; - } else if (dev->dev->bus->sprom.r1. + } else if (dev->dev->bus->sprom. boardflags_lo & B43_BFL_PACTRL) { bbatt += 4 * (rfatt - 2); @@ -2127,15 +1692,17 @@ void b43_phy_xmitpower(struct b43_wldev *dev) phy->bbatt.att = bbatt; /* Adjust the hardware */ - b43_phy_lock(dev, phylock_flags); + b43_phy_lock(dev); b43_radio_lock(dev); b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control); - b43_lo_g_ctl_mark_cur_used(dev); b43_radio_unlock(dev); - b43_phy_unlock(dev, phylock_flags); + b43_phy_unlock(dev); break; } + case B43_PHYTYPE_N: + b43_nphy_xmitpower(dev); + break; default: B43_WARN_ON(1); } @@ -2166,7 +1733,7 @@ static inline f = q; i++; } while (delta >= 2); - entry[index] = limit_value(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128); + entry[index] = clamp_val(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128); return 0; } @@ -2179,13 +1746,13 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev) s8 *dyn_tssi2dbm; if (phy->type == B43_PHYTYPE_A) { - pab0 = (s16) (dev->dev->bus->sprom.r1.pa1b0); - pab1 = (s16) (dev->dev->bus->sprom.r1.pa1b1); - pab2 = (s16) (dev->dev->bus->sprom.r1.pa1b2); + pab0 = (s16) (dev->dev->bus->sprom.pa1b0); + pab1 = (s16) (dev->dev->bus->sprom.pa1b1); + pab2 = (s16) (dev->dev->bus->sprom.pa1b2); } else { - pab0 = (s16) (dev->dev->bus->sprom.r1.pa0b0); - pab1 = (s16) (dev->dev->bus->sprom.r1.pa0b1); - pab2 = (s16) (dev->dev->bus->sprom.r1.pa0b2); + pab0 = (s16) (dev->dev->bus->sprom.pa0b0); + pab1 = (s16) (dev->dev->bus->sprom.pa0b1); + pab2 = (s16) (dev->dev->bus->sprom.pa0b2); } if ((dev->dev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)) { @@ -2198,23 +1765,23 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev) pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ if (phy->type == B43_PHYTYPE_A) { - if ((s8) dev->dev->bus->sprom.r1.itssi_a != 0 && - (s8) dev->dev->bus->sprom.r1.itssi_a != -1) + if ((s8) dev->dev->bus->sprom.itssi_a != 0 && + (s8) dev->dev->bus->sprom.itssi_a != -1) phy->tgt_idle_tssi = - (s8) (dev->dev->bus->sprom.r1.itssi_a); + (s8) (dev->dev->bus->sprom.itssi_a); else phy->tgt_idle_tssi = 62; } else { - if ((s8) dev->dev->bus->sprom.r1.itssi_bg != 0 && - (s8) dev->dev->bus->sprom.r1.itssi_bg != -1) + if ((s8) dev->dev->bus->sprom.itssi_bg != 0 && + (s8) dev->dev->bus->sprom.itssi_bg != -1) phy->tgt_idle_tssi = - (s8) (dev->dev->bus->sprom.r1.itssi_bg); + (s8) (dev->dev->bus->sprom.itssi_bg); else phy->tgt_idle_tssi = 62; } dyn_tssi2dbm = kmalloc(64, GFP_KERNEL); if (dyn_tssi2dbm == NULL) { - b43err(dev->wl, "Could not allocate memory" + b43err(dev->wl, "Could not allocate memory " "for tssi2dbm table\n"); return -ENOMEM; } @@ -2255,41 +1822,26 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev) int b43_phy_init(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; - int err = -ENODEV; + bool unsupported = 0; + int err = 0; switch (phy->type) { case B43_PHYTYPE_A: - if (phy->rev == 2 || phy->rev == 3) { + if (phy->rev == 2 || phy->rev == 3) b43_phy_inita(dev); - err = 0; - } - break; - case B43_PHYTYPE_B: - switch (phy->rev) { - case 2: - b43_phy_initb2(dev); - err = 0; - break; - case 4: - b43_phy_initb4(dev); - err = 0; - break; - case 5: - b43_phy_initb5(dev); - err = 0; - break; - case 6: - b43_phy_initb6(dev); - err = 0; - break; - } + else + unsupported = 1; break; case B43_PHYTYPE_G: b43_phy_initg(dev); - err = 0; break; + case B43_PHYTYPE_N: + err = b43_phy_initn(dev); + break; + default: + unsupported = 1; } - if (err) + if (unsupported) b43err(dev->wl, "Unknown PHYTYPE found\n"); return err; @@ -2298,7 +1850,7 @@ int b43_phy_init(struct b43_wldev *dev) void b43_set_rx_antenna(struct b43_wldev *dev, int antenna) { struct b43_phy *phy = &dev->phy; - u32 hf; + u64 hf; u16 tmp; int autodiv = 0; @@ -2392,6 +1944,9 @@ void b43_set_rx_antenna(struct b43_wldev *dev, int antenna) << B43_PHY_BBANDCFG_RXANT_SHIFT; b43_phy_write(dev, B43_PHY_CCKBBANDCFG, tmp); break; + case B43_PHYTYPE_N: + b43_nphy_set_rxantenna(dev, antenna); + break; default: B43_WARN_ON(1); } @@ -2421,6 +1976,7 @@ void b43_radio_lock(struct b43_wldev *dev) u32 macctl; macctl = b43_read32(dev, B43_MMIO_MACCTL); + B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK); macctl |= B43_MACCTL_RADIOLOCK; b43_write32(dev, B43_MMIO_MACCTL, macctl); /* Commit the write and wait for the device @@ -2437,6 +1993,7 @@ void b43_radio_unlock(struct b43_wldev *dev) b43_read16(dev, B43_MMIO_PHY_VER); /* unlock */ macctl = b43_read32(dev, B43_MMIO_MACCTL); + B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK)); macctl &= ~B43_MACCTL_RADIOLOCK; b43_write32(dev, B43_MMIO_MACCTL, macctl); } @@ -2445,9 +2002,12 @@ u16 b43_radio_read16(struct b43_wldev *dev, u16 offset) { struct b43_phy *phy = &dev->phy; + /* Offset 1 is a 32-bit register. */ + B43_WARN_ON(offset == 1); + switch (phy->type) { case B43_PHYTYPE_A: - offset |= 0x0040; + offset |= 0x40; break; case B43_PHYTYPE_B: if (phy->radio_ver == 0x2053) { @@ -2463,6 +2023,14 @@ u16 b43_radio_read16(struct b43_wldev *dev, u16 offset) case B43_PHYTYPE_G: offset |= 0x80; break; + case B43_PHYTYPE_N: + offset |= 0x100; + break; + case B43_PHYTYPE_LP: + /* No adjustment required. */ + break; + default: + B43_WARN_ON(1); } b43_write16(dev, B43_MMIO_RADIO_CONTROL, offset); @@ -2471,11 +2039,31 @@ u16 b43_radio_read16(struct b43_wldev *dev, u16 offset) void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val) { + /* Offset 1 is a 32-bit register. */ + B43_WARN_ON(offset == 1); + b43_write16(dev, B43_MMIO_RADIO_CONTROL, offset); - mmiowb(); b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, val); } +void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask) +{ + b43_radio_write16(dev, offset, + b43_radio_read16(dev, offset) & mask); +} + +void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set) +{ + b43_radio_write16(dev, offset, + b43_radio_read16(dev, offset) | set); +} + +void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set) +{ + b43_radio_write16(dev, offset, + (b43_radio_read16(dev, offset) & mask) | set); +} + static void b43_set_all_gains(struct b43_wldev *dev, s16 first, s16 second, s16 third) { @@ -2605,12 +2193,11 @@ u8 b43_radio_aci_scan(struct b43_wldev * dev) u8 ret[13]; unsigned int channel = phy->channel; unsigned int i, j, start, end; - unsigned long phylock_flags; if (!((phy->type == B43_PHYTYPE_G) && (phy->rev > 0))) return 0; - b43_phy_lock(dev, phylock_flags); + b43_phy_lock(dev); b43_radio_lock(dev); b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC); b43_phy_write(dev, B43_PHY_G_CRS, @@ -2639,7 +2226,7 @@ u8 b43_radio_aci_scan(struct b43_wldev * dev) ret[j] = 1; } b43_radio_unlock(dev); - b43_phy_unlock(dev, phylock_flags); + b43_phy_unlock(dev); return ret[channel - 1]; } @@ -2672,7 +2259,7 @@ void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val) for (i = 0; i < 64; i++) { tmp = b43_nrssi_hw_read(dev, i); tmp -= val; - tmp = limit_value(tmp, -32, 31); + tmp = clamp_val(tmp, -32, 31); b43_nrssi_hw_write(dev, i, tmp); } } @@ -2689,7 +2276,7 @@ void b43_nrssi_mem_update(struct b43_wldev *dev) tmp = (i - delta) * phy->nrssislope; tmp /= 0x10000; tmp += 0x3A; - tmp = limit_value(tmp, 0, 0x3F); + tmp = clamp_val(tmp, 0, 0x3F); phy->nrssi_lt[i] = tmp; } } @@ -3114,7 +2701,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) if (phy->radio_ver != 0x2050) return; if (! - (dev->dev->bus->sprom.r1. + (dev->dev->bus->sprom. boardflags_lo & B43_BFL_RSSI)) return; @@ -3126,7 +2713,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) } else threshold = phy->nrssi[1] - 5; - threshold = limit_value(threshold, 0, 0x3E); + threshold = clamp_val(threshold, 0, 0x3E); b43_phy_read(dev, 0x0020); /* dummy read */ b43_phy_write(dev, 0x0020, (((u16) threshold) << 8) | 0x001C); @@ -3145,7 +2732,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) } case B43_PHYTYPE_G: if (!phy->gmode || - !(dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI)) { + !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { tmp16 = b43_nrssi_hw_read(dev, 0x20); if (tmp16 >= 0x20) tmp16 -= 0x40; @@ -3177,7 +2764,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) else a += 32; a = a >> 6; - a = limit_value(a, -31, 31); + a = clamp_val(a, -31, 31); b = b * (phy->nrssi[1] - phy->nrssi[0]); b += (phy->nrssi[0] << 6); @@ -3186,7 +2773,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) else b += 32; b = b >> 6; - b = limit_value(b, -31, 31); + b = clamp_val(b, -31, 31); tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000; tmp_u16 |= ((u32) b & 0x0000003F); @@ -3289,13 +2876,13 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode) } radio_stacksave(0x0078); tmp = (b43_radio_read16(dev, 0x0078) & 0x001E); - flipped = flip_4bit(tmp); + B43_WARN_ON(tmp > 15); + flipped = bitrev4(tmp); if (flipped < 10 && flipped >= 8) flipped = 7; else if (flipped >= 10) flipped -= 3; - flipped = flip_4bit(flipped); - flipped = (flipped << 1) | 0x0020; + flipped = (bitrev4(flipped) << 1) | 0x0020; b43_radio_write16(dev, 0x0078, flipped); b43_calc_nrssi_threshold(dev); @@ -3667,7 +3254,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, } if ((phy->rev < 7) || - !(sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) { + !(sprom->boardflags_lo & B43_BFL_EXTLNA)) { if (phy_register == B43_PHY_RFOVER) { return 0x1B3; } else if (phy_register == B43_PHY_RFOVERVAL) { @@ -3707,7 +3294,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, } } else { if ((phy->rev < 7) || - !(sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) { + !(sprom->boardflags_lo & B43_BFL_EXTLNA)) { if (phy_register == B43_PHY_RFOVER) { return 0x1B3; } else if (phy_register == B43_PHY_RFOVERVAL) { @@ -3757,10 +3344,10 @@ struct init2050_saved_values { u16 radio_52; /* PHY registers */ u16 phy_pgactl; - u16 phy_base_5A; - u16 phy_base_59; - u16 phy_base_58; - u16 phy_base_30; + u16 phy_cck_5A; + u16 phy_cck_59; + u16 phy_cck_58; + u16 phy_cck_30; u16 phy_rfover; u16 phy_rfoverval; u16 phy_analogover; @@ -3788,15 +3375,15 @@ u16 b43_radio_init2050(struct b43_wldev *dev) sav.radio_51 = b43_radio_read16(dev, 0x51); sav.radio_52 = b43_radio_read16(dev, 0x52); sav.phy_pgactl = b43_phy_read(dev, B43_PHY_PGACTL); - sav.phy_base_5A = b43_phy_read(dev, B43_PHY_BASE(0x5A)); - sav.phy_base_59 = b43_phy_read(dev, B43_PHY_BASE(0x59)); - sav.phy_base_58 = b43_phy_read(dev, B43_PHY_BASE(0x58)); + sav.phy_cck_5A = b43_phy_read(dev, B43_PHY_CCK(0x5A)); + sav.phy_cck_59 = b43_phy_read(dev, B43_PHY_CCK(0x59)); + sav.phy_cck_58 = b43_phy_read(dev, B43_PHY_CCK(0x58)); if (phy->type == B43_PHYTYPE_B) { - sav.phy_base_30 = b43_phy_read(dev, B43_PHY_BASE(0x30)); + sav.phy_cck_30 = b43_phy_read(dev, B43_PHY_CCK(0x30)); sav.reg_3EC = b43_read16(dev, 0x3EC); - b43_phy_write(dev, B43_PHY_BASE(0x30), 0xFF); + b43_phy_write(dev, B43_PHY_CCK(0x30), 0xFF); b43_write16(dev, 0x3EC, 0x3F3F); } else if (phy->gmode || phy->rev >= 2) { sav.phy_rfover = b43_phy_read(dev, B43_PHY_RFOVER); @@ -3847,8 +3434,8 @@ u16 b43_radio_init2050(struct b43_wldev *dev) b43_write16(dev, 0x03E6, 0x0122); } else { if (phy->analog >= 2) { - b43_phy_write(dev, B43_PHY_BASE(0x03), - (b43_phy_read(dev, B43_PHY_BASE(0x03)) + b43_phy_write(dev, B43_PHY_CCK(0x03), + (b43_phy_read(dev, B43_PHY_CCK(0x03)) & 0xFFBF) | 0x40); } b43_write16(dev, B43_MMIO_CHANNEL_EXT, @@ -3865,7 +3452,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev) LPD(0, 1, 1))); } b43_phy_write(dev, B43_PHY_PGACTL, 0xBFAF); - b43_phy_write(dev, B43_PHY_BASE(0x2B), 0x1403); + b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x1403); if (phy->gmode || phy->rev >= 2) { b43_phy_write(dev, B43_PHY_RFOVERVAL, radio2050_rfover_val(dev, B43_PHY_RFOVERVAL, @@ -3881,12 +3468,12 @@ u16 b43_radio_init2050(struct b43_wldev *dev) b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43) & 0xFFF0) | 0x0009); } - b43_phy_write(dev, B43_PHY_BASE(0x58), 0); + b43_phy_write(dev, B43_PHY_CCK(0x58), 0); for (i = 0; i < 16; i++) { - b43_phy_write(dev, B43_PHY_BASE(0x5A), 0x0480); - b43_phy_write(dev, B43_PHY_BASE(0x59), 0xC810); - b43_phy_write(dev, B43_PHY_BASE(0x58), 0x000D); + b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0480); + b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810); + b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D); if (phy->gmode || phy->rev >= 2) { b43_phy_write(dev, B43_PHY_RFOVERVAL, radio2050_rfover_val(dev, @@ -3912,7 +3499,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0); udelay(20); tmp1 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE); - b43_phy_write(dev, B43_PHY_BASE(0x58), 0); + b43_phy_write(dev, B43_PHY_CCK(0x58), 0); if (phy->gmode || phy->rev >= 2) { b43_phy_write(dev, B43_PHY_RFOVERVAL, radio2050_rfover_val(dev, @@ -3923,18 +3510,18 @@ u16 b43_radio_init2050(struct b43_wldev *dev) } udelay(10); - b43_phy_write(dev, B43_PHY_BASE(0x58), 0); + b43_phy_write(dev, B43_PHY_CCK(0x58), 0); tmp1++; tmp1 >>= 9; for (i = 0; i < 16; i++) { - radio78 = ((flip_4bit(i) << 1) | 0x20); + radio78 = (bitrev4(i) << 1) | 0x0020; b43_radio_write16(dev, 0x78, radio78); udelay(10); for (j = 0; j < 16; j++) { - b43_phy_write(dev, B43_PHY_BASE(0x5A), 0x0D80); - b43_phy_write(dev, B43_PHY_BASE(0x59), 0xC810); - b43_phy_write(dev, B43_PHY_BASE(0x58), 0x000D); + b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0D80); + b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810); + b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D); if (phy->gmode || phy->rev >= 2) { b43_phy_write(dev, B43_PHY_RFOVERVAL, radio2050_rfover_val(dev, @@ -3963,7 +3550,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0); udelay(10); tmp2 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE); - b43_phy_write(dev, B43_PHY_BASE(0x58), 0); + b43_phy_write(dev, B43_PHY_CCK(0x58), 0); if (phy->gmode || phy->rev >= 2) { b43_phy_write(dev, B43_PHY_RFOVERVAL, radio2050_rfover_val(dev, @@ -3984,16 +3571,16 @@ u16 b43_radio_init2050(struct b43_wldev *dev) b43_radio_write16(dev, 0x51, sav.radio_51); b43_radio_write16(dev, 0x52, sav.radio_52); b43_radio_write16(dev, 0x43, sav.radio_43); - b43_phy_write(dev, B43_PHY_BASE(0x5A), sav.phy_base_5A); - b43_phy_write(dev, B43_PHY_BASE(0x59), sav.phy_base_59); - b43_phy_write(dev, B43_PHY_BASE(0x58), sav.phy_base_58); + b43_phy_write(dev, B43_PHY_CCK(0x5A), sav.phy_cck_5A); + b43_phy_write(dev, B43_PHY_CCK(0x59), sav.phy_cck_59); + b43_phy_write(dev, B43_PHY_CCK(0x58), sav.phy_cck_58); b43_write16(dev, 0x3E6, sav.reg_3E6); if (phy->analog != 0) b43_write16(dev, 0x3F4, sav.reg_3F4); b43_phy_write(dev, B43_PHY_SYNCCTL, sav.phy_syncctl); b43_synth_pu_workaround(dev, phy->channel); if (phy->type == B43_PHYTYPE_B) { - b43_phy_write(dev, B43_PHY_BASE(0x30), sav.phy_base_30); + b43_phy_write(dev, B43_PHY_CCK(0x30), sav.phy_cck_30); b43_write16(dev, 0x3EC, sav.reg_3EC); } else if (phy->gmode) { b43_write16(dev, B43_MMIO_PHY_RADIO, @@ -4103,7 +3690,8 @@ int b43_radio_selectchannel(struct b43_wldev *dev, struct b43_phy *phy = &dev->phy; u16 r8, tmp; u16 freq; - u16 channelcookie; + u16 channelcookie, savedcookie; + int err = 0; if (channel == 0xFF) { switch (phy->type) { @@ -4114,6 +3702,10 @@ int b43_radio_selectchannel(struct b43_wldev *dev, case B43_PHYTYPE_G: channel = B43_DEFAULT_CHANNEL_BG; break; + case B43_PHYTYPE_N: + //FIXME check if we are on 2.4GHz or 5GHz and set a default channel. + channel = 1; + break; default: B43_WARN_ON(1); } @@ -4123,13 +3715,18 @@ int b43_radio_selectchannel(struct b43_wldev *dev, * firmware from sending ghost packets. */ channelcookie = channel; - if (phy->type == B43_PHYTYPE_A) + if (0 /*FIXME on 5Ghz */) channelcookie |= 0x100; + //FIXME set 40Mhz flag if required + savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie); - if (phy->type == B43_PHYTYPE_A) { - if (channel > 200) - return -EINVAL; + switch (phy->type) { + case B43_PHYTYPE_A: + if (channel > 200) { + err = -EINVAL; + goto out; + } freq = channel2freq_a(channel); r8 = b43_radio_read16(dev, 0x0008); @@ -4176,9 +3773,12 @@ int b43_radio_selectchannel(struct b43_wldev *dev, b43_radio_set_tx_iq(dev); //TODO: TSSI2dbm workaround b43_phy_xmitpower(dev); //FIXME correct? - } else { - if ((channel < 1) || (channel > 14)) - return -EINVAL; + break; + case B43_PHYTYPE_G: + if ((channel < 1) || (channel > 14)) { + err = -EINVAL; + goto out; + } if (synthetic_pu_workaround) b43_synth_pu_workaround(dev, channel); @@ -4186,7 +3786,7 @@ int b43_radio_selectchannel(struct b43_wldev *dev, b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); if (channel == 14) { - if (dev->dev->bus->sprom.r1.country_code == + if (dev->dev->bus->sprom.country_code == SSB_SPROM1CCODE_JAPAN) b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACPR); @@ -4201,110 +3801,25 @@ int b43_radio_selectchannel(struct b43_wldev *dev, b43_read16(dev, B43_MMIO_CHANNEL_EXT) & 0xF7BF); } + break; + case B43_PHYTYPE_N: + err = b43_nphy_selectchannel(dev, channel); + if (err) + goto out; + break; + default: + B43_WARN_ON(1); } phy->channel = channel; /* Wait for the radio to tune to the channel and stabilize. */ msleep(8); - - return 0; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */ -static u16 b43_get_txgain_base_band(u16 txpower) -{ - u16 ret; - - B43_WARN_ON(txpower > 63); - - if (txpower >= 54) - ret = 2; - else if (txpower >= 49) - ret = 4; - else if (txpower >= 44) - ret = 5; - else - ret = 6; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */ -static u16 b43_get_txgain_freq_power_amp(u16 txpower) -{ - u16 ret; - - B43_WARN_ON(txpower > 63); - - if (txpower >= 32) - ret = 0; - else if (txpower >= 25) - ret = 1; - else if (txpower >= 20) - ret = 2; - else if (txpower >= 12) - ret = 3; - else - ret = 4; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */ -static u16 b43_get_txgain_dac(u16 txpower) -{ - u16 ret; - - B43_WARN_ON(txpower > 63); - - if (txpower >= 54) - ret = txpower - 53; - else if (txpower >= 49) - ret = txpower - 42; - else if (txpower >= 44) - ret = txpower - 37; - else if (txpower >= 32) - ret = txpower - 32; - else if (txpower >= 25) - ret = txpower - 20; - else if (txpower >= 20) - ret = txpower - 13; - else if (txpower >= 12) - ret = txpower - 8; - else - ret = txpower; - - return ret; -} - -static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower) -{ - struct b43_phy *phy = &dev->phy; - u16 pamp, base, dac, t; - - txpower = limit_value(txpower, 0, 63); - - pamp = b43_get_txgain_freq_power_amp(txpower); - pamp <<= 5; - pamp &= 0x00E0; - b43_phy_write(dev, 0x0019, pamp); - - base = b43_get_txgain_base_band(txpower); - base &= 0x000F; - b43_phy_write(dev, 0x0017, base | 0x0020); - - t = b43_ofdmtab_read16(dev, 0x3000, 1); - t &= 0x0007; - - dac = b43_get_txgain_dac(txpower); - dac <<= 3; - dac |= t; - - b43_ofdmtab_write16(dev, 0x3000, 1, dac); - - phy->txpwr_offset = txpower; - - //TODO: FuncPlaceholder (Adjust BB loft cancel) +out: + if (err) { + b43_shm_write16(dev, B43_SHM_SHARED, + B43_SHM_SH_CHAN, savedcookie); + } + return err; } void b43_radio_turn_on(struct b43_wldev *dev) @@ -4344,6 +3859,9 @@ void b43_radio_turn_on(struct b43_wldev *dev) err |= b43_radio_selectchannel(dev, channel, 0); B43_WARN_ON(err); break; + case B43_PHYTYPE_N: + b43_nphy_radio_turn_on(dev); + break; default: B43_WARN_ON(1); } @@ -4357,13 +3875,17 @@ void b43_radio_turn_off(struct b43_wldev *dev, bool force) if (!phy->radio_on && !force) return; - if (phy->type == B43_PHYTYPE_A) { + switch (phy->type) { + case B43_PHYTYPE_N: + b43_nphy_radio_turn_off(dev); + break; + case B43_PHYTYPE_A: b43_radio_write16(dev, 0x0004, 0x00FF); b43_radio_write16(dev, 0x0005, 0x00FB); b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008); b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008); - } - if (phy->type == B43_PHYTYPE_G && dev->dev->id.revision >= 5) { + break; + case B43_PHYTYPE_G: { u16 rfover, rfoverval; rfover = b43_phy_read(dev, B43_PHY_RFOVER); @@ -4375,7 +3897,10 @@ void b43_radio_turn_off(struct b43_wldev *dev, bool force) } b43_phy_write(dev, B43_PHY_RFOVER, rfover | 0x008C); b43_phy_write(dev, B43_PHY_RFOVERVAL, rfoverval & 0xFF73); - } else - b43_phy_write(dev, 0x0015, 0xAA00); + break; + } + default: + B43_WARN_ON(1); + } phy->radio_on = 0; }