diff options
Diffstat (limited to 'drivers/net/wireless/b43')
36 files changed, 2722 insertions, 418 deletions
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 480595f04411..d2293dcc117f 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -26,6 +26,16 @@ config B43 This driver can be built as a module (recommended) that will be called "b43". If unsure, say M. +config B43_BCMA + bool "Support for BCMA bus" + depends on B43 && BCMA && BROKEN + default y + +config B43_SSB + bool + depends on B43 && SSB + default y + # Auto-select SSB PCI-HOST support, if possible config B43_PCI_AUTOSELECT bool @@ -80,6 +90,12 @@ config B43_SDIO #Data transfers to the device via PIO. We want it as a fallback even # if we can do DMA. +config B43_BCMA_PIO + bool + depends on B43_BCMA + select BCMA_BLOCKIO + default y + config B43_PIO bool depends on B43 @@ -107,6 +123,22 @@ config B43_PHY_LP and embedded devices. It supports 802.11a/g (802.11a support is optional, and currently disabled). +config B43_PHY_HT + bool "Support for HT-PHY devices (BROKEN)" + depends on B43 && BROKEN + ---help--- + Support for the HT-PHY. + + Say N, this is BROKEN and crashes driver. + +config B43_PHY_LCN + bool "Support for LCN-PHY devices (BROKEN)" + depends on B43 && BROKEN + ---help--- + Support for the LCN-PHY. + + Say N, this is BROKEN and crashes driver. + # This config option automatically enables b43 LEDS support, # if it's possible. config B43_LEDS diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index cef334a8c669..4648bbf76abc 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -1,4 +1,5 @@ b43-y += main.o +b43-y += bus.o b43-y += tables.o b43-$(CONFIG_B43_PHY_N) += tables_nphy.o b43-$(CONFIG_B43_PHY_N) += radio_2055.o @@ -9,6 +10,10 @@ b43-y += phy_a.o b43-$(CONFIG_B43_PHY_N) += phy_n.o b43-$(CONFIG_B43_PHY_LP) += phy_lp.o b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o +b43-$(CONFIG_B43_PHY_HT) += phy_ht.o +b43-$(CONFIG_B43_PHY_HT) += tables_phy_ht.o +b43-$(CONFIG_B43_PHY_HT) += radio_2059.o +b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o b43-y += sysfs.o b43-y += xmit.o b43-y += lo.o diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 25a78cfb7d15..08a28270bbb3 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -5,12 +5,14 @@ #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/hw_random.h> +#include <linux/bcma/bcma.h> #include <linux/ssb/ssb.h> #include <net/mac80211.h> #include "debugfs.h" #include "leds.h" #include "rfkill.h" +#include "bus.h" #include "lo.h" #include "phy_common.h" @@ -90,6 +92,8 @@ #define B43_MMIO_PIO11_BASE4 0x300 #define B43_MMIO_PIO11_BASE5 0x340 +#define B43_MMIO_RADIO24_CONTROL 0x3D8 /* core rev >= 24 only */ +#define B43_MMIO_RADIO24_DATA 0x3DA /* core rev >= 24 only */ #define B43_MMIO_PHY_VER 0x3E0 #define B43_MMIO_PHY_RADIO 0x3E2 #define B43_MMIO_PHY0 0x3E6 @@ -361,6 +365,10 @@ enum { #define B43_PHYTYPE_G 0x02 #define B43_PHYTYPE_N 0x04 #define B43_PHYTYPE_LP 0x05 +#define B43_PHYTYPE_SSLPN 0x06 +#define B43_PHYTYPE_HT 0x07 +#define B43_PHYTYPE_LCN 0x08 +#define B43_PHYTYPE_LCNXN 0x09 /* PHYRegisters */ #define B43_PHY_ILT_A_CTRL 0x0072 @@ -414,6 +422,17 @@ enum { #define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ #define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ +/* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */ +#define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */ +#define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */ +#define B43_BCMA_IOCTL_MACPHYCLKEN 0x00000010 /* MAC PHY Clock Control Enable */ +#define B43_BCMA_IOCTL_PLLREFSEL 0x00000020 /* PLL Frequency Reference Select */ +#define B43_BCMA_IOCTL_PHY_BW 0x000000C0 /* PHY band width and clock speed mask (N-PHY+ only?) */ +#define B43_BCMA_IOCTL_PHY_BW_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */ +#define B43_BCMA_IOCTL_PHY_BW_20MHZ 0x00000040 /* 20 MHz bandwidth, 80 MHz PHY */ +#define B43_BCMA_IOCTL_PHY_BW_40MHZ 0x00000080 /* 40 MHz bandwidth, 160 MHz PHY */ +#define B43_BCMA_IOCTL_GMODE 0x00002000 /* G Mode Enable */ + /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */ #define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ #define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */ @@ -707,7 +726,7 @@ enum { /* Data structure for one wireless device (802.11 core) */ struct b43_wldev { - struct ssb_device *sdev; + struct b43_bus_dev *dev; struct b43_wl *wl; /* The device initialization status. @@ -879,36 +898,59 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) return wl->hw->conf.channel->band; } +static inline int b43_bus_may_powerdown(struct b43_wldev *wldev) +{ + return wldev->dev->bus_may_powerdown(wldev->dev); +} +static inline int b43_bus_powerup(struct b43_wldev *wldev, bool dynamic_pctl) +{ + return wldev->dev->bus_powerup(wldev->dev, dynamic_pctl); +} +static inline int b43_device_is_enabled(struct b43_wldev *wldev) +{ + return wldev->dev->device_is_enabled(wldev->dev); +} +static inline void b43_device_enable(struct b43_wldev *wldev, + u32 core_specific_flags) +{ + wldev->dev->device_enable(wldev->dev, core_specific_flags); +} +static inline void b43_device_disable(struct b43_wldev *wldev, + u32 core_specific_flags) +{ + wldev->dev->device_disable(wldev->dev, core_specific_flags); +} + static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) { - return ssb_read16(dev->sdev, offset); + return dev->dev->read16(dev->dev, offset); } static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) { - ssb_write16(dev->sdev, offset, value); + dev->dev->write16(dev->dev, offset, value); } static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) { - return ssb_read32(dev->sdev, offset); + return dev->dev->read32(dev->dev, offset); } static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) { - ssb_write32(dev->sdev, offset, value); + dev->dev->write32(dev->dev, offset, value); } static inline void b43_block_read(struct b43_wldev *dev, void *buffer, size_t count, u16 offset, u8 reg_width) { - ssb_block_read(dev->sdev, buffer, count, offset, reg_width); + dev->dev->block_read(dev->dev, buffer, count, offset, reg_width); } static inline void b43_block_write(struct b43_wldev *dev, const void *buffer, size_t count, u16 offset, u8 reg_width) { - ssb_block_write(dev->sdev, buffer, count, offset, reg_width); + dev->dev->block_write(dev->dev, buffer, count, offset, reg_width); } static inline bool b43_using_pio_transfers(struct b43_wldev *dev) diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c new file mode 100644 index 000000000000..a5e61a9fb539 --- /dev/null +++ b/drivers/net/wireless/b43/bus.c @@ -0,0 +1,256 @@ +/* + + Broadcom B43 wireless driver + Bus abstraction layer + + 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 "b43.h" +#include "bus.h" + +/* BCMA */ +#ifdef CONFIG_B43_BCMA +static int b43_bus_bcma_bus_may_powerdown(struct b43_bus_dev *dev) +{ + return 0; /* bcma_bus_may_powerdown(dev->bdev->bus); */ +} +static int b43_bus_bcma_bus_powerup(struct b43_bus_dev *dev, + bool dynamic_pctl) +{ + return 0; /* bcma_bus_powerup(dev->sdev->bus, dynamic_pctl); */ +} +static int b43_bus_bcma_device_is_enabled(struct b43_bus_dev *dev) +{ + return bcma_core_is_enabled(dev->bdev); +} +static void b43_bus_bcma_device_enable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + bcma_core_enable(dev->bdev, core_specific_flags); +} +static void b43_bus_bcma_device_disable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + bcma_core_disable(dev->bdev, core_specific_flags); +} +static u16 b43_bus_bcma_read16(struct b43_bus_dev *dev, u16 offset) +{ + return bcma_read16(dev->bdev, offset); +} +static u32 b43_bus_bcma_read32(struct b43_bus_dev *dev, u16 offset) +{ + return bcma_read32(dev->bdev, offset); +} +static +void b43_bus_bcma_write16(struct b43_bus_dev *dev, u16 offset, u16 value) +{ + bcma_write16(dev->bdev, offset, value); +} +static +void b43_bus_bcma_write32(struct b43_bus_dev *dev, u16 offset, u32 value) +{ + bcma_write32(dev->bdev, offset, value); +} +static +void b43_bus_bcma_block_read(struct b43_bus_dev *dev, void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + bcma_block_read(dev->bdev, buffer, count, offset, reg_width); +} +static +void b43_bus_bcma_block_write(struct b43_bus_dev *dev, const void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + bcma_block_write(dev->bdev, buffer, count, offset, reg_width); +} + +struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core) +{ + struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->bus_type = B43_BUS_BCMA; + dev->bdev = core; + + dev->bus_may_powerdown = b43_bus_bcma_bus_may_powerdown; + dev->bus_powerup = b43_bus_bcma_bus_powerup; + dev->device_is_enabled = b43_bus_bcma_device_is_enabled; + dev->device_enable = b43_bus_bcma_device_enable; + dev->device_disable = b43_bus_bcma_device_disable; + + dev->read16 = b43_bus_bcma_read16; + dev->read32 = b43_bus_bcma_read32; + dev->write16 = b43_bus_bcma_write16; + dev->write32 = b43_bus_bcma_write32; + dev->block_read = b43_bus_bcma_block_read; + dev->block_write = b43_bus_bcma_block_write; + + dev->dev = &core->dev; + dev->dma_dev = core->dma_dev; + dev->irq = core->irq; + + /* + dev->board_vendor = core->bus->boardinfo.vendor; + dev->board_type = core->bus->boardinfo.type; + dev->board_rev = core->bus->boardinfo.rev; + */ + + dev->chip_id = core->bus->chipinfo.id; + dev->chip_rev = core->bus->chipinfo.rev; + dev->chip_pkg = core->bus->chipinfo.pkg; + + dev->bus_sprom = &core->bus->sprom; + + dev->core_id = core->id.id; + dev->core_rev = core->id.rev; + + return dev; +} +#endif /* CONFIG_B43_BCMA */ + +/* SSB */ +#ifdef CONFIG_B43_SSB +static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev) +{ + return ssb_bus_may_powerdown(dev->sdev->bus); +} +static inline int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev, + bool dynamic_pctl) +{ + return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl); +} +static inline int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev) +{ + return ssb_device_is_enabled(dev->sdev); +} +static inline void b43_bus_ssb_device_enable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + ssb_device_enable(dev->sdev, core_specific_flags); +} +static inline void b43_bus_ssb_device_disable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + ssb_device_disable(dev->sdev, core_specific_flags); +} + +static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset) +{ + return ssb_read16(dev->sdev, offset); +} +static inline u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset) +{ + return ssb_read32(dev->sdev, offset); +} +static inline +void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value) +{ + ssb_write16(dev->sdev, offset, value); +} +static inline +void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value) +{ + ssb_write32(dev->sdev, offset, value); +} +static inline +void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + ssb_block_read(dev->sdev, buffer, count, offset, reg_width); +} +static inline +void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + ssb_block_write(dev->sdev, buffer, count, offset, reg_width); +} + +struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) +{ + struct b43_bus_dev *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->bus_type = B43_BUS_SSB; + dev->sdev = sdev; + + dev->bus_may_powerdown = b43_bus_ssb_bus_may_powerdown; + dev->bus_powerup = b43_bus_ssb_bus_powerup; + dev->device_is_enabled = b43_bus_ssb_device_is_enabled; + dev->device_enable = b43_bus_ssb_device_enable; + dev->device_disable = b43_bus_ssb_device_disable; + + dev->read16 = b43_bus_ssb_read16; + dev->read32 = b43_bus_ssb_read32; + dev->write16 = b43_bus_ssb_write16; + dev->write32 = b43_bus_ssb_write32; + dev->block_read = b43_bus_ssb_block_read; + dev->block_write = b43_bus_ssb_block_write; + + dev->dev = sdev->dev; + dev->dma_dev = sdev->dma_dev; + dev->irq = sdev->irq; + + dev->board_vendor = sdev->bus->boardinfo.vendor; + dev->board_type = sdev->bus->boardinfo.type; + dev->board_rev = sdev->bus->boardinfo.rev; + + dev->chip_id = sdev->bus->chip_id; + dev->chip_rev = sdev->bus->chip_rev; + dev->chip_pkg = sdev->bus->chip_package; + + dev->bus_sprom = &sdev->bus->sprom; + + dev->core_id = sdev->id.coreid; + dev->core_rev = sdev->id.revision; + + return dev; +} +#endif /* CONFIG_B43_SSB */ + +void *b43_bus_get_wldev(struct b43_bus_dev *dev) +{ + switch (dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + return bcma_get_drvdata(dev->bdev); +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + return ssb_get_drvdata(dev->sdev); +#endif + } + return NULL; +} + +void b43_bus_set_wldev(struct b43_bus_dev *dev, void *wldev) +{ + switch (dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_set_drvdata(dev->bdev, wldev); +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + ssb_set_drvdata(dev->sdev, wldev); +#endif + } +} diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h new file mode 100644 index 000000000000..184c95659279 --- /dev/null +++ b/drivers/net/wireless/b43/bus.h @@ -0,0 +1,70 @@ +#ifndef B43_BUS_H_ +#define B43_BUS_H_ + +enum b43_bus_type { +#ifdef CONFIG_B43_BCMA + B43_BUS_BCMA, +#endif + B43_BUS_SSB, +}; + +struct b43_bus_dev { + enum b43_bus_type bus_type; + union { + struct bcma_device *bdev; + struct ssb_device *sdev; + }; + + int (*bus_may_powerdown)(struct b43_bus_dev *dev); + int (*bus_powerup)(struct b43_bus_dev *dev, bool dynamic_pctl); + int (*device_is_enabled)(struct b43_bus_dev *dev); + void (*device_enable)(struct b43_bus_dev *dev, + u32 core_specific_flags); + void (*device_disable)(struct b43_bus_dev *dev, + u32 core_specific_flags); + + u16 (*read16)(struct b43_bus_dev *dev, u16 offset); + u32 (*read32)(struct b43_bus_dev *dev, u16 offset); + void (*write16)(struct b43_bus_dev *dev, u16 offset, u16 value); + void (*write32)(struct b43_bus_dev *dev, u16 offset, u32 value); + void (*block_read)(struct b43_bus_dev *dev, void *buffer, + size_t count, u16 offset, u8 reg_width); + void (*block_write)(struct b43_bus_dev *dev, const void *buffer, + size_t count, u16 offset, u8 reg_width); + + struct device *dev; + struct device *dma_dev; + unsigned int irq; + + u16 board_vendor; + u16 board_type; + u16 board_rev; + + u16 chip_id; + u8 chip_rev; + u8 chip_pkg; + + struct ssb_sprom *bus_sprom; + + u16 core_id; + u8 core_rev; +}; + +static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev) +{ + return (dev->bus_type == B43_BUS_SSB && + dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA); +} +static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) +{ + return (dev->bus_type == B43_BUS_SSB && + dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); +} + +struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core); +struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); + +void *b43_bus_get_wldev(struct b43_bus_dev *dev); +void b43_bus_set_wldev(struct b43_bus_dev *dev, void *data); + +#endif /* B43_BUS_H_ */ diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 47d44bcff37d..ce572aebeffd 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -333,10 +333,10 @@ static inline dma_addr_t dmaaddr; if (tx) { - dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_TO_DEVICE); } else { - dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_FROM_DEVICE); } @@ -348,10 +348,10 @@ static inline dma_addr_t addr, size_t len, int tx) { if (tx) { - dma_unmap_single(ring->dev->sdev->dma_dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_TO_DEVICE); } else { - dma_unmap_single(ring->dev->sdev->dma_dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } } @@ -361,7 +361,7 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - dma_sync_single_for_cpu(ring->dev->sdev->dma_dev, + dma_sync_single_for_cpu(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -370,7 +370,7 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - dma_sync_single_for_device(ring->dev->sdev->dma_dev, + dma_sync_single_for_device(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) */ if (ring->type == B43_DMA_64BIT) flags |= GFP_DMA; - ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev, + ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, &(ring->dmabase), flags); if (!ring->descbase) { @@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) static void free_ringmemory(struct b43_dmaring *ring) { - dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE, + dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, ring->descbase, ring->dmabase); } @@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, dma_addr_t addr, size_t buffersize, bool dma_to_device) { - if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr))) + if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) return 1; switch (ring->type) { @@ -757,14 +757,14 @@ static void dmacontroller_cleanup(struct b43_dmaring *ring) static void free_all_descbuffers(struct b43_dmaring *ring) { - struct b43_dmadesc_generic *desc; struct b43_dmadesc_meta *meta; int i; if (!ring->used_slots) return; for (i = 0; i < ring->nr_slots; i++) { - desc = ring->ops->idx2desc(ring, i, &meta); + /* get meta - ignore returned value */ + ring->ops->idx2desc(ring, i, &meta); if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) { B43_WARN_ON(!ring->tx); @@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = dma_map_single(dev->sdev->dma_dev, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, b43_txhdr_size(dev), DMA_TO_DEVICE); @@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, if (!ring->txhdr_cache) goto err_kfree_meta; - dma_test = dma_map_single(dev->sdev->dma_dev, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, b43_txhdr_size(dev), DMA_TO_DEVICE); @@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, } } - dma_unmap_single(dev->sdev->dma_dev, + dma_unmap_single(dev->dev->dma_dev, dma_test, b43_txhdr_size(dev), DMA_TO_DEVICE); } @@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask) /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = dma_set_mask(dev->sdev->dma_dev, mask); + err = dma_set_mask(dev->dev->dma_dev, mask); if (!err) { - err = dma_set_coherent_mask(dev->sdev->dma_dev, mask); + err = dma_set_coherent_mask(dev->dev->dma_dev, mask); if (!err) break; } @@ -1055,7 +1055,14 @@ int b43_dma_init(struct b43_wldev *dev) err = b43_dma_set_mask(dev, dmamask); if (err) return err; - dma->translation = ssb_dma_translation(dev->sdev); + + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + dma->translation = ssb_dma_translation(dev->dev->sdev); + break; +#endif + } err = -ENOMEM; /* setup TX DMA channels. */ @@ -1085,7 +1092,7 @@ int b43_dma_init(struct b43_wldev *dev) goto err_destroy_mcast; /* No support for the TX status DMA ring. */ - B43_WARN_ON(dev->sdev->id.revision < 5); + B43_WARN_ON(dev->dev->core_rev < 5); b43dbg(dev->wl, "%u-bit DMA initialized\n", (unsigned int)type); @@ -1388,7 +1395,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, { const struct b43_dma_ops *ops; struct b43_dmaring *ring; - struct b43_dmadesc_generic *desc; struct b43_dmadesc_meta *meta; int slot, firstused; bool frame_succeed; @@ -1416,7 +1422,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, ops = ring->ops; while (1) { B43_WARN_ON(slot < 0 || slot >= ring->nr_slots); - desc = ops->idx2desc(ring, slot, &meta); + /* get meta - ignore returned value */ + ops->idx2desc(ring, slot, &meta); if (b43_dma_ptr_is_poisoned(meta->skb)) { b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) " @@ -1600,6 +1607,7 @@ void b43_dma_rx(struct b43_dmaring *ring) dma_rx(ring, &slot); update_max_used_slots(ring, ++used_slots); } + wmb(); ops->set_current_rxslot(ring, slot); ring->current_slot = slot; } diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 0cafafe368af..b56ed41fc1bd 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, led->led_dev.default_trigger = default_trigger; led->led_dev.brightness_set = b43_led_brightness_set; - err = led_classdev_register(dev->sdev->dev, &led->led_dev); + err = led_classdev_register(dev->dev->dev, &led->led_dev); if (err) { b43warn(dev->wl, "LEDs: Failed to register %s\n", name); led->wl = NULL; @@ -215,13 +215,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, enum b43_led_behaviour *behaviour, bool *activelow) { - struct ssb_bus *bus = dev->sdev->bus; u8 sprom[4]; - sprom[0] = bus->sprom.gpio0; - sprom[1] = bus->sprom.gpio1; - sprom[2] = bus->sprom.gpio2; - sprom[3] = bus->sprom.gpio3; + sprom[0] = dev->dev->bus_sprom->gpio0; + sprom[1] = dev->dev->bus_sprom->gpio1; + sprom[2] = dev->dev->bus_sprom->gpio2; + sprom[3] = dev->dev->bus_sprom->gpio3; if (sprom[led_index] == 0xFF) { /* There is no LED information in the SPROM @@ -231,12 +230,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, case 0: *behaviour = B43_LED_ACTIVITY; *activelow = 1; - if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) + if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ) *behaviour = B43_LED_RADIO_ALL; break; case 1: *behaviour = B43_LED_RADIO_B; - if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) + if (dev->dev->board_vendor == PCI_VENDOR_ID_ASUSTEK) *behaviour = B43_LED_ASSOC; break; case 2: diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 2ef7d4b38540..a3dc8bb8ca95 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c @@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev, rfover |= pga; rfover |= lna; rfover |= trsw_rx; - if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) + if ((dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) && phy->rev > 6) rfover |= B43_PHY_RFOVERVAL_EXTLNA; @@ -301,14 +301,12 @@ static void lo_measure_gain_values(struct b43_wldev *dev, max_rx_gain = 0; if (has_loopback_gain(phy)) { - int trsw_rx = 0; int trsw_rx_gain; if (use_trsw_rx) { trsw_rx_gain = gphy->trsw_rx_gain / 2; if (max_rx_gain >= trsw_rx_gain) { trsw_rx_gain = max_rx_gain - trsw_rx_gain; - trsw_rx = 0x20; } } else trsw_rx_gain = max_rx_gain; @@ -387,7 +385,7 @@ struct lo_g_saved_values { static void lo_measure_setup(struct b43_wldev *dev, struct lo_g_saved_values *sav) { - struct ssb_sprom *sprom = &dev->sdev->bus->sprom; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; struct b43_txpower_lo_control *lo = gphy->lo_control; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index eb4159686985..092dd9318869 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -113,6 +113,17 @@ static int b43_modparam_pio = B43_PIO_DEFAULT; module_param_named(pio, b43_modparam_pio, int, 0644); MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); +#ifdef CONFIG_B43_BCMA +static const struct bcma_device_id b43_bcma_tbl[] = { + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), + BCMA_CORETABLE_END +}; +MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); +#endif + +#ifdef CONFIG_B43_SSB static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), @@ -126,8 +137,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), SSB_DEVTABLE_END }; - MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); +#endif /* Channel and ratetables are shared for all devices. * They can't be const, because ieee80211 puts some precalculated @@ -548,7 +559,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) { u32 low, high; - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); /* The hardware guarantees us an atomic read, if we * read the low register first. */ @@ -586,7 +597,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) { u32 low, high; - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); low = tsf; high = (tsf >> 32); @@ -714,7 +725,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) b43_ram_write(dev, i * 4, buffer[i]); b43_write16(dev, 0x0568, 0x0000); - if (dev->sdev->id.revision < 11) + if (dev->dev->core_rev < 11) b43_write16(dev, 0x07C0, 0x0000); else b43_write16(dev, 0x07C0, 0x0100); @@ -1132,7 +1143,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) b43_write32(dev, B43_MMIO_MACCTL, macctl); /* Commit write */ b43_read32(dev, B43_MMIO_MACCTL); - if (awake && dev->sdev->id.revision >= 5) { + if (awake && dev->dev->core_rev >= 5) { /* Wait for the microcode to wake up. */ for (i = 0; i < 100; i++) { ucstat = b43_shm_read16(dev, B43_SHM_SHARED, @@ -1144,35 +1155,65 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) } } -static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) +#ifdef CONFIG_B43_BCMA +static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode) +{ + u32 flags = 0; + + if (gmode) + flags = B43_BCMA_IOCTL_GMODE; + flags |= B43_BCMA_IOCTL_PHY_CLKEN; + flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */ + b43_device_enable(dev, flags); + + /* TODO: reset PHY */ +} +#endif + +static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) { + struct ssb_device *sdev = dev->dev->sdev; u32 tmslow; + u32 flags = 0; + if (gmode) + flags |= B43_TMSLOW_GMODE; flags |= B43_TMSLOW_PHYCLKEN; flags |= B43_TMSLOW_PHYRESET; if (dev->phy.type == B43_PHYTYPE_N) flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ - ssb_device_enable(dev->sdev, flags); + b43_device_enable(dev, flags); msleep(2); /* Wait for the PLL to turn on. */ /* Now take the PHY out of Reset again */ - tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); + tmslow = ssb_read32(sdev, SSB_TMSLOW); tmslow |= SSB_TMSLOW_FGC; tmslow &= ~B43_TMSLOW_PHYRESET; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); - ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ + ssb_write32(sdev, SSB_TMSLOW, tmslow); + ssb_read32(sdev, SSB_TMSLOW); /* flush */ msleep(1); tmslow &= ~SSB_TMSLOW_FGC; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); - ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ + ssb_write32(sdev, SSB_TMSLOW, tmslow); + ssb_read32(sdev, SSB_TMSLOW); /* flush */ msleep(1); } -void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) +void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode) { u32 macctl; - b43_ssb_wireless_core_reset(dev, flags); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + b43_bcma_wireless_core_reset(dev, gmode); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + b43_ssb_wireless_core_reset(dev, gmode); + break; +#endif + } /* Turn Analog ON, but only if we already know the PHY-type. * This protects against very early setup where we don't know the @@ -1183,7 +1224,7 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) macctl = b43_read32(dev, B43_MMIO_MACCTL); macctl &= ~B43_MACCTL_GMODE; - if (flags & B43_TMSLOW_GMODE) + if (gmode) macctl |= B43_MACCTL_GMODE; macctl |= B43_MACCTL_IHR_ENABLED; b43_write32(dev, B43_MMIO_MACCTL, macctl); @@ -1221,7 +1262,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev) { u32 dummy; - if (dev->sdev->id.revision < 5) + if (dev->dev->core_rev < 5) return; /* Read all entries from the microcode TXstatus FIFO * and throw them away. @@ -1427,9 +1468,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev, /* Get the mask of available antennas. */ if (dev->phy.gmode) - antenna_mask = dev->sdev->bus->sprom.ant_available_bg; + antenna_mask = dev->dev->bus_sprom->ant_available_bg; else - antenna_mask = dev->sdev->bus->sprom.ant_available_a; + antenna_mask = dev->dev->bus_sprom->ant_available_a; if (!(antenna_mask & (1 << (antenna_nr - 1)))) { /* This antenna is not available. Fall back to default. */ @@ -1644,7 +1685,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) mutex_lock(&wl->mutex); dev = wl->current_dev; if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { /* wl->mutex is enough. */ b43_do_beacon_update_trigger_work(dev); mmiowb(); @@ -1689,7 +1730,7 @@ static void b43_update_templates(struct b43_wl *wl) static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) { b43_time_lock(dev); - if (dev->sdev->id.revision >= 3) { + if (dev->dev->core_rev >= 3) { b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); } else { @@ -1923,7 +1964,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; reason &= dev->irq_mask; if (!reason) - return IRQ_HANDLED; + return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) & 0x0001DC00; @@ -2063,7 +2104,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, B43_WARN_ON(1); return -ENOSYS; } - err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev); + err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); if (err == -ENOENT) { snprintf(ctx->errors[ctx->req_type], sizeof(ctx->errors[ctx->req_type]), @@ -2113,26 +2154,48 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) { struct b43_wldev *dev = ctx->dev; struct b43_firmware *fw = &ctx->dev->fw; - const u8 rev = ctx->dev->sdev->id.revision; + const u8 rev = ctx->dev->dev->core_rev; const char *filename; u32 tmshigh; int err; + /* Files for HT and LCN were found by trying one by one */ + /* Get microcode */ - if ((rev >= 5) && (rev <= 10)) + if ((rev >= 5) && (rev <= 10)) { filename = "ucode5"; - else if ((rev >= 11) && (rev <= 12)) + } else if ((rev >= 11) && (rev <= 12)) { filename = "ucode11"; - else if (rev == 13) + } else if (rev == 13) { filename = "ucode13"; - else if (rev == 14) + } else if (rev == 14) { filename = "ucode14"; - else if (rev == 15) + } else if (rev == 15) { filename = "ucode15"; - else if ((rev >= 16) && (rev <= 20)) - filename = "ucode16_mimo"; - else - goto err_no_ucode; + } else { + switch (dev->phy.type) { + case B43_PHYTYPE_N: + if (rev >= 16) + filename = "ucode16_mimo"; + else + goto err_no_ucode; + break; + case B43_PHYTYPE_HT: + if (rev == 29) + filename = "ucode29_mimo"; + else + goto err_no_ucode; + break; + case B43_PHYTYPE_LCN: + if (rev == 24) + filename = "ucode24_mimo"; + else + goto err_no_ucode; + break; + default: + goto err_no_ucode; + } + } err = b43_do_request_fw(ctx, filename, &fw->ucode); if (err) goto err_load; @@ -2157,7 +2220,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) switch (dev->phy.type) { case B43_PHYTYPE_A: if ((rev >= 5) && (rev <= 10)) { - tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); + tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) filename = "a0g1initvals5"; else @@ -2191,6 +2254,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) else goto err_no_initvals; break; + case B43_PHYTYPE_HT: + if (rev == 29) + filename = "ht0initvals29"; + else + goto err_no_initvals; + break; + case B43_PHYTYPE_LCN: + if (rev == 24) + filename = "lcn0initvals24"; + else + goto err_no_initvals; + break; default: goto err_no_initvals; } @@ -2202,7 +2277,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) switch (dev->phy.type) { case B43_PHYTYPE_A: if ((rev >= 5) && (rev <= 10)) { - tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); + tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) filename = "a0g1bsinitvals5"; else @@ -2238,6 +2313,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) else goto err_no_initvals; break; + case B43_PHYTYPE_HT: + if (rev == 29) + filename = "ht0bsinitvals29"; + else + goto err_no_initvals; + break; + case B43_PHYTYPE_LCN: + if (rev == 24) + filename = "lcn0bsinitvals24"; + else + goto err_no_initvals; + break; default: goto err_no_initvals; } @@ -2448,7 +2535,7 @@ static int b43_upload_microcode(struct b43_wldev *dev) snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", dev->fw.rev, dev->fw.patch); - wiphy->hw_version = dev->sdev->id.coreid; + wiphy->hw_version = dev->dev->core_id; if (b43_is_old_txhdr_format(dev)) { /* We're over the deadline, but we keep support for old fw @@ -2566,7 +2653,7 @@ out: */ static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; #ifdef CONFIG_SSB_DRIVER_PCICORE return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); @@ -2588,7 +2675,7 @@ static int b43_gpio_init(struct b43_wldev *dev) mask = 0x0000001F; set = 0x0000000F; - if (dev->sdev->bus->chip_id == 0x4301) { + if (dev->dev->chip_id == 0x4301) { mask |= 0x0060; set |= 0x0060; } @@ -2599,21 +2686,34 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0180; set |= 0x0180; } - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) | 0x0200); mask |= 0x0200; set |= 0x0200; } - if (dev->sdev->id.revision >= 2) + if (dev->dev->core_rev >= 2) mask |= 0x0010; /* FIXME: This is redundant. */ - gpiodev = b43_ssb_gpio_dev(dev); - if (gpiodev) - ssb_write32(gpiodev, B43_GPIO_CONTROL, - (ssb_read32(gpiodev, B43_GPIO_CONTROL) - & mask) | set); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, + (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, + BCMA_CC_GPIOCTL) & mask) | set); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + gpiodev = b43_ssb_gpio_dev(dev); + if (gpiodev) + ssb_write32(gpiodev, B43_GPIO_CONTROL, + (ssb_read32(gpiodev, B43_GPIO_CONTROL) + & mask) | set); + break; +#endif + } return 0; } @@ -2623,9 +2723,21 @@ static void b43_gpio_cleanup(struct b43_wldev *dev) { struct ssb_device *gpiodev; - gpiodev = b43_ssb_gpio_dev(dev); - if (gpiodev) - ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, + 0); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + gpiodev = b43_ssb_gpio_dev(dev); + if (gpiodev) + ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); + break; +#endif + } } /* http://bcm-specs.sipsolutions.net/EnableMac */ @@ -2697,12 +2809,30 @@ out: /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) { - u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); - if (on) - tmslow |= B43_TMSLOW_MACPHYCLKEN; - else - tmslow &= ~B43_TMSLOW_MACPHYCLKEN; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); + u32 tmp; + + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL); + if (on) + tmp |= B43_BCMA_IOCTL_MACPHYCLKEN; + else + tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN; + bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + if (on) + tmp |= B43_TMSLOW_MACPHYCLKEN; + else + tmp &= ~B43_TMSLOW_MACPHYCLKEN; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + break; +#endif + } } static void b43_adjust_opmode(struct b43_wldev *dev) @@ -2741,15 +2871,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev) /* Workaround: On old hardware the HW-MAC-address-filter * doesn't work properly, so always run promisc in filter * it in software. */ - if (dev->sdev->id.revision <= 4) + if (dev->dev->core_rev <= 4) ctl |= B43_MACCTL_PROMISC; b43_write32(dev, B43_MMIO_MACCTL, ctl); cfp_pretbtt = 2; if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { - if (dev->sdev->bus->chip_id == 0x4306 && - dev->sdev->bus->chip_rev == 3) + if (dev->dev->chip_id == 0x4306 && + dev->dev->chip_rev == 3) cfp_pretbtt = 100; else cfp_pretbtt = 50; @@ -2907,7 +3037,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write16(dev, 0x005E, value16); } b43_write32(dev, 0x0100, 0x01000000); - if (dev->sdev->id.revision < 5) + if (dev->dev->core_rev < 5) b43_write32(dev, 0x010C, 0x01000000); b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) @@ -2922,7 +3052,7 @@ static int b43_chip_init(struct b43_wldev *dev) /* Initially set the wireless operation mode. */ b43_adjust_opmode(dev); - if (dev->sdev->id.revision < 3) { + if (dev->dev->core_rev < 3) { b43_write16(dev, 0x060E, 0x0000); b43_write16(dev, 0x0610, 0x8000); b43_write16(dev, 0x0604, 0x0000); @@ -2941,8 +3071,20 @@ static int b43_chip_init(struct b43_wldev *dev) b43_mac_phy_clock_set(dev, true); - b43_write16(dev, B43_MMIO_POWERUP_DELAY, - dev->sdev->bus->chipco.fast_pwrup_delay); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + /* FIXME: 0xE74 is quite common, but should be read from CC */ + b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + b43_write16(dev, B43_MMIO_POWERUP_DELAY, + dev->dev->sdev->bus->chipco.fast_pwrup_delay); + break; +#endif + } err = 0; b43dbg(dev->wl, "Chip initialized\n"); @@ -3105,7 +3247,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev) b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); - if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) { + if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) { /* The 32bit register shadows the two 16bit registers * with update sideeffects. Validate this. */ b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); @@ -3458,21 +3600,33 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) static void b43_put_phy_into_reset(struct b43_wldev *dev) { - struct ssb_device *sdev = dev->sdev; - u32 tmslow; + u32 tmp; - tmslow = ssb_read32(sdev, SSB_TMSLOW); - tmslow &= ~B43_TMSLOW_GMODE; - tmslow |= B43_TMSLOW_PHYRESET; - tmslow |= SSB_TMSLOW_FGC; - ssb_write32(sdev, SSB_TMSLOW, tmslow); - msleep(1); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + b43err(dev->wl, + "Putting PHY into reset not supported on BCMA\n"); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + tmp &= ~B43_TMSLOW_GMODE; + tmp |= B43_TMSLOW_PHYRESET; + tmp |= SSB_TMSLOW_FGC; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + msleep(1); + + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + tmp &= ~SSB_TMSLOW_FGC; + tmp |= B43_TMSLOW_PHYRESET; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + msleep(1); - tmslow = ssb_read32(sdev, SSB_TMSLOW); - tmslow &= ~SSB_TMSLOW_FGC; - tmslow |= B43_TMSLOW_PHYRESET; - ssb_write32(sdev, SSB_TMSLOW, tmslow); - msleep(1); + break; +#endif + } } static const char *band_to_string(enum ieee80211_band band) @@ -3954,7 +4108,7 @@ redo: /* Disable interrupts on the device. */ b43_set_status(dev, B43_STAT_INITIALIZED); - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { /* wl->mutex is locked. That is enough. */ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ @@ -3967,11 +4121,11 @@ redo: /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ orig_dev = dev; mutex_unlock(&wl->mutex); - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { b43_sdio_free_irq(dev); } else { - synchronize_irq(dev->sdev->irq); - free_irq(dev->sdev->irq, dev); + synchronize_irq(dev->dev->irq); + free_irq(dev->dev->irq, dev); } mutex_lock(&wl->mutex); dev = wl->current_dev; @@ -4004,19 +4158,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev) B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); drain_txstatus_queue(dev); - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); if (err) { b43err(dev->wl, "Cannot request SDIO IRQ\n"); goto out; } } else { - err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler, + err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, b43_interrupt_thread_handler, IRQF_SHARED, KBUILD_MODNAME, dev); if (err) { b43err(dev->wl, "Cannot request IRQ-%d\n", - dev->sdev->irq); + dev->dev->irq); goto out; } } @@ -4083,9 +4237,21 @@ static int b43_phy_versioning(struct b43_wldev *dev) unsupported = 1; break; #endif +#ifdef CONFIG_B43_PHY_HT + case B43_PHYTYPE_HT: + if (phy_rev > 1) + unsupported = 1; + break; +#endif +#ifdef CONFIG_B43_PHY_LCN + case B43_PHYTYPE_LCN: + if (phy_rev > 1) + unsupported = 1; + break; +#endif default: unsupported = 1; - }; + } if (unsupported) { b43err(dev->wl, "FOUND UNSUPPORTED PHY " "(Analog %u, Type %u, Revision %u)\n", @@ -4096,22 +4262,42 @@ static int b43_phy_versioning(struct b43_wldev *dev) analog_type, phy_type, phy_rev); /* Get RADIO versioning */ - if (dev->sdev->bus->chip_id == 0x4317) { - if (dev->sdev->bus->chip_rev == 0) - tmp = 0x3205017F; - else if (dev->sdev->bus->chip_rev == 1) - tmp = 0x4205017F; - else - tmp = 0x5205017F; + if (dev->dev->core_rev >= 24) { + u16 radio24[3]; + + for (tmp = 0; tmp < 3; tmp++) { + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp); + radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); + } + + /* Broadcom uses "id" for our "ver" and has separated "ver" */ + /* radio_ver = (radio24[0] & 0xF0) >> 4; */ + + radio_manuf = 0x17F; + radio_ver = (radio24[2] << 8) | radio24[1]; + radio_rev = (radio24[0] & 0xF); } else { - b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); - tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); - b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); - tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16; - } - radio_manuf = (tmp & 0x00000FFF); - radio_ver = (tmp & 0x0FFFF000) >> 12; - radio_rev = (tmp & 0xF0000000) >> 28; + if (dev->dev->chip_id == 0x4317) { + if (dev->dev->chip_rev == 0) + tmp = 0x3205017F; + else if (dev->dev->chip_rev == 1) + tmp = 0x4205017F; + else + tmp = 0x5205017F; + } else { + b43_write16(dev, B43_MMIO_RADIO_CONTROL, + B43_RADIOCTL_ID); + tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); + b43_write16(dev, B43_MMIO_RADIO_CONTROL, + B43_RADIOCTL_ID); + tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) + << 16; + } + radio_manuf = (tmp & 0x00000FFF); + radio_ver = (tmp & 0x0FFFF000) >> 12; + radio_rev = (tmp & 0xF0000000) >> 28; + } + if (radio_manuf != 0x17F /* Broadcom */) unsupported = 1; switch (phy_type) { @@ -4139,6 +4325,14 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (radio_ver != 0x2062 && radio_ver != 0x2063) unsupported = 1; break; + case B43_PHYTYPE_HT: + if (radio_ver != 0x2059) + unsupported = 1; + break; + case B43_PHYTYPE_LCN: + if (radio_ver != 0x2064) + unsupported = 1; + break; default: B43_WARN_ON(1); } @@ -4204,7 +4398,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev) static void b43_bluetooth_coext_enable(struct b43_wldev *dev) { - struct ssb_sprom *sprom = &dev->sdev->bus->sprom; + struct ssb_sprom *sprom = dev->dev->bus_sprom; u64 hf; if (!modparam_btcoex) @@ -4231,16 +4425,21 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev) static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus; u32 tmp; + if (dev->dev->bus_type != B43_BUS_SSB) + return; + + bus = dev->dev->sdev->bus; + if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || (bus->chip_id == 0x4312)) { - tmp = ssb_read32(dev->sdev, SSB_IMCFGLO); + tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO); tmp &= ~SSB_IMCFGLO_REQTO; tmp &= ~SSB_IMCFGLO_SERTO; tmp |= 0x3; - ssb_write32(dev->sdev, SSB_IMCFGLO, tmp); + ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp); ssb_commit_settings(bus); } } @@ -4310,36 +4509,45 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) dev->wl->current_beacon = NULL; } - ssb_device_disable(dev->sdev, 0); - ssb_bus_may_powerdown(dev->sdev->bus); + b43_device_disable(dev, 0); + b43_bus_may_powerdown(dev); } /* Initialize a wireless core */ static int b43_wireless_core_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; - struct ssb_sprom *sprom = &bus->sprom; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; int err; u64 hf; - u32 tmp; B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); - err = ssb_bus_powerup(bus, 0); + err = b43_bus_powerup(dev, 0); if (err) goto out; - if (!ssb_device_is_enabled(dev->sdev)) { - tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; - b43_wireless_core_reset(dev, tmp); - } + if (!b43_device_is_enabled(dev)) + b43_wireless_core_reset(dev, phy->gmode); /* Reset all data structures. */ setup_struct_wldev_for_init(dev); phy->ops->prepare_structs(dev); /* Enable IRQ routing to this device. */ - ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci, + dev->dev->bdev, true); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore, + dev->dev->sdev); + break; +#endif + } b43_imcfglo_timeouts_workaround(dev); b43_bluetooth_coext_disable(dev); @@ -4352,7 +4560,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) if (err) goto err_busdown; b43_shm_write16(dev, B43_SHM_SHARED, - B43_SHM_SH_WLCOREREV, dev->sdev->id.revision); + B43_SHM_SH_WLCOREREV, dev->dev->core_rev); hf = b43_hf_read(dev); if (phy->type == B43_PHYTYPE_G) { hf |= B43_HF_SYMW; @@ -4370,8 +4578,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev) if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ #ifdef CONFIG_SSB_DRIVER_PCICORE - if ((bus->bustype == SSB_BUSTYPE_PCI) && - (bus->pcicore.dev->id.revision <= 10)) + if (dev->dev->bus_type == B43_BUS_SSB && + dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && + dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */ #endif hf &= ~B43_HF_SKCFPUP; @@ -4399,8 +4608,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) /* Maximum Contention Window */ b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); - if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) || - (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) || + if (b43_bus_host_is_pcmcia(dev->dev) || + b43_bus_host_is_sdio(dev->dev) || dev->use_pio) { dev->__using_pio_transfers = 1; err = b43_pio_init(dev); @@ -4414,7 +4623,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) b43_set_synth_pu_delay(dev, 1); b43_bluetooth_coext_enable(dev); - ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); + b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); b43_upload_card_macaddress(dev); b43_security_init(dev); @@ -4431,7 +4640,7 @@ out: err_chip_exit: b43_chip_exit(dev); err_busdown: - ssb_bus_may_powerdown(bus); + b43_bus_may_powerdown(dev); B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); return err; } @@ -4737,11 +4946,9 @@ static void b43_wireless_core_detach(struct b43_wldev *dev) static int b43_wireless_core_attach(struct b43_wldev *dev) { struct b43_wl *wl = dev->wl; - struct ssb_bus *bus = dev->sdev->bus; - struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; + struct pci_dev *pdev = NULL; int err; bool have_2ghz_phy = 0, have_5ghz_phy = 0; - u32 tmp; /* Do NOT do any device initialization here. * Do it in wireless_core_init() instead. @@ -4750,25 +4957,42 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) * that in core_init(), too. */ - err = ssb_bus_powerup(bus, 0); +#ifdef CONFIG_B43_SSB + if (dev->dev->bus_type == B43_BUS_SSB && + dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI) + pdev = dev->dev->sdev->bus->host_pci; +#endif + + err = b43_bus_powerup(dev, 0); if (err) { b43err(wl, "Bus powerup failed\n"); goto out; } - /* Get the PHY type. */ - if (dev->sdev->id.revision >= 5) { - u32 tmshigh; - tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); - have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); - have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); - } else - B43_WARN_ON(1); + /* Get the PHY type. */ + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + /* FIXME */ + have_2ghz_phy = 1; + have_5ghz_phy = 0; + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + if (dev->dev->core_rev >= 5) { + u32 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); + have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); + have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); + } else + B43_WARN_ON(1); + break; +#endif + } dev->phy.gmode = have_2ghz_phy; dev->phy.radio_on = 1; - tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; - b43_wireless_core_reset(dev, tmp); + b43_wireless_core_reset(dev, dev->phy.gmode); err = b43_phy_versioning(dev); if (err) @@ -4790,6 +5014,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) #endif case B43_PHYTYPE_G: case B43_PHYTYPE_N: + case B43_PHYTYPE_HT: + case B43_PHYTYPE_LCN: have_2ghz_phy = 1; break; default: @@ -4816,8 +5042,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) goto err_powerdown; dev->phy.gmode = have_2ghz_phy; - tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; - b43_wireless_core_reset(dev, tmp); + b43_wireless_core_reset(dev, dev->phy.gmode); err = b43_validate_chipaccess(dev); if (err) @@ -4832,8 +5057,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) INIT_WORK(&dev->restart_work, b43_chip_reset); dev->phy.ops->switch_analog(dev, 0); - ssb_device_disable(dev->sdev, 0); - ssb_bus_may_powerdown(bus); + b43_device_disable(dev, 0); + b43_bus_may_powerdown(dev); out: return err; @@ -4841,11 +5066,11 @@ out: err_phy_free: b43_phy_free(dev); err_powerdown: - ssb_bus_may_powerdown(bus); + b43_bus_may_powerdown(dev); return err; } -static void b43_one_core_detach(struct ssb_device *dev) +static void b43_one_core_detach(struct b43_bus_dev *dev) { struct b43_wldev *wldev; struct b43_wl *wl; @@ -4853,17 +5078,17 @@ static void b43_one_core_detach(struct ssb_device *dev) /* Do not cancel ieee80211-workqueue based work here. * See comment in b43_remove(). */ - wldev = ssb_get_drvdata(dev); + wldev = b43_bus_get_wldev(dev); wl = wldev->wl; b43_debugfs_remove_device(wldev); b43_wireless_core_detach(wldev); list_del(&wldev->list); wl->nr_devs--; - ssb_set_drvdata(dev, NULL); + b43_bus_set_wldev(dev, NULL); kfree(wldev); } -static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) +static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl) { struct b43_wldev *wldev; int err = -ENOMEM; @@ -4873,7 +5098,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) goto out; wldev->use_pio = b43_modparam_pio; - wldev->sdev = dev; + wldev->dev = dev; wldev->wl = wl; b43_set_status(wldev, B43_STAT_UNINIT); wldev->bad_frames_preempt = modparam_bad_frames_preempt; @@ -4885,7 +5110,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) list_add(&wldev->list, &wl->devlist); wl->nr_devs++; - ssb_set_drvdata(dev, wldev); + b43_bus_set_wldev(dev, wldev); b43_debugfs_add_device(wldev); out: @@ -4926,17 +5151,17 @@ static void b43_sprom_fixup(struct ssb_bus *bus) } } -static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) +static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl) { struct ieee80211_hw *hw = wl->hw; - ssb_set_devtypedata(dev, NULL); + ssb_set_devtypedata(dev->sdev, NULL); ieee80211_free_hw(hw); } -static struct b43_wl *b43_wireless_init(struct ssb_device *dev) +static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) { - struct ssb_sprom *sprom = &dev->bus->sprom; + struct ssb_sprom *sprom = dev->bus_sprom; struct ieee80211_hw *hw; struct b43_wl *wl; @@ -4978,28 +5203,62 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev) skb_queue_head_init(&wl->tx_queue); b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", - dev->bus->chip_id, dev->id.revision); + dev->chip_id, dev->core_rev); return wl; } -static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) +#ifdef CONFIG_B43_BCMA +static int b43_bcma_probe(struct bcma_device *core) +{ + struct b43_bus_dev *dev; + + dev = b43_bus_dev_bcma_init(core); + if (!dev) + return -ENODEV; + + b43err(NULL, "BCMA is not supported yet!"); + kfree(dev); + return -EOPNOTSUPP; +} + +static void b43_bcma_remove(struct bcma_device *core) +{ + /* TODO */ +} + +static struct bcma_driver b43_bcma_driver = { + .name = KBUILD_MODNAME, + .id_table = b43_bcma_tbl, + .probe = b43_bcma_probe, + .remove = b43_bcma_remove, +}; +#endif + +#ifdef CONFIG_B43_SSB +static +int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) { + struct b43_bus_dev *dev; struct b43_wl *wl; int err; int first = 0; - wl = ssb_get_devtypedata(dev); + dev = b43_bus_dev_ssb_init(sdev); + if (!dev) + return -ENOMEM; + + wl = ssb_get_devtypedata(sdev); if (!wl) { /* Probing the first core. Must setup common struct b43_wl */ first = 1; - b43_sprom_fixup(dev->bus); + b43_sprom_fixup(sdev->bus); wl = b43_wireless_init(dev); if (IS_ERR(wl)) { err = PTR_ERR(wl); goto out; } - ssb_set_devtypedata(dev, wl); - B43_WARN_ON(ssb_get_devtypedata(dev) != wl); + ssb_set_devtypedata(sdev, wl); + B43_WARN_ON(ssb_get_devtypedata(sdev) != wl); } err = b43_one_core_attach(dev, wl); if (err) @@ -5023,10 +5282,10 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) return err; } -static void b43_ssb_remove(struct ssb_device *dev) +static void b43_ssb_remove(struct ssb_device *sdev) { - struct b43_wl *wl = ssb_get_devtypedata(dev); - struct b43_wldev *wldev = ssb_get_drvdata(dev); + struct b43_wl *wl = ssb_get_devtypedata(sdev); + struct b43_wldev *wldev = ssb_get_drvdata(sdev); /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ @@ -5042,17 +5301,25 @@ static void b43_ssb_remove(struct ssb_device *dev) ieee80211_unregister_hw(wl->hw); } - b43_one_core_detach(dev); + b43_one_core_detach(wldev->dev); if (list_empty(&wl->devlist)) { b43_leds_unregister(wl); /* Last core on the chip unregistered. * We can destroy common struct b43_wl. */ - b43_wireless_exit(dev, wl); + b43_wireless_exit(wldev->dev, wl); } } +static struct ssb_driver b43_ssb_driver = { + .name = KBUILD_MODNAME, + .id_table = b43_ssb_tbl, + .probe = b43_ssb_probe, + .remove = b43_ssb_remove, +}; +#endif /* CONFIG_B43_SSB */ + /* Perform a hardware reset. This can be called from any context. */ void b43_controller_restart(struct b43_wldev *dev, const char *reason) { @@ -5063,13 +5330,6 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason) ieee80211_queue_work(dev->wl->hw, &dev->restart_work); } -static struct ssb_driver b43_ssb_driver = { - .name = KBUILD_MODNAME, - .id_table = b43_ssb_tbl, - .probe = b43_ssb_probe, - .remove = b43_ssb_remove, -}; - static void b43_print_driverinfo(void) { const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", @@ -5108,14 +5368,27 @@ static int __init b43_init(void) err = b43_sdio_init(); if (err) goto err_pcmcia_exit; - err = ssb_driver_register(&b43_ssb_driver); +#ifdef CONFIG_B43_BCMA + err = bcma_driver_register(&b43_bcma_driver); if (err) goto err_sdio_exit; +#endif +#ifdef CONFIG_B43_SSB + err = ssb_driver_register(&b43_ssb_driver); + if (err) + goto err_bcma_driver_exit; +#endif b43_print_driverinfo(); return err; +#ifdef CONFIG_B43_SSB +err_bcma_driver_exit: +#endif +#ifdef CONFIG_B43_BCMA + bcma_driver_unregister(&b43_bcma_driver); err_sdio_exit: +#endif b43_sdio_exit(); err_pcmcia_exit: b43_pcmcia_exit(); @@ -5126,7 +5399,12 @@ err_dfs_exit: static void __exit b43_exit(void) { +#ifdef CONFIG_B43_SSB ssb_driver_unregister(&b43_ssb_driver); +#endif +#ifdef CONFIG_B43_BCMA + bcma_driver_unregister(&b43_bcma_driver); +#endif b43_sdio_exit(); b43_pcmcia_exit(); b43_debugfs_exit(); diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index a0d327f13183..e4ebce9be592 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h @@ -121,7 +121,7 @@ void b43_hf_write(struct b43_wldev *dev, u64 value); void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on); -void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags); +void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode); void b43_controller_restart(struct b43_wldev *dev, const char *reason); diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index b01c8ced57c3..73ace5552bad 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c @@ -265,7 +265,6 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev) void b43_phy_inita(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; /* This lowlevel A-PHY init is also called from G-PHY init. @@ -296,9 +295,9 @@ void b43_phy_inita(struct b43_wldev *dev) b43_radio_init2060(dev); - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - ((bus->boardinfo.type == SSB_BOARD_BU4306) || - (bus->boardinfo.type == SSB_BOARD_BU4309))) { + if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && + ((dev->dev->board_type == SSB_BOARD_BU4306) || + (dev->dev->board_type == SSB_BOARD_BU4309))) { ; //TODO: A PHY LO } @@ -311,7 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev) } if ((phy->type == B43_PHYTYPE_G) && - (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { + (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)) { b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); } } @@ -323,17 +322,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev) struct b43_phy_a *aphy = phy->a; s16 pab0, pab1, pab2; - pab0 = (s16) (dev->sdev->bus->sprom.pa1b0); - pab1 = (s16) (dev->sdev->bus->sprom.pa1b1); - pab2 = (s16) (dev->sdev->bus->sprom.pa1b2); + pab0 = (s16) (dev->dev->bus_sprom->pa1b0); + pab1 = (s16) (dev->dev->bus_sprom->pa1b1); + pab2 = (s16) (dev->dev->bus_sprom->pa1b2); if (pab0 != 0 && pab1 != 0 && pab2 != 0 && pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ - if ((s8) dev->sdev->bus->sprom.itssi_a != 0 && - (s8) dev->sdev->bus->sprom.itssi_a != -1) + if ((s8) dev->dev->bus_sprom->itssi_a != 0 && + (s8) dev->dev->bus_sprom->itssi_a != -1) aphy->tgt_idle_tssi = - (s8) (dev->sdev->bus->sprom.itssi_a); + (s8) (dev->dev->bus_sprom->itssi_a); else aphy->tgt_idle_tssi = 62; aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index e46b2f4f0920..101957512bcc 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -31,6 +31,8 @@ #include "phy_a.h" #include "phy_n.h" #include "phy_lp.h" +#include "phy_ht.h" +#include "phy_lcn.h" #include "b43.h" #include "main.h" @@ -59,6 +61,16 @@ int b43_phy_allocate(struct b43_wldev *dev) phy->ops = &b43_phyops_lp; #endif break; + case B43_PHYTYPE_HT: +#ifdef CONFIG_B43_PHY_HT + phy->ops = &b43_phyops_ht; +#endif + break; + case B43_PHYTYPE_LCN: +#ifdef CONFIG_B43_PHY_LCN + phy->ops = &b43_phyops_lcn; +#endif + break; } if (B43_WARN_ON(!phy->ops)) return -ENODEV; @@ -168,7 +180,7 @@ void b43_phy_lock(struct b43_wldev *dev) B43_WARN_ON(dev->phy.phy_locked); dev->phy.phy_locked = 1; #endif - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); @@ -180,7 +192,7 @@ void b43_phy_unlock(struct b43_wldev *dev) B43_WARN_ON(!dev->phy.phy_locked); dev->phy.phy_locked = 0; #endif - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) b43_power_saving_ctl_bits(dev, 0); @@ -368,8 +380,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) /* The next check will be needed in two seconds, or later. */ phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); - if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306)) + if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && + (dev->dev->board_type == SSB_BOARD_BU4306)) return; /* No software txpower adjustment needed */ result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 2401bee8b081..aa77ba612a92 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -194,6 +194,8 @@ struct b43_phy_a; struct b43_phy_g; struct b43_phy_n; struct b43_phy_lp; +struct b43_phy_ht; +struct b43_phy_lcn; struct b43_phy { /* Hardware operation callbacks. */ @@ -216,6 +218,10 @@ struct b43_phy { struct b43_phy_n *n; /* LP-PHY specific information */ struct b43_phy_lp *lp; + /* HT-PHY specific information */ + struct b43_phy_ht *ht; + /* LCN-PHY specific information */ + struct b43_phy_lcn *lcn; }; /* Band support flags. */ diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 1758a282f913..83532d19347f 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev) B43_WARN_ON(phy->type != B43_PHYTYPE_G); if (!phy->gmode || - !(dev->sdev->bus->sprom.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; @@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, { struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_sprom *sprom = dev->dev->bus_sprom; if (!phy->gmode) return 0; @@ -1491,7 +1491,6 @@ static u16 b43_radio_init2050(struct b43_wldev *dev) static void b43_phy_initb5(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; u16 offset, value; @@ -1500,8 +1499,8 @@ static void b43_phy_initb5(struct b43_wldev *dev) if (phy->analog == 1) { b43_radio_set(dev, 0x007A, 0x0050); } - if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type != SSB_BOARD_BU4306)) { + if ((dev->dev->board_vendor != SSB_BOARDVENDOR_BCM) && + (dev->dev->board_type != SSB_BOARD_BU4306)) { value = 0x2120; for (offset = 0x00A8; offset < 0x00C7; offset++) { b43_phy_write(dev, offset, value); @@ -1620,7 +1619,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->sdev->bus->sprom.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 { @@ -1787,7 +1786,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) { if (phy->rev >= 7) { b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); @@ -1922,7 +1921,6 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) /* Initialize B/G PHY power control */ static void b43_phy_init_pctl(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; struct b43_rfatt old_rfatt; @@ -1931,8 +1929,8 @@ static void b43_phy_init_pctl(struct b43_wldev *dev) B43_WARN_ON(phy->type != B43_PHYTYPE_G); - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type == SSB_BOARD_BU4306)) + if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && + (dev->dev->board_type == SSB_BOARD_BU4306)) return; b43_phy_write(dev, 0x0028, 0x8018); @@ -2053,7 +2051,7 @@ static void b43_phy_initg(struct b43_wldev *dev) if (phy->rev >= 6) { b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); } - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) + 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); @@ -2066,7 +2064,7 @@ static void b43_phy_initg(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); } - if (!(dev->sdev->bus->sprom.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. @@ -2088,8 +2086,8 @@ static void b43_phy_initg(struct b43_wldev *dev) /* FIXME: The spec says in the following if, the 0 should be replaced 'if OFDM may not be used in the current locale' but OFDM is legal everywhere */ - if ((dev->sdev->bus->chip_id == 0x4306 - && dev->sdev->bus->chip_package == 2) || 0) { + if ((dev->dev->chip_id == 0x4306 + && dev->dev->chip_pkg == 2) || 0) { b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); } @@ -2105,7 +2103,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev, b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); if (channel == 14) { - if (dev->sdev->bus->sprom.country_code == + if (dev->dev->bus_sprom->country_code == SSB_SPROM1CCODE_JAPAN) b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACPR); @@ -2136,17 +2134,17 @@ static void default_baseband_attenuation(struct b43_wldev *dev, static void default_radio_attenuation(struct b43_wldev *dev, struct b43_rfatt *rf) { - struct ssb_bus *bus = dev->sdev->bus; + struct b43_bus_dev *bdev = dev->dev; struct b43_phy *phy = &dev->phy; rf->with_padmix = 0; - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && - bus->boardinfo.type == SSB_BOARD_BCM4309G) { - if (bus->boardinfo.rev < 0x43) { + if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM && + dev->dev->board_type == SSB_BOARD_BCM4309G) { + if (dev->dev->board_rev < 0x43) { rf->att = 2; return; - } else if (bus->boardinfo.rev < 0x51) { + } else if (dev->dev->board_rev < 0x51) { rf->att = 3; return; } @@ -2172,21 +2170,21 @@ static void default_radio_attenuation(struct b43_wldev *dev, return; case 1: if (phy->type == B43_PHYTYPE_G) { - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == SSB_BOARD_BCM4309G - && bus->boardinfo.rev >= 30) + if (bdev->board_vendor == SSB_BOARDVENDOR_BCM + && bdev->board_type == SSB_BOARD_BCM4309G + && bdev->board_rev >= 30) rf->att = 3; - else if (bus->boardinfo.vendor == + else if (bdev->board_vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == + && bdev->board_type == SSB_BOARD_BU4306) rf->att = 3; else rf->att = 1; } else { - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == SSB_BOARD_BCM4309G - && bus->boardinfo.rev >= 30) + if (bdev->board_vendor == SSB_BOARDVENDOR_BCM + && bdev->board_type == SSB_BOARD_BCM4309G + && bdev->board_rev >= 30) rf->att = 7; else rf->att = 6; @@ -2194,16 +2192,16 @@ static void default_radio_attenuation(struct b43_wldev *dev, return; case 2: if (phy->type == B43_PHYTYPE_G) { - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == SSB_BOARD_BCM4309G - && bus->boardinfo.rev >= 30) + if (bdev->board_vendor == SSB_BOARDVENDOR_BCM + && bdev->board_type == SSB_BOARD_BCM4309G + && bdev->board_rev >= 30) rf->att = 3; - else if (bus->boardinfo.vendor == + else if (bdev->board_vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == + && bdev->board_type == SSB_BOARD_BU4306) rf->att = 5; - else if (bus->chip_id == 0x4320) + else if (bdev->chip_id == 0x4320) rf->att = 4; else rf->att = 3; @@ -2384,11 +2382,11 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) struct b43_phy_g *gphy = phy->g; s16 pab0, pab1, pab2; - pab0 = (s16) (dev->sdev->bus->sprom.pa0b0); - pab1 = (s16) (dev->sdev->bus->sprom.pa0b1); - pab2 = (s16) (dev->sdev->bus->sprom.pa0b2); + pab0 = (s16) (dev->dev->bus_sprom->pa0b0); + pab1 = (s16) (dev->dev->bus_sprom->pa0b1); + pab2 = (s16) (dev->dev->bus_sprom->pa0b2); - B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) && + B43_WARN_ON((dev->dev->chip_id == 0x4301) && (phy->radio_ver != 0x2050)); /* Not supported anymore */ gphy->dyn_tssi_tbl = 0; @@ -2396,10 +2394,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) if (pab0 != 0 && pab1 != 0 && pab2 != 0 && pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ - if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 && - (s8) dev->sdev->bus->sprom.itssi_bg != -1) { + if ((s8) dev->dev->bus_sprom->itssi_bg != 0 && + (s8) dev->dev->bus_sprom->itssi_bg != -1) { gphy->tgt_idle_tssi = - (s8) (dev->sdev->bus->sprom.itssi_bg); + (s8) (dev->dev->bus_sprom->itssi_bg); } else gphy->tgt_idle_tssi = 62; gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, @@ -2537,7 +2535,7 @@ static int b43_gphy_op_prepare_hardware(struct b43_wldev *dev) b43_wireless_core_reset(dev, 0); b43_phy_initg(dev); phy->gmode = 1; - b43_wireless_core_reset(dev, B43_TMSLOW_GMODE); + b43_wireless_core_reset(dev, 1); } return 0; @@ -2840,7 +2838,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev) B43_TXCTL_TXMIX; rfatt += 2; bbatt += 2; - } else if (dev->sdev->bus->sprom. + } else if (dev->dev->bus_sprom-> boardflags_lo & B43_BFL_PACTRL) { bbatt += 4 * (rfatt - 2); @@ -2914,14 +2912,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); B43_WARN_ON(phy->type != B43_PHYTYPE_G); - max_pwr = dev->sdev->bus->sprom.maxpwr_bg; - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) + max_pwr = dev->dev->bus_sprom->maxpwr_bg; + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) max_pwr -= 3; /* minus 0.75 */ if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { b43warn(dev->wl, "Invalid max-TX-power value in SPROM.\n"); max_pwr = INT_TO_Q52(20); /* fake it */ - dev->sdev->bus->sprom.maxpwr_bg = max_pwr; + dev->dev->bus_sprom->maxpwr_bg = max_pwr; } /* Get desired power (in Q5.2) */ @@ -3014,7 +3012,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; - if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) + if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) return; b43_mac_suspend(dev); diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c new file mode 100644 index 000000000000..29821036badf --- /dev/null +++ b/drivers/net/wireless/b43/phy_ht.c @@ -0,0 +1,406 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n HT-PHY support + + 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/slab.h> + +#include "b43.h" +#include "phy_ht.h" +#include "tables_phy_ht.h" +#include "radio_2059.h" +#include "main.h" + +/************************************************** + * Radio 2059. + **************************************************/ + +static void b43_radio_2059_channel_setup(struct b43_wldev *dev, + const struct b43_phy_ht_channeltab_e_radio2059 *e) +{ + u8 i; + u16 routing; + + b43_radio_write(dev, 0x16, e->radio_syn16); + b43_radio_write(dev, 0x17, e->radio_syn17); + b43_radio_write(dev, 0x22, e->radio_syn22); + b43_radio_write(dev, 0x25, e->radio_syn25); + b43_radio_write(dev, 0x27, e->radio_syn27); + b43_radio_write(dev, 0x28, e->radio_syn28); + b43_radio_write(dev, 0x29, e->radio_syn29); + b43_radio_write(dev, 0x2c, e->radio_syn2c); + b43_radio_write(dev, 0x2d, e->radio_syn2d); + b43_radio_write(dev, 0x37, e->radio_syn37); + b43_radio_write(dev, 0x41, e->radio_syn41); + b43_radio_write(dev, 0x43, e->radio_syn43); + b43_radio_write(dev, 0x47, e->radio_syn47); + b43_radio_write(dev, 0x4a, e->radio_syn4a); + b43_radio_write(dev, 0x58, e->radio_syn58); + b43_radio_write(dev, 0x5a, e->radio_syn5a); + b43_radio_write(dev, 0x6a, e->radio_syn6a); + b43_radio_write(dev, 0x6d, e->radio_syn6d); + b43_radio_write(dev, 0x6e, e->radio_syn6e); + b43_radio_write(dev, 0x92, e->radio_syn92); + b43_radio_write(dev, 0x98, e->radio_syn98); + + for (i = 0; i < 2; i++) { + routing = i ? R2059_RXRX1 : R2059_TXRX0; + b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a); + b43_radio_write(dev, routing | 0x58, e->radio_rxtx58); + b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a); + b43_radio_write(dev, routing | 0x6a, e->radio_rxtx6a); + b43_radio_write(dev, routing | 0x6d, e->radio_rxtx6d); + b43_radio_write(dev, routing | 0x6e, e->radio_rxtx6e); + b43_radio_write(dev, routing | 0x92, e->radio_rxtx92); + b43_radio_write(dev, routing | 0x98, e->radio_rxtx98); + } + + udelay(50); + + /* Calibration */ + b43_radio_mask(dev, 0x2b, ~0x1); + b43_radio_mask(dev, 0x2e, ~0x4); + b43_radio_set(dev, 0x2e, 0x4); + b43_radio_set(dev, 0x2b, 0x1); + + udelay(300); +} + +static void b43_radio_2059_init(struct b43_wldev *dev) +{ + const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 }; + const u16 radio_values[3][2] = { + { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, + }; + u16 i, j; + + b43_radio_write(dev, R2059_ALL | 0x51, 0x0070); + b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003); + + for (i = 0; i < ARRAY_SIZE(routing); i++) + b43_radio_set(dev, routing[i] | 0x146, 0x3); + + b43_radio_set(dev, 0x2e, 0x0078); + b43_radio_set(dev, 0xc0, 0x0080); + msleep(2); + b43_radio_mask(dev, 0x2e, ~0x0078); + b43_radio_mask(dev, 0xc0, ~0x0080); + + if (1) { /* FIXME */ + b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1); + udelay(10); + b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1); + b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2); + + b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2); + udelay(100); + b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2); + + for (i = 0; i < 10000; i++) { + if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) { + i = 0; + break; + } + udelay(100); + } + if (i) + b43err(dev->wl, "radio 0x945 timeout\n"); + + b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1); + b43_radio_set(dev, 0xa, 0x60); + + for (i = 0; i < 3; i++) { + b43_radio_write(dev, 0x17F, radio_values[i][0]); + b43_radio_write(dev, 0x13D, 0x6E); + b43_radio_write(dev, 0x13E, radio_values[i][1]); + b43_radio_write(dev, 0x13C, 0x55); + + for (j = 0; j < 10000; j++) { + if (b43_radio_read(dev, 0x140) & 2) { + j = 0; + break; + } + udelay(500); + } + if (j) + b43err(dev->wl, "radio 0x140 timeout\n"); + + b43_radio_write(dev, 0x13C, 0x15); + } + + b43_radio_mask(dev, 0x17F, ~0x1); + } + + b43_radio_mask(dev, 0x11, 0x0008); +} + +/************************************************** + * Channel switching ops. + **************************************************/ + +static void b43_phy_ht_channel_setup(struct b43_wldev *dev, + const struct b43_phy_ht_channeltab_e_phy *e, + struct ieee80211_channel *new_channel) +{ + bool old_band_5ghz; + u8 i; + + old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ + if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { + /* TODO */ + } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) { + /* TODO */ + } + + b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1); + b43_phy_write(dev, B43_PHY_HT_BW2, e->bw2); + b43_phy_write(dev, B43_PHY_HT_BW3, e->bw3); + b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4); + b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5); + b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6); + + /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */ + + /* TODO: separated function? */ + for (i = 0; i < 3; i++) { + u16 mask; + u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8)); + + if (0) /* FIXME */ + mask = 0x2 << (i * 4); + else + mask = 0; + b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask); + + b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16); + b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)), + tmp & 0xFF); + b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)), + tmp & 0xFF); + } + + b43_phy_write(dev, 0x017e, 0x3830); +} + +static int b43_phy_ht_set_channel(struct b43_wldev *dev, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type) +{ + struct b43_phy *phy = &dev->phy; + + const struct b43_phy_ht_channeltab_e_radio2059 *chent_r2059 = NULL; + + if (phy->radio_ver == 0x2059) { + chent_r2059 = b43_phy_ht_get_channeltab_e_r2059(dev, + channel->center_freq); + if (!chent_r2059) + return -ESRCH; + } else { + return -ESRCH; + } + + /* TODO: In case of N-PHY some bandwidth switching goes here */ + + if (phy->radio_ver == 0x2059) { + b43_radio_2059_channel_setup(dev, chent_r2059); + b43_phy_ht_channel_setup(dev, &(chent_r2059->phy_regs), + channel); + } else { + return -ESRCH; + } + + return 0; +} + +/************************************************** + * Basic PHY ops. + **************************************************/ + +static int b43_phy_ht_op_allocate(struct b43_wldev *dev) +{ + struct b43_phy_ht *phy_ht; + + phy_ht = kzalloc(sizeof(*phy_ht), GFP_KERNEL); + if (!phy_ht) + return -ENOMEM; + dev->phy.ht = phy_ht; + + return 0; +} + +static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_ht *phy_ht = phy->ht; + + memset(phy_ht, 0, sizeof(*phy_ht)); +} + +static int b43_phy_ht_op_init(struct b43_wldev *dev) +{ + b43_phy_ht_tables_init(dev); + + return 0; +} + +static void b43_phy_ht_op_free(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_ht *phy_ht = phy->ht; + + kfree(phy_ht); + phy->ht = NULL; +} + +/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */ +static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, + bool blocked) +{ + if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) + b43err(dev->wl, "MAC not suspended\n"); + + if (blocked) { + b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); + } else { + b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); + b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1); + b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); + b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2); + + if (dev->phy.radio_ver == 0x2059) + b43_radio_2059_init(dev); + else + B43_WARN_ON(1); + } +} + +static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) +{ + if (on) { + b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000); + } else { + b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd); + } +} + +static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev, + unsigned int new_channel) +{ + struct ieee80211_channel *channel = dev->wl->hw->conf.channel; + enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; + + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if ((new_channel < 1) || (new_channel > 14)) + return -EINVAL; + } else { + return -EINVAL; + } + + return b43_phy_ht_set_channel(dev, channel, channel_type); +} + +static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev) +{ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + return 1; + return 36; +} + +/************************************************** + * R/W ops. + **************************************************/ + +static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + return b43_read16(dev, B43_MMIO_PHY_DATA); +} + +static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, value); +} + +static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, + u16 set) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, + (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); +} + +static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg) +{ + /* HT-PHY needs 0x200 for read access */ + reg |= 0x200; + + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); + return b43_read16(dev, B43_MMIO_RADIO24_DATA); +} + +static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg, + u16 value) +{ + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); + b43_write16(dev, B43_MMIO_RADIO24_DATA, value); +} + +static enum b43_txpwr_result +b43_phy_ht_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi) +{ + return B43_TXPWR_RES_DONE; +} + +static void b43_phy_ht_op_adjust_txpower(struct b43_wldev *dev) +{ +} + +/************************************************** + * PHY ops struct. + **************************************************/ + +const struct b43_phy_operations b43_phyops_ht = { + .allocate = b43_phy_ht_op_allocate, + .free = b43_phy_ht_op_free, + .prepare_structs = b43_phy_ht_op_prepare_structs, + .init = b43_phy_ht_op_init, + .phy_read = b43_phy_ht_op_read, + .phy_write = b43_phy_ht_op_write, + .phy_maskset = b43_phy_ht_op_maskset, + .radio_read = b43_phy_ht_op_radio_read, + .radio_write = b43_phy_ht_op_radio_write, + .software_rfkill = b43_phy_ht_op_software_rfkill, + .switch_analog = b43_phy_ht_op_switch_analog, + .switch_channel = b43_phy_ht_op_switch_channel, + .get_default_chan = b43_phy_ht_op_get_default_chan, + .recalc_txpower = b43_phy_ht_op_recalc_txpower, + .adjust_txpower = b43_phy_ht_op_adjust_txpower, +}; diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h new file mode 100644 index 000000000000..7ad7affc8df0 --- /dev/null +++ b/drivers/net/wireless/b43/phy_ht.h @@ -0,0 +1,46 @@ +#ifndef B43_PHY_HT_H_ +#define B43_PHY_HT_H_ + +#include "phy_common.h" + + +#define B43_PHY_HT_BANDCTL 0x009 /* Band control */ +#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ +#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ +#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ +#define B43_PHY_HT_BW1 0x1CE +#define B43_PHY_HT_BW2 0x1CF +#define B43_PHY_HT_BW3 0x1D0 +#define B43_PHY_HT_BW4 0x1D1 +#define B43_PHY_HT_BW5 0x1D2 +#define B43_PHY_HT_BW6 0x1D3 + +#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) + +#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) +#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111) +#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114) +#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115) +#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118) +#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119) + + +/* Values for PHY registers used on channel switching */ +struct b43_phy_ht_channeltab_e_phy { + u16 bw1; + u16 bw2; + u16 bw3; + u16 bw4; + u16 bw5; + u16 bw6; +}; + + +struct b43_phy_ht { +}; + + +struct b43_phy_operations; +extern const struct b43_phy_operations b43_phyops_ht; + +#endif /* B43_PHY_HT_H_ */ diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c new file mode 100644 index 000000000000..9f7dbbd5ced6 --- /dev/null +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -0,0 +1,52 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n LCN-PHY support + + 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/slab.h> + +#include "b43.h" +#include "phy_lcn.h" +#include "tables_phy_lcn.h" +#include "main.h" + +/************************************************** + * PHY ops struct. + **************************************************/ + +const struct b43_phy_operations b43_phyops_lcn = { + /* + .allocate = b43_phy_lcn_op_allocate, + .free = b43_phy_lcn_op_free, + .prepare_structs = b43_phy_lcn_op_prepare_structs, + .init = b43_phy_lcn_op_init, + .phy_read = b43_phy_lcn_op_read, + .phy_write = b43_phy_lcn_op_write, + .phy_maskset = b43_phy_lcn_op_maskset, + .radio_read = b43_phy_lcn_op_radio_read, + .radio_write = b43_phy_lcn_op_radio_write, + .software_rfkill = b43_phy_lcn_op_software_rfkill, + .switch_analog = b43_phy_lcn_op_switch_analog, + .switch_channel = b43_phy_lcn_op_switch_channel, + .get_default_chan = b43_phy_lcn_op_get_default_chan, + .recalc_txpower = b43_phy_lcn_op_recalc_txpower, + .adjust_txpower = b43_phy_lcn_op_adjust_txpower, + */ +}; diff --git a/drivers/net/wireless/b43/phy_lcn.h b/drivers/net/wireless/b43/phy_lcn.h new file mode 100644 index 000000000000..c046c2a6cab4 --- /dev/null +++ b/drivers/net/wireless/b43/phy_lcn.h @@ -0,0 +1,14 @@ +#ifndef B43_PHY_LCN_H_ +#define B43_PHY_LCN_H_ + +#include "phy_common.h" + + +struct b43_phy_lcn { +}; + + +struct b43_phy_operations; +extern const struct b43_phy_operations b43_phyops_lcn; + +#endif /* B43_PHY_LCN_H_ */
\ No newline at end of file diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 012c8da2f944..daec1d9e4a18 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -85,39 +85,39 @@ static void b43_lpphy_op_free(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */ static void lpphy_read_band_sprom(struct b43_wldev *dev) { + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; u16 cckpo, maxpwr; u32 ofdmpo; int i; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - lpphy->tx_isolation_med_band = bus->sprom.tri2g; - lpphy->bx_arch = bus->sprom.bxa2g; - lpphy->rx_pwr_offset = bus->sprom.rxpo2g; - lpphy->rssi_vf = bus->sprom.rssismf2g; - lpphy->rssi_vc = bus->sprom.rssismc2g; - lpphy->rssi_gs = bus->sprom.rssisav2g; - lpphy->txpa[0] = bus->sprom.pa0b0; - lpphy->txpa[1] = bus->sprom.pa0b1; - lpphy->txpa[2] = bus->sprom.pa0b2; - maxpwr = bus->sprom.maxpwr_bg; + lpphy->tx_isolation_med_band = sprom->tri2g; + lpphy->bx_arch = sprom->bxa2g; + lpphy->rx_pwr_offset = sprom->rxpo2g; + lpphy->rssi_vf = sprom->rssismf2g; + lpphy->rssi_vc = sprom->rssismc2g; + lpphy->rssi_gs = sprom->rssisav2g; + lpphy->txpa[0] = sprom->pa0b0; + lpphy->txpa[1] = sprom->pa0b1; + lpphy->txpa[2] = sprom->pa0b2; + maxpwr = sprom->maxpwr_bg; lpphy->max_tx_pwr_med_band = maxpwr; - cckpo = bus->sprom.cck2gpo; + cckpo = sprom->cck2gpo; /* * We don't read SPROM's opo as specs say. On rev8 SPROMs * opo == ofdm2gpo and we don't know any SSB with LP-PHY * and SPROM rev below 8. */ - B43_WARN_ON(bus->sprom.revision < 8); - ofdmpo = bus->sprom.ofdm2gpo; + B43_WARN_ON(sprom->revision < 8); + ofdmpo = sprom->ofdm2gpo; if (cckpo) { for (i = 0; i < 4; i++) { lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; ofdmpo >>= 4; } - ofdmpo = bus->sprom.ofdm2gpo; + ofdmpo = sprom->ofdm2gpo; for (i = 4; i < 15; i++) { lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; @@ -131,39 +131,39 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev) lpphy->tx_max_rate[i] = maxpwr - ofdmpo; } } else { /* 5GHz */ - lpphy->tx_isolation_low_band = bus->sprom.tri5gl; - lpphy->tx_isolation_med_band = bus->sprom.tri5g; - lpphy->tx_isolation_hi_band = bus->sprom.tri5gh; - lpphy->bx_arch = bus->sprom.bxa5g; - lpphy->rx_pwr_offset = bus->sprom.rxpo5g; - lpphy->rssi_vf = bus->sprom.rssismf5g; - lpphy->rssi_vc = bus->sprom.rssismc5g; - lpphy->rssi_gs = bus->sprom.rssisav5g; - lpphy->txpa[0] = bus->sprom.pa1b0; - lpphy->txpa[1] = bus->sprom.pa1b1; - lpphy->txpa[2] = bus->sprom.pa1b2; - lpphy->txpal[0] = bus->sprom.pa1lob0; - lpphy->txpal[1] = bus->sprom.pa1lob1; - lpphy->txpal[2] = bus->sprom.pa1lob2; - lpphy->txpah[0] = bus->sprom.pa1hib0; - lpphy->txpah[1] = bus->sprom.pa1hib1; - lpphy->txpah[2] = bus->sprom.pa1hib2; - maxpwr = bus->sprom.maxpwr_al; - ofdmpo = bus->sprom.ofdm5glpo; + lpphy->tx_isolation_low_band = sprom->tri5gl; + lpphy->tx_isolation_med_band = sprom->tri5g; + lpphy->tx_isolation_hi_band = sprom->tri5gh; + lpphy->bx_arch = sprom->bxa5g; + lpphy->rx_pwr_offset = sprom->rxpo5g; + lpphy->rssi_vf = sprom->rssismf5g; + lpphy->rssi_vc = sprom->rssismc5g; + lpphy->rssi_gs = sprom->rssisav5g; + lpphy->txpa[0] = sprom->pa1b0; + lpphy->txpa[1] = sprom->pa1b1; + lpphy->txpa[2] = sprom->pa1b2; + lpphy->txpal[0] = sprom->pa1lob0; + lpphy->txpal[1] = sprom->pa1lob1; + lpphy->txpal[2] = sprom->pa1lob2; + lpphy->txpah[0] = sprom->pa1hib0; + lpphy->txpah[1] = sprom->pa1hib1; + lpphy->txpah[2] = sprom->pa1hib2; + maxpwr = sprom->maxpwr_al; + ofdmpo = sprom->ofdm5glpo; lpphy->max_tx_pwr_low_band = maxpwr; for (i = 4; i < 12; i++) { lpphy->tx_max_ratel[i] = maxpwr - (ofdmpo & 0xF) * 2; ofdmpo >>= 4; } - maxpwr = bus->sprom.maxpwr_a; - ofdmpo = bus->sprom.ofdm5gpo; + maxpwr = sprom->maxpwr_a; + ofdmpo = sprom->ofdm5gpo; lpphy->max_tx_pwr_med_band = maxpwr; for (i = 4; i < 12; i++) { lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; ofdmpo >>= 4; } - maxpwr = bus->sprom.maxpwr_ah; - ofdmpo = bus->sprom.ofdm5ghpo; + maxpwr = sprom->maxpwr_ah; + ofdmpo = sprom->ofdm5ghpo; lpphy->max_tx_pwr_hi_band = maxpwr; for (i = 4; i < 12; i++) { lpphy->tx_max_rateh[i] = maxpwr - (ofdmpo & 0xF) * 2; @@ -214,7 +214,8 @@ static void lpphy_table_init(struct b43_wldev *dev) static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy_lp *lpphy = dev->phy.lp; u16 tmp, tmp2; @@ -242,9 +243,9 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00); b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, 0xFF00, lpphy->rx_pwr_offset); - if ((bus->sprom.boardflags_lo & B43_BFL_FEM) && + if ((sprom->boardflags_lo & B43_BFL_FEM) && ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || - (bus->sprom.boardflags_hi & B43_BFH_PAREF))) { + (sprom->boardflags_hi & B43_BFH_PAREF))) { ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28); ssb_pmu_set_ldo_paref(&bus->chipco, true); if (dev->phy.rev == 0) { @@ -260,7 +261,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) } tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000; b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp); - if (bus->sprom.boardflags_hi & B43_BFH_RSSIINV) + if (sprom->boardflags_hi & B43_BFH_RSSIINV) b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA); else b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA); @@ -268,7 +269,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL, 0xFFF9, (lpphy->bx_arch << 1)); if (dev->phy.rev == 1 && - (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) { + (sprom->boardflags_hi & B43_BFH_FEM_BT)) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A); @@ -286,8 +287,8 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || - (bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) && - (bus->sprom.boardflags_lo & B43_BFL_FEM))) { + (dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) && + (sprom->boardflags_lo & B43_BFL_FEM))) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001); @@ -297,7 +298,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00); } else if (dev->phy.rev == 1 || - (bus->sprom.boardflags_lo & B43_BFL_FEM)) { + (sprom->boardflags_lo & B43_BFL_FEM)) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004); @@ -316,15 +317,15 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700); } - if (dev->phy.rev == 1 && (bus->sprom.boardflags_hi & B43_BFH_PAREF)) { + if (dev->phy.rev == 1 && (sprom->boardflags_hi & B43_BFH_PAREF)) { b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1); b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2); b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3); b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4); } - if ((bus->sprom.boardflags_hi & B43_BFH_FEM_BT) && - (bus->chip_id == 0x5354) && - (bus->chip_package == SSB_CHIPPACK_BCM4712S)) { + if ((sprom->boardflags_hi & B43_BFH_FEM_BT) && + (dev->dev->chip_id == 0x5354) && + (dev->dev->chip_pkg == SSB_CHIPPACK_BCM4712S)) { b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006); b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005); b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF); @@ -412,7 +413,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy_lp *lpphy = dev->phy.lp; b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); @@ -432,7 +432,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000); b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000); b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1); - if (bus->boardinfo.rev >= 0x18) { + if (dev->dev->board_rev >= 0x18) { b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC); b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14); } else { @@ -449,7 +449,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0); b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300); b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100); b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA); } else { @@ -467,7 +467,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12); b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0); b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40); } @@ -492,7 +492,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) 0x2000 | ((u16)lpphy->rssi_gs << 10) | ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_phy_set(dev, B43_LPPHY_AFE_ADC_CTL_0, 0x1C); b43_phy_maskset(dev, B43_LPPHY_AFE_CTL, 0x00FF, 0x8800); b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_1, 0xFC3C, 0x0400); @@ -519,7 +519,7 @@ struct b2062_freqdata { static void lpphy_2062_init(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; u32 crystalfreq, tmp, ref; unsigned int i; const struct b2062_freqdata *fd = NULL; @@ -697,7 +697,7 @@ static void lpphy_radio_init(struct b43_wldev *dev) lpphy_sync_stx(dev); b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); - if (dev->sdev->bus->chip_id == 0x4325) { + if (dev->dev->chip_id == 0x4325) { // TODO SSB PMU recalibration } } @@ -1289,7 +1289,7 @@ finish: static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; int i; @@ -1840,7 +1840,6 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; struct lpphy_tx_gains gains, oldgains; int old_txpctl, old_afe_ovr, old_rf, old_bbmult; @@ -1854,7 +1853,7 @@ static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); - if (bus->chip_id == 0x4325 && bus->chip_rev == 0) + if (dev->dev->chip_id == 0x4325 && dev->dev->chip_rev == 0) lpphy_papd_cal(dev, gains, 0, 1, 30); else lpphy_papd_cal(dev, gains, 0, 1, 65); @@ -1870,7 +1869,6 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, bool rx, bool pa, struct lpphy_tx_gains *gains) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; const struct lpphy_rx_iq_comp *iqcomp = NULL; struct lpphy_tx_gains nogains, oldgains; u16 tmp; @@ -1879,7 +1877,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, memset(&nogains, 0, sizeof(nogains)); memset(&oldgains, 0, sizeof(oldgains)); - if (bus->chip_id == 0x5354) { + if (dev->dev->chip_id == 0x5354) { for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) { if (lpphy_5354_iq_table[i].chan == lpphy->channel) { iqcomp = &lpphy_5354_iq_table[i]; @@ -2408,11 +2406,9 @@ static const struct b206x_channel b2063_chantbl[] = { static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; - b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); udelay(20); - if (bus->chip_id == 0x5354) { + if (dev->dev->chip_id == 0x5354) { b43_radio_write(dev, B2062_N_COMM1, 4); b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4); } else { @@ -2432,7 +2428,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev, unsigned int channel) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; const struct b206x_channel *chandata = NULL; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; @@ -2522,7 +2518,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev) static int lpphy_b2063_tune(struct b43_wldev *dev, unsigned int channel) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; static const struct b206x_channel *chandata = NULL; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; @@ -2670,6 +2666,11 @@ static int b43_lpphy_op_init(struct b43_wldev *dev) { int err; + if (dev->dev->bus_type != B43_BUS_SSB) { + b43err(dev->wl, "LP-PHY is supported only on SSB!\n"); + return -EOPNOTSUPP; + } + lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? lpphy_baseband_init(dev); lpphy_radio_init(dev); diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 05960ddde24e..95c28f584ed9 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) static void b43_nphy_tx_power_fix(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_sprom *sprom = dev->dev->bus_sprom; u8 txpi[2], bbmult, i; u16 tmp, radio_gain, dac_gain; @@ -423,16 +423,15 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev) static void b43_radio_init2055_post(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); - struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo); + struct ssb_sprom *sprom = dev->dev->bus_sprom; int i; u16 val; bool workaround = false; if (sprom->revision < 4) - workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM && - binfo->type == 0x46D && - binfo->rev >= 0x41); + workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM + && dev->dev->board_type == 0x46D + && dev->dev->board_rev >= 0x41); else workaround = !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); @@ -604,17 +603,33 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force) { - u32 tmslow; + u32 tmp; if (dev->phy.type != B43_PHYTYPE_N) return; - tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); - if (force) - tmslow |= SSB_TMSLOW_FGC; - else - tmslow &= ~SSB_TMSLOW_FGC; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL); + if (force) + tmp |= BCMA_IOCTL_FGC; + else + tmp &= ~BCMA_IOCTL_FGC; + bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + if (force) + tmp |= SSB_TMSLOW_FGC; + else + tmp &= ~SSB_TMSLOW_FGC; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + break; +#endif + } } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ @@ -959,8 +974,21 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); - ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00, - 0xFC00); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, + 0xFC00, 0xFC00); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco, + 0xFC00, 0xFC00); + break; +#endif + } + b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) & ~B43_MACCTL_GPOUTSMSK); @@ -983,7 +1011,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) { u16 tmp; - if (dev->sdev->id.revision == 16) + if (dev->dev->core_rev == 16) b43_mac_suspend(dev); tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); @@ -993,7 +1021,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) tmp |= (val & mask); b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); - if (dev->sdev->id.revision == 16) + if (dev->dev->core_rev == 16) b43_mac_enable(dev); return tmp; @@ -1168,7 +1196,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_sprom *sprom = dev->dev->bus_sprom; /* PHY rev 0, 1, 2 */ u8 i, j; @@ -1373,7 +1401,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ static void b43_nphy_workarounds(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; @@ -1443,9 +1471,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ - if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR && + if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR && b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || - (bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR && + (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR && b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) tmp32 = 0x00088888; else @@ -1503,8 +1531,8 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); - if (bus->sprom.boardflags2_lo & 0x100 && - bus->boardinfo.type == 0x8B) { + if (sprom->boardflags2_lo & 0x100 && + dev->dev->board_type == 0x8B) { delays1[0] = 0x1; delays1[5] = 0x14; } @@ -3586,7 +3614,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) */ int b43_phy_initn(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; u8 tx_pwr_state; @@ -3599,9 +3627,22 @@ int b43_phy_initn(struct b43_wldev *dev) bool do_cal = false; if ((dev->phy.rev >= 3) && - (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && + (sprom->boardflags_lo & B43_BFL_EXTLNA) && (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { - chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_cc_set32(&dev->dev->bdev->bus->drv_cc, + BCMA_CC_CHIPCTL, 0x40); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + chipco_set32(&dev->dev->sdev->bus->chipco, + SSB_CHIPCO_CHIPCTL, 0x40); + break; +#endif + } } nphy->deaf_count = 0; b43_nphy_tables_init(dev); @@ -3639,9 +3680,9 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); - if (bus->sprom.boardflags2_lo & 0x100 || - (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && - bus->boardinfo.type == 0x8B)) + if (sprom->boardflags2_lo & 0x100 || + (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE && + dev->dev->board_type == 0x8B)) b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); else b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); @@ -4026,11 +4067,24 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) { - u16 val = on ? 0 : 0x7FFF; + u16 override = on ? 0x0 : 0x7FFF; + u16 core = on ? 0xD : 0x00FD; - if (dev->phy.rev >= 3) - b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, val); - b43_phy_write(dev, B43_NPHY_AFECTL_OVER, val); + if (dev->phy.rev >= 3) { + if (on) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, core); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, core); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); + } else { + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override); + b43_phy_write(dev, B43_NPHY_AFECTL_C1, core); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, core); + } + } else { + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); + } } static int b43_nphy_op_switch_channel(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 72ab94df7569..44da620d9cc2 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c @@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, B43_MMIO_PIO11_BASE5, }; - if (dev->sdev->id.revision >= 11) { + if (dev->dev->core_rev >= 11) { B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); return bases_rev11[index]; } @@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, static u16 pio_txqueue_offset(struct b43_wldev *dev) { - if (dev->sdev->id.revision >= 11) + if (dev->dev->core_rev >= 11) return 0x18; return 0; } static u16 pio_rxqueue_offset(struct b43_wldev *dev) { - if (dev->sdev->id.revision >= 11) + if (dev->dev->core_rev >= 11) return 0x38; return 8; } @@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev, if (!q) return NULL; q->dev = dev; - q->rev = dev->sdev->id.revision; + q->rev = dev->dev->core_rev; q->mmio_base = index_to_pioqueue_base(dev, index) + pio_txqueue_offset(dev); q->index = index; @@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev, if (!q) return NULL; q->dev = dev; - q->rev = dev->sdev->id.revision; + q->rev = dev->dev->core_rev; q->mmio_base = index_to_pioqueue_base(dev, index) + pio_rxqueue_offset(dev); diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h index d9bfa0f21b72..67f96122f8d8 100644 --- a/drivers/net/wireless/b43/radio_2055.h +++ b/drivers/net/wireless/b43/radio_2055.h @@ -251,4 +251,9 @@ struct b43_nphy_channeltab_entry_rev2 { void b2055_upload_inittab(struct b43_wldev *dev, bool ghz5, bool ignore_uploadflag); +/* Get the NPHY Channel Switch Table entry for a channel. + * Returns NULL on failure to find an entry. */ +const struct b43_nphy_channeltab_entry_rev2 * +b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); + #endif /* B43_RADIO_2055_H_ */ diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index d601f6e7e313..d52df6be705a 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h @@ -1117,4 +1117,9 @@ struct b43_nphy_channeltab_entry_rev3 { void b2056_upload_inittabs(struct b43_wldev *dev, bool ghz5, bool ignore_uploadflag); +/* Get the NPHY Channel Switch Table entry for a channel. + * Returns NULL on failure to find an entry. */ +const struct b43_nphy_channeltab_entry_rev3 * +b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); + #endif /* B43_RADIO_2056_H_ */ diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c new file mode 100644 index 000000000000..23dea4ba8219 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2059.c @@ -0,0 +1,165 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n 2059 radio device data tables + + 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 "b43.h" +#include "radio_2059.h" + +#define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ + r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ + r20, r21, r22, r23, r24, r25, r26, r27, r28) \ + .radio_syn16 = r00, \ + .radio_syn17 = r01, \ + .radio_syn22 = r02, \ + .radio_syn25 = r03, \ + .radio_syn27 = r04, \ + .radio_syn28 = r05, \ + .radio_syn29 = r06, \ + .radio_syn2c = r07, \ + .radio_syn2d = r08, \ + .radio_syn37 = r09, \ + .radio_syn41 = r10, \ + .radio_syn43 = r11, \ + .radio_syn47 = r12, \ + .radio_syn4a = r13, \ + .radio_syn58 = r14, \ + .radio_syn5a = r15, \ + .radio_syn6a = r16, \ + .radio_syn6d = r17, \ + .radio_syn6e = r18, \ + .radio_syn92 = r19, \ + .radio_syn98 = r20, \ + .radio_rxtx4a = r21, \ + .radio_rxtx58 = r22, \ + .radio_rxtx5a = r23, \ + .radio_rxtx6a = r24, \ + .radio_rxtx6d = r25, \ + .radio_rxtx6e = r26, \ + .radio_rxtx92 = r27, \ + .radio_rxtx98 = r28 + +#define PHYREGS(r0, r1, r2, r3, r4, r5) \ + .phy_regs.bw1 = r0, \ + .phy_regs.bw2 = r1, \ + .phy_regs.bw3 = r2, \ + .phy_regs.bw4 = r3, \ + .phy_regs.bw5 = r4, \ + .phy_regs.bw6 = r5 + +static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = { + { .freq = 2412, + RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, + 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, + 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, + 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, + 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, + 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, + 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, + 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, + 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, + 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, + 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, +}; + +const struct b43_phy_ht_channeltab_e_radio2059 +*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq) +{ + return NULL; +} diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h new file mode 100644 index 000000000000..e4d69e55e9fe --- /dev/null +++ b/drivers/net/wireless/b43/radio_2059.h @@ -0,0 +1,54 @@ +#ifndef B43_RADIO_2059_H_ +#define B43_RADIO_2059_H_ + +#include <linux/types.h> + +#include "phy_ht.h" + +#define R2059_SYN 0x000 +#define R2059_TXRX0 0x400 +#define R2059_RXRX1 0x800 +#define R2059_ALL 0xC00 + +/* Values for various registers uploaded on channel switching */ +struct b43_phy_ht_channeltab_e_radio2059 { + /* The channel frequency in MHz */ + u16 freq; + /* Values for radio registers */ + u8 radio_syn16; + u8 radio_syn17; + u8 radio_syn22; + u8 radio_syn25; + u8 radio_syn27; + u8 radio_syn28; + u8 radio_syn29; + u8 radio_syn2c; + u8 radio_syn2d; + u8 radio_syn37; + u8 radio_syn41; + u8 radio_syn43; + u8 radio_syn47; + u8 radio_syn4a; + u8 radio_syn58; + u8 radio_syn5a; + u8 radio_syn6a; + u8 radio_syn6d; + u8 radio_syn6e; + u8 radio_syn92; + u8 radio_syn98; + u8 radio_rxtx4a; + u8 radio_rxtx58; + u8 radio_rxtx5a; + u8 radio_rxtx6a; + u8 radio_rxtx6d; + u8 radio_rxtx6e; + u8 radio_rxtx92; + u8 radio_rxtx98; + /* Values for PHY registers */ + struct b43_phy_ht_channeltab_e_phy phy_regs; +}; + +const struct b43_phy_ht_channeltab_e_radio2059 +*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq); + +#endif /* B43_RADIO_2059_H_ */ diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index a617efe38289..59c3afe047af 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -37,17 +37,16 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; - struct ssb_bus *bus = dev->sdev->bus; bool enabled; bool brought_up = false; mutex_lock(&wl->mutex); if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { - if (ssb_bus_powerup(bus, 0)) { + if (b43_bus_powerup(dev, 0)) { mutex_unlock(&wl->mutex); return; } - ssb_device_enable(dev->sdev, 0); + b43_device_enable(dev, 0); brought_up = true; } @@ -63,8 +62,8 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) } if (brought_up) { - ssb_device_disable(dev->sdev, 0); - ssb_bus_may_powerdown(bus); + b43_device_disable(dev, 0); + b43_bus_may_powerdown(dev); } mutex_unlock(&wl->mutex); diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 808e25b79703..4fd6775b8c33 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c @@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func) int b43_sdio_request_irq(struct b43_wldev *dev, void (*handler)(struct b43_wldev *dev)) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; struct sdio_func *func = bus->host_sdio; struct b43_sdio *sdio = sdio_get_drvdata(func); int err; @@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev, void b43_sdio_free_irq(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; struct sdio_func *func = bus->host_sdio; struct b43_sdio *sdio = sdio_get_drvdata(func); @@ -93,8 +93,8 @@ void b43_sdio_free_irq(struct b43_wldev *dev) sdio->irq_handler = NULL; } -static int b43_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) +static int __devinit b43_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) { struct b43_sdio *sdio; struct sdio_func_tuple *tuple; @@ -171,7 +171,7 @@ out: return error; } -static void b43_sdio_remove(struct sdio_func *func) +static void __devexit b43_sdio_remove(struct sdio_func *func) { struct b43_sdio *sdio = sdio_get_drvdata(func); diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c index 57af619725c3..f1ae4e05a32c 100644 --- a/drivers/net/wireless/b43/sysfs.c +++ b/drivers/net/wireless/b43/sysfs.c @@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644, int b43_sysfs_register(struct b43_wldev *wldev) { - struct device *dev = wldev->sdev->dev; + struct device *dev = wldev->dev->dev; B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); @@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev) void b43_sysfs_unregister(struct b43_wldev *wldev) { - struct device *dev = wldev->sdev->dev; + struct device *dev = wldev->dev->dev; device_remove_file(dev, &dev_attr_interference); } diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c index 59df3c64af63..6748c5a196e9 100644 --- a/drivers/net/wireless/b43/tables_lpphy.c +++ b/drivers/net/wireless/b43/tables_lpphy.c @@ -2304,7 +2304,6 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev) void lpphy_rev2plus_table_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; int i; B43_WARN_ON(dev->phy.rev < 2); @@ -2341,7 +2340,7 @@ void lpphy_rev2plus_table_init(struct b43_wldev *dev) b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0), ARRAY_SIZE(lpphy_papd_mult_table), lpphy_papd_mult_table); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0), ARRAY_SIZE(lpphy_a0_gain_idx_table), lpphy_a0_gain_idx_table); b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0), @@ -2416,12 +2415,12 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count, void lpphy_init_tx_gain_table(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; switch (dev->phy.rev) { case 0: - if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) || - (bus->sprom.boardflags_lo & B43_BFL_HGPA)) + if ((sprom->boardflags_hi & B43_BFH_NOPA) || + (sprom->boardflags_lo & B43_BFL_HGPA)) lpphy_write_gain_table_bulk(dev, 0, 128, lpphy_rev0_nopa_tx_gain_table); else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -2432,8 +2431,8 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev) lpphy_rev0_5ghz_tx_gain_table); break; case 1: - if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) || - (bus->sprom.boardflags_lo & B43_BFL_HGPA)) + if ((sprom->boardflags_hi & B43_BFH_NOPA) || + (sprom->boardflags_lo & B43_BFL_HGPA)) lpphy_write_gain_table_bulk(dev, 0, 128, lpphy_rev1_nopa_tx_gain_table); else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -2444,7 +2443,7 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev) lpphy_rev1_5ghz_tx_gain_table); break; default: - if (bus->sprom.boardflags_hi & B43_BFH_NOPA) + if (sprom->boardflags_hi & B43_BFH_NOPA) lpphy_write_gain_table_bulk(dev, 0, 128, lpphy_rev2_nopa_tx_gain_table); else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 18569367ce43..a81696bff0ed 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -60,16 +60,8 @@ struct nphy_gain_ctl_workaround_entry { struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( struct b43_wldev *dev, bool ghz5, bool ext_lna); -/* Get the NPHY Channel Switch Table entry for a channel. - * Returns NULL on failure to find an entry. */ -const struct b43_nphy_channeltab_entry_rev2 * -b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); -const struct b43_nphy_channeltab_entry_rev3 * -b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); - /* The N-PHY tables. */ - #define B43_NTAB_TYPEMASK 0xF0000000 #define B43_NTAB_8BIT 0x10000000 #define B43_NTAB_16BIT 0x20000000 diff --git a/drivers/net/wireless/b43/tables_phy_ht.c b/drivers/net/wireless/b43/tables_phy_ht.c new file mode 100644 index 000000000000..603938657b15 --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_ht.c @@ -0,0 +1,750 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n HT-PHY data tables + + 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 "b43.h" +#include "tables_phy_ht.h" +#include "phy_common.h" +#include "phy_ht.h" + +static const u16 b43_httab_0x12[] = { + 0x0000, 0x0008, 0x000a, 0x0010, 0x0012, 0x0019, + 0x001a, 0x001c, 0x0080, 0x0088, 0x008a, 0x0090, + 0x0092, 0x0099, 0x009a, 0x009c, 0x0100, 0x0108, + 0x010a, 0x0110, 0x0112, 0x0119, 0x011a, 0x011c, + 0x0180, 0x0188, 0x018a, 0x0190, 0x0192, 0x0199, + 0x019a, 0x019c, 0x0000, 0x0098, 0x00a0, 0x00a8, + 0x009a, 0x00a2, 0x00aa, 0x0120, 0x0128, 0x0128, + 0x0130, 0x0138, 0x0138, 0x0140, 0x0122, 0x012a, + 0x012a, 0x0132, 0x013a, 0x013a, 0x0142, 0x01a8, + 0x01b0, 0x01b8, 0x01b0, 0x01b8, 0x01c0, 0x01c8, + 0x01c0, 0x01c8, 0x01d0, 0x01d0, 0x01d8, 0x01aa, + 0x01b2, 0x01ba, 0x01b2, 0x01ba, 0x01c2, 0x01ca, + 0x01c2, 0x01ca, 0x01d2, 0x01d2, 0x01da, 0x0001, + 0x0002, 0x0004, 0x0009, 0x000c, 0x0011, 0x0014, + 0x0018, 0x0020, 0x0021, 0x0022, 0x0024, 0x0081, + 0x0082, 0x0084, 0x0089, 0x008c, 0x0091, 0x0094, + 0x0098, 0x00a0, 0x00a1, 0x00a2, 0x00a4, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, +}; + +static const u16 b43_httab_0x27[] = { + 0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a, + 0x001d, 0x0020, 0x0009, 0x000e, 0x0011, 0x0014, + 0x0017, 0x001a, 0x001d, 0x0020, 0x0009, 0x000e, + 0x0011, 0x0014, 0x0017, 0x001a, 0x001d, 0x0020, + 0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a, + 0x001d, 0x0020, +}; + +static const u16 b43_httab_0x26[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u32 b43_httab_0x25[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_httab_0x2f[] = { + 0x00035700, 0x0002cc9a, 0x00026666, 0x0001581f, + 0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f, + 0x0001581f, 0x0001581f, 0x0001581f, 0x00035700, + 0x0002cc9a, 0x00026666, 0x0001581f, 0x0001581f, + 0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f, + 0x0001581f, 0x0001581f, +}; + +static const u16 b43_httab_0x1a[] = { + 0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e, + 0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a, + 0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046, + 0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040, + 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a, + 0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033, + 0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b, + 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e, + 0x000b, 0x0007, 0x0002, 0x00fd, +}; + +static const u16 b43_httab_0x1b[] = { + 0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e, + 0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a, + 0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046, + 0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040, + 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a, + 0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033, + 0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b, + 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e, + 0x000b, 0x0007, 0x0002, 0x00fd, +}; + +static const u16 b43_httab_0x1c[] = { + 0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e, + 0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a, + 0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046, + 0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040, + 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a, + 0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033, + 0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b, + 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e, + 0x000b, 0x0007, 0x0002, 0x00fd, +}; + +static const u32 b43_httab_0x1a_0xc0[] = { + 0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e, + 0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037, + 0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031, + 0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040, + 0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039, + 0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033, + 0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e, + 0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037, + 0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031, + 0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c, + 0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e, + 0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037, + 0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031, + 0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c, + 0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042, + 0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b, + 0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034, + 0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f, + 0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e, + 0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037, + 0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031, + 0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c, + 0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027, + 0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023, + 0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e, + 0x5b07003c, 0x5b07003b, 0x5b070039, 0x5b070037, + 0x5b070036, 0x5b070034, 0x5b070033, 0x5b070031, + 0x5b070030, 0x5b07002f, 0x5b07002d, 0x5b07002c, + 0x5b07002b, 0x5b07002a, 0x5b070028, 0x5b070027, + 0x5b070026, 0x5b070025, 0x5b070024, 0x5b070023, + 0x5b070022, 0x5b070021, 0x5b070020, 0x5b07001f, + 0x5b07001e, 0x5b07001d, 0x5b07001d, 0x5b07001c, +}; + +static const u32 b43_httab_0x1a_0x140[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_httab_0x1b_0x140[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_httab_0x1c_0x140[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u16 b43_httab_0x1a_0x1c0[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u16 b43_httab_0x1b_0x1c0[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u16 b43_httab_0x1c_0x1c0[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u16 b43_httab_0x1a_0x240[] = { + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, +}; + +static const u16 b43_httab_0x1b_0x240[] = { + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, +}; + +static const u16 b43_httab_0x1c_0x240[] = { + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, +}; + +static const u32 b43_httab_0x1f[] = { + 0x00000000, 0x00000000, 0x00016023, 0x00006028, + 0x00034036, 0x0003402e, 0x0007203c, 0x0006e037, + 0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d, + 0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9, + 0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9, + 0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6, + 0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c, + 0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b, + 0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15, + 0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9, + 0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87, + 0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3, + 0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa, + 0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff, + 0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff, + 0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff, +}; + +static const u32 b43_httab_0x21[] = { + 0x00000000, 0x00000000, 0x00016023, 0x00006028, + 0x00034036, 0x0003402e, 0x0007203c, 0x0006e037, + 0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d, + 0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9, + 0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9, + 0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6, + 0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c, + 0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b, + 0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15, + 0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9, + 0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87, + 0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3, + 0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa, + 0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff, + 0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff, + 0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff, +}; + +static const u32 b43_httab_0x23[] = { + 0x00000000, 0x00000000, 0x00016023, 0x00006028, + 0x00034036, 0x0003402e, 0x0007203c, 0x0006e037, + 0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d, + 0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9, + 0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9, + 0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6, + 0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c, + 0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b, + 0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15, + 0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9, + 0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87, + 0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3, + 0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa, + 0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff, + 0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff, + 0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff, +}; + +static const u32 b43_httab_0x20[] = { + 0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035, + 0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043, + 0x07340047, 0x06d2004b, 0x067a004f, 0x06170054, + 0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a, + 0x04910070, 0x044c0077, 0x040f007e, 0x03d90085, + 0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8, + 0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3, + 0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a, + 0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e, + 0x01720162, 0x015d0177, 0x0149018e, 0x013701a5, + 0x012601be, 0x011501d8, 0x010601f4, 0x00f70212, + 0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b, + 0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348, + 0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422, + 0x00750460, 0x006e04a3, 0x006804e9, 0x00620533, + 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c, +}; + +static const u32 b43_httab_0x22[] = { + 0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035, + 0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043, + 0x07340047, 0x06d2004b, 0x067a004f, 0x06170054, + 0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a, + 0x04910070, 0x044c0077, 0x040f007e, 0x03d90085, + 0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8, + 0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3, + 0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a, + 0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e, + 0x01720162, 0x015d0177, 0x0149018e, 0x013701a5, + 0x012601be, 0x011501d8, 0x010601f4, 0x00f70212, + 0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b, + 0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348, + 0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422, + 0x00750460, 0x006e04a3, 0x006804e9, 0x00620533, + 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c, +}; + +static const u32 b43_httab_0x24[] = { + 0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035, + 0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043, + 0x07340047, 0x06d2004b, 0x067a004f, 0x06170054, + 0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a, + 0x04910070, 0x044c0077, 0x040f007e, 0x03d90085, + 0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8, + 0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3, + 0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a, + 0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e, + 0x01720162, 0x015d0177, 0x0149018e, 0x013701a5, + 0x012601be, 0x011501d8, 0x010601f4, 0x00f70212, + 0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b, + 0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348, + 0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422, + 0x00750460, 0x006e04a3, 0x006804e9, 0x00620533, + 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c, +}; + +/************************************************** + * R/W ops. + **************************************************/ + +u32 b43_httab_read(struct b43_wldev *dev, u32 offset) +{ + u32 type, value; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= ~B43_HTTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + switch (type) { + case B43_HTTAB_8BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO) & 0xFF; + break; + case B43_HTTAB_16BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + break; + case B43_HTTAB_32BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATAHI); + value <<= 16; + value |= b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + break; + default: + B43_WARN_ON(1); + value = 0; + } + + return value; +} + +void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, void *_data) +{ + u32 type; + u8 *data = _data; + unsigned int i; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= ~B43_HTTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + + for (i = 0; i < nr_elements; i++) { + switch (type) { + case B43_HTTAB_8BIT: + *data = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO) & 0xFF; + data++; + break; + case B43_HTTAB_16BIT: + *((u16 *)data) = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + data += 2; + break; + case B43_HTTAB_32BIT: + *((u32 *)data) = b43_phy_read(dev, B43_PHY_HT_TABLE_DATAHI); + *((u32 *)data) <<= 16; + *((u32 *)data) |= b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + data += 4; + break; + default: + B43_WARN_ON(1); + } + } +} + +void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value) +{ + u32 type; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= 0xFFFF; + + switch (type) { + case B43_HTTAB_8BIT: + B43_WARN_ON(value & ~0xFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_16BIT: + B43_WARN_ON(value & ~0xFFFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_32BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, value >> 16); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value & 0xFFFF); + break; + default: + B43_WARN_ON(1); + } + + return; +} + +void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, const void *_data) +{ + u32 type, value; + const u8 *data = _data; + unsigned int i; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= ~B43_HTTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + + for (i = 0; i < nr_elements; i++) { + switch (type) { + case B43_HTTAB_8BIT: + value = *data; + data++; + B43_WARN_ON(value & ~0xFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_16BIT: + value = *((u16 *)data); + data += 2; + B43_WARN_ON(value & ~0xFFFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_32BIT: + value = *((u32 *)data); + data += 4; + b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, value >> 16); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, + value & 0xFFFF); + break; + default: + B43_WARN_ON(1); + } + } +} + +/************************************************** + * Tables ops. + **************************************************/ + +#define httab_upload(dev, offset, data) do { \ + b43_httab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ + } while (0) +void b43_phy_ht_tables_init(struct b43_wldev *dev) +{ + httab_upload(dev, B43_HTTAB16(0x12, 0), b43_httab_0x12); + httab_upload(dev, B43_HTTAB16(0x27, 0), b43_httab_0x27); + httab_upload(dev, B43_HTTAB16(0x26, 0), b43_httab_0x26); + httab_upload(dev, B43_HTTAB32(0x25, 0), b43_httab_0x25); + httab_upload(dev, B43_HTTAB32(0x2f, 0), b43_httab_0x2f); + httab_upload(dev, B43_HTTAB16(0x1a, 0), b43_httab_0x1a); + httab_upload(dev, B43_HTTAB16(0x1b, 0), b43_httab_0x1b); + httab_upload(dev, B43_HTTAB16(0x1c, 0), b43_httab_0x1c); + httab_upload(dev, B43_HTTAB32(0x1a, 0x0c0), b43_httab_0x1a_0xc0); + httab_upload(dev, B43_HTTAB32(0x1a, 0x140), b43_httab_0x1a_0x140); + httab_upload(dev, B43_HTTAB32(0x1b, 0x140), b43_httab_0x1b_0x140); + httab_upload(dev, B43_HTTAB32(0x1c, 0x140), b43_httab_0x1c_0x140); + httab_upload(dev, B43_HTTAB16(0x1a, 0x1c0), b43_httab_0x1a_0x1c0); + httab_upload(dev, B43_HTTAB16(0x1b, 0x1c0), b43_httab_0x1b_0x1c0); + httab_upload(dev, B43_HTTAB16(0x1c, 0x1c0), b43_httab_0x1c_0x1c0); + httab_upload(dev, B43_HTTAB16(0x1a, 0x240), b43_httab_0x1a_0x240); + httab_upload(dev, B43_HTTAB16(0x1b, 0x240), b43_httab_0x1b_0x240); + httab_upload(dev, B43_HTTAB16(0x1c, 0x240), b43_httab_0x1c_0x240); + httab_upload(dev, B43_HTTAB32(0x1f, 0), b43_httab_0x1f); + httab_upload(dev, B43_HTTAB32(0x21, 0), b43_httab_0x21); + httab_upload(dev, B43_HTTAB32(0x23, 0), b43_httab_0x23); + httab_upload(dev, B43_HTTAB32(0x20, 0), b43_httab_0x20); + httab_upload(dev, B43_HTTAB32(0x22, 0), b43_httab_0x22); + httab_upload(dev, B43_HTTAB32(0x24, 0), b43_httab_0x24); +} diff --git a/drivers/net/wireless/b43/tables_phy_ht.h b/drivers/net/wireless/b43/tables_phy_ht.h new file mode 100644 index 000000000000..ea3be382c894 --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_ht.h @@ -0,0 +1,22 @@ +#ifndef B43_TABLES_PHY_HT_H_ +#define B43_TABLES_PHY_HT_H_ + +/* The HT-PHY tables. */ +#define B43_HTTAB_TYPEMASK 0xF0000000 +#define B43_HTTAB_8BIT 0x10000000 +#define B43_HTTAB_16BIT 0x20000000 +#define B43_HTTAB_32BIT 0x30000000 +#define B43_HTTAB8(table, offset) (((table) << 10) | (offset) | B43_HTTAB_8BIT) +#define B43_HTTAB16(table, offset) (((table) << 10) | (offset) | B43_HTTAB_16BIT) +#define B43_HTTAB32(table, offset) (((table) << 10) | (offset) | B43_HTTAB_32BIT) + +u32 b43_httab_read(struct b43_wldev *dev, u32 offset); +void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, void *_data); +void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value); +void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, const void *_data); + +void b43_phy_ht_tables_init(struct b43_wldev *dev); + +#endif /* B43_TABLES_PHY_HT_H_ */ diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c new file mode 100644 index 000000000000..40c1d0915dd3 --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -0,0 +1,34 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n LCN-PHY data tables + + 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 "b43.h" +#include "tables_phy_lcn.h" +#include "phy_common.h" +#include "phy_lcn.h" + +/************************************************** + * Tables ops. + **************************************************/ + +void b43_phy_lcn_tables_init(struct b43_wldev *dev) +{ +} diff --git a/drivers/net/wireless/b43/tables_phy_lcn.h b/drivers/net/wireless/b43/tables_phy_lcn.h new file mode 100644 index 000000000000..5e31b15b81ec --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_lcn.h @@ -0,0 +1,6 @@ +#ifndef B43_TABLES_PHY_LCN_H_ +#define B43_TABLES_PHY_LCN_H_ + +void b43_phy_lcn_tables_init(struct b43_wldev *dev); + +#endif /* B43_TABLES_PHY_LCN_H_ */ diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c index 8f4db448ec33..5d00d0eaf2e7 100644 --- a/drivers/net/wireless/b43/wa.c +++ b/drivers/net/wireless/b43/wa.c @@ -458,17 +458,15 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev) static void b43_wa_boards_a(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; - - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && - bus->boardinfo.type == SSB_BOARD_BU4306 && - bus->boardinfo.rev < 0x30) { + if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM && + dev->dev->board_type == SSB_BOARD_BU4306 && + dev->dev->board_rev < 0x30) { b43_phy_write(dev, 0x0010, 0xE000); b43_phy_write(dev, 0x0013, 0x0140); b43_phy_write(dev, 0x0014, 0x0280); } else { - if (bus->boardinfo.type == SSB_BOARD_MP4318 && - bus->boardinfo.rev < 0x20) { + if (dev->dev->board_type == SSB_BOARD_MP4318 && + dev->dev->board_rev < 0x20) { b43_phy_write(dev, 0x0013, 0x0210); b43_phy_write(dev, 0x0014, 0x0840); } else { @@ -486,19 +484,19 @@ static void b43_wa_boards_a(struct b43_wldev *dev) static void b43_wa_boards_g(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; - if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || - bus->boardinfo.type != SSB_BOARD_BU4306 || - bus->boardinfo.rev != 0x17) { + if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM || + dev->dev->board_type != SSB_BOARD_BU4306 || + dev->dev->board_rev != 0x17) { if (phy->rev < 2) { b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); } else { b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); - if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && + if ((sprom->boardflags_lo & B43_BFL_EXTLNA) && (phy->rev >= 7)) { b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); @@ -510,7 +508,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev) } } } - if (bus->sprom.boardflags_lo & B43_BFL_FEM) { + if (sprom->boardflags_lo & B43_BFL_FEM) { b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); } diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index c8f99aebe01f..82bcf7595139 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, /* we give the phase1key and iv16 here, the key is stored in * shm. With that the hardware can do phase 2 and encryption. */ - ieee80211_get_tkip_key(info->control.hw_key, skb_frag, - IEEE80211_TKIP_P1_KEY, (u8*)phase1key); + ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key); /* phase1key is in host endian. Copy to little-endian txhdr->iv. */ for (i = 0; i < 5; i++) { txhdr->iv[i * 2 + 0] = phase1key[i]; @@ -547,7 +546,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev, else tmp -= 3; } else { - if (dev->sdev->bus->sprom. + if (dev->dev->bus_sprom-> boardflags_lo & B43_BFL_RSSI) { if (in_rssi > 63) in_rssi = 63; |