Skip to content

Commit

Permalink
b43: Add NPHY radio init code
Browse files Browse the repository at this point in the history
This adds some code to init the 2055 radio.
This patch adds two files "tables_nphy.h" and "tables_nphy.c"

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Michael Buesch authored and David S. Miller committed Jan 28, 2008
1 parent af4b745 commit 53a6e23
Show file tree
Hide file tree
Showing 8 changed files with 512 additions and 9 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/b43/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
b43-y += main.o
b43-y += tables.o
b43-y += tables_nphy.o
b43-y += phy.o
b43-y += nphy.o
b43-y += sysfs.o
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/b43/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2132,6 +2132,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
switch (dev->phy.type) {
case B43_PHYTYPE_A:
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
Expand Down Expand Up @@ -2320,6 +2321,8 @@ static void b43_periodic_every60sec(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;

if (phy->type != B43_PHYTYPE_G)
return;
if (!b43_has_hardware_pctl(phy))
b43_lo_g_ctl_mark_all_unused(dev);
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
Expand Down
98 changes: 97 additions & 1 deletion drivers/net/wireless/b43/nphy.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,107 @@

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


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

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

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

//TODO
}

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);
}

int b43_phy_initn(struct b43_wldev *dev)
{
b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");

return -EOPNOTSUPP;
return 0;
}
9 changes: 9 additions & 0 deletions drivers/net/wireless/b43/nphy.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
#define B43_NPHY_RFCTL_CMD_RXEN 0x0100 /* RX enable */
#define B43_NPHY_RFCTL_CMD_TXEN 0x0200 /* TX enable */
#define B43_NPHY_RFCTL_CMD_CHIP0PU 0x0400 /* Chip0 PU */
#define B43_NPHY_RFCTL_CMD_EN 0x0800 /* Radio enabled */
#define B43_NPHY_RFCTL_CMD_SEQENCORE 0xF000 /* Seq en core */
#define B43_NPHY_RFCTL_CMD_SEQENCORE_SHIFT 12
#define B43_NPHY_RFCTL_RSSIO1 B43_PHY_N(0x07A) /* RF control (RSSI others 1) */
Expand Down Expand Up @@ -913,4 +914,12 @@ struct b43_wldev;

int b43_phy_initn(struct b43_wldev *dev);

void b43_nphy_radio_turn_on(struct b43_wldev *dev);
void b43_nphy_radio_turn_off(struct b43_wldev *dev);

void b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel);

void b43_nphy_xmitpower(struct b43_wldev *dev);
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna);

#endif /* B43_NPHY_H_ */
81 changes: 73 additions & 8 deletions drivers/net/wireless/b43/phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,24 @@ void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val)
b43_write16(dev, B43_MMIO_PHY_DATA, val);
}

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,
const struct b43_bbatt *bbatt,
Expand Down Expand Up @@ -1857,6 +1875,9 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
b43_phy_unlock(dev);
break;
}
case B43_PHYTYPE_N:
b43_nphy_xmitpower(dev);
break;
default:
B43_WARN_ON(1);
}
Expand Down Expand Up @@ -2116,6 +2137,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);
}
Expand Down Expand Up @@ -2215,6 +2239,24 @@ void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val)
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)
{
Expand Down Expand Up @@ -3852,6 +3894,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);
}
Expand All @@ -3861,11 +3907,13 @@ 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
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);

if (phy->type == B43_PHYTYPE_A) {
switch (phy->type) {
case B43_PHYTYPE_A:
if (channel > 200)
return -EINVAL;
freq = channel2freq_a(channel);
Expand Down Expand Up @@ -3914,7 +3962,8 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
b43_radio_set_tx_iq(dev);
//TODO: TSSI2dbm workaround
b43_phy_xmitpower(dev); //FIXME correct?
} else {
break;
case B43_PHYTYPE_G:
if ((channel < 1) || (channel > 14))
return -EINVAL;

Expand All @@ -3939,6 +3988,12 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
b43_read16(dev, B43_MMIO_CHANNEL_EXT)
& 0xF7BF);
}
break;
case B43_PHYTYPE_N:
b43_nphy_selectchannel(dev, channel);
break;
default:
B43_WARN_ON(1);
}

phy->channel = channel;
Expand Down Expand Up @@ -3985,6 +4040,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);
}
Expand All @@ -3998,13 +4056,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);
Expand All @@ -4016,7 +4078,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;
}
20 changes: 20 additions & 0 deletions drivers/net/wireless/b43/phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,18 @@ enum {
void b43_phy_lock(struct b43_wldev *dev);
void b43_phy_unlock(struct b43_wldev *dev);


/* Read a value from a PHY register */
u16 b43_phy_read(struct b43_wldev *dev, u16 offset);
/* Write a value to a PHY register */
void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val);
/* Mask a PHY register with a mask */
void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
/* OR a PHY register with a bitmap */
void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set);
/* Mask and OR a PHY register with a mask and bitmap */
void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);


int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev);

Expand Down Expand Up @@ -269,8 +279,18 @@ extern const u8 b43_radio_channel_codes_bg[];
void b43_radio_lock(struct b43_wldev *dev);
void b43_radio_unlock(struct b43_wldev *dev);


/* Read a value from a 16bit radio register */
u16 b43_radio_read16(struct b43_wldev *dev, u16 offset);
/* Write a value to a 16bit radio register */
void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val);
/* Mask a 16bit radio register with a mask */
void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask);
/* OR a 16bit radio register with a bitmap */
void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
/* Mask and OR a PHY register with a mask and bitmap */
void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);


u16 b43_radio_init2050(struct b43_wldev *dev);
void b43_radio_init2060(struct b43_wldev *dev);
Expand Down
Loading

0 comments on commit 53a6e23

Please sign in to comment.