diff options
author | Michael Buesch <mb@bu3sch.de> | 2008-08-27 18:53:02 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-29 16:24:12 -0400 |
commit | ef1a628d83fc0423c36e773281162be790503168 (patch) | |
tree | 436d3d7d91434febb1813dcea16060e6937288b9 /drivers/net/wireless/b43/nphy.c | |
parent | 35e032d82f3e2a9b0d92077b4fbc97166525ed53 (diff) | |
download | blackbird-op-linux-ef1a628d83fc0423c36e773281162be790503168.tar.gz blackbird-op-linux-ef1a628d83fc0423c36e773281162be790503168.zip |
b43: Implement dynamic PHY API
This patch implements a dynamic "ops" based PHY API.
This is needed in order to conveniently support future PHY types
to avoid the "switch"-hell.
This patch does not change any functionality. It just moves lots
of code from one place to another and adjusts it for the changed
data structures.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/nphy.c')
-rw-r--r-- | drivers/net/wireless/b43/nphy.c | 143 |
1 files changed, 139 insertions, 4 deletions
diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/nphy.c index 644eed993bea..831986c459f8 100644 --- a/drivers/net/wireless/b43/nphy.c +++ b/drivers/net/wireless/b43/nphy.c @@ -81,9 +81,8 @@ 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) +/* Tune the hardware to a new channel. */ +static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel) { const struct b43_nphy_channeltab_entry *tabent; @@ -162,7 +161,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) msleep(1); b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); msleep(1); - b43_radio_selectchannel(dev, dev->phy.channel, 0); + nphy_channel_switch(dev, dev->phy.channel); 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); @@ -484,3 +483,139 @@ int b43_phy_initn(struct b43_wldev *dev) b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); return 0; } + +static int b43_nphy_op_allocate(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy; + + nphy = kzalloc(sizeof(*nphy), GFP_KERNEL); + if (!nphy) + return -ENOMEM; + dev->phy.n = nphy; + + //TODO init struct b43_phy_n + + return 0; +} + +static int b43_nphy_op_init(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + int err; + + err = b43_phy_initn(dev); + if (err) + return err; + nphy->initialised = 1; + + return 0; +} + +static void b43_nphy_op_exit(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + if (nphy->initialised) { + //TODO + nphy->initialised = 0; + } + //TODO + kfree(nphy); + dev->phy.n = NULL; +} + +static inline void check_phyreg(struct b43_wldev *dev, u16 offset) +{ +#if B43_DEBUG + if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) { + /* OFDM registers are onnly available on A/G-PHYs */ + b43err(dev->wl, "Invalid OFDM PHY access at " + "0x%04X on N-PHY\n", offset); + dump_stack(); + } + if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) { + /* Ext-G registers are only available on G-PHYs */ + b43err(dev->wl, "Invalid EXT-G PHY access at " + "0x%04X on N-PHY\n", offset); + dump_stack(); + } +#endif /* B43_DEBUG */ +} + +static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg) +{ + check_phyreg(dev, reg); + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + return b43_read16(dev, B43_MMIO_PHY_DATA); +} + +static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) +{ + check_phyreg(dev, reg); + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, value); +} + +static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) +{ + /* Register 1 is a 32-bit register. */ + B43_WARN_ON(reg == 1); + /* N-PHY needs 0x100 for read access */ + reg |= 0x100; + + b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); + return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); +} + +static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) +{ + /* Register 1 is a 32-bit register. */ + B43_WARN_ON(reg == 1); + + b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); + b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); +} + +static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, + enum rfkill_state state) +{//TODO +} + +static int b43_nphy_op_switch_channel(struct b43_wldev *dev, + unsigned int new_channel) +{ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if ((new_channel < 1) || (new_channel > 14)) + return -EINVAL; + } else { + if (new_channel > 200) + return -EINVAL; + } + + return nphy_channel_switch(dev, new_channel); +} + +static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) +{ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + return 1; + return 36; +} + +static void b43_nphy_op_xmitpower(struct b43_wldev *dev) +{//TODO +} + +const struct b43_phy_operations b43_phyops_n = { + .allocate = b43_nphy_op_allocate, + .init = b43_nphy_op_init, + .exit = b43_nphy_op_exit, + .phy_read = b43_nphy_op_read, + .phy_write = b43_nphy_op_write, + .radio_read = b43_nphy_op_radio_read, + .radio_write = b43_nphy_op_radio_write, + .software_rfkill = b43_nphy_op_software_rfkill, + .switch_channel = b43_nphy_op_switch_channel, + .get_default_chan = b43_nphy_op_get_default_chan, + .xmitpower = b43_nphy_op_xmitpower, +}; |