diff options
Diffstat (limited to 'package')
6 files changed, 2700 insertions, 6 deletions
| diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile index 5270413c8..07af5f29d 100644 --- a/package/mac80211/Makefile +++ b/package/mac80211/Makefile @@ -852,6 +852,7 @@ endef  define KernelPackage/b43  $(call KernelPackage/b43-common) +  DEPENDS+= +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma    TITLE:=Broadcom 43xx wireless support    FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43/b43.ko    AUTOLOAD:=$(call AutoLoad,30,b43) @@ -864,7 +865,7 @@ define KernelPackage/b43/config  	choice  		prompt "b43 firmware version" -		default B43_FW_4_150 +		default B43_FW_5_10  		help  		  This option allows you to select the version of the b43 firmware. @@ -922,8 +923,7 @@ define KernelPackage/b43/config  	config B43_FW_SQUASH_COREREVS  		string "Core revisions to include"  		depends on B43_FW_SQUASH -		default "5,6,7,8,9,10,11,13,14,15,16" if PACKAGE_B43_PHY_N -		default "5,6,7,8,9,10,13,14,15" if !PACKAGE_B43_PHY_N +		default "5,6,7,8,9,10,11,13,14,15,16"  		help  		  This is a comma seperated list of core revision numbers. @@ -936,8 +936,7 @@ define KernelPackage/b43/config  	config B43_FW_SQUASH_PHYTYPES  		string "PHY types to include"  		depends on B43_FW_SQUASH -		default "G,LP,N" if PACKAGE_B43_PHY_N -		default "G,LP" if !PACKAGE_B43_PHY_N +		default "G,LP,N"  		help  		  This is a comma seperated list of PHY types:  		    A  => A-PHY @@ -973,12 +972,30 @@ define KernelPackage/b43/config  	config PACKAGE_B43_PHY_N  		bool "Enable support for N-PHYs"  		select B43_FW_5_10 -		default n +		default y  		help  		  Enable support for BCM4321 and BCM4322.  		  Currently only 11g speed is available. +		  If unsure, say Y. + +	config PACKAGE_B43_PHY_HT +		bool "Enable support for HT-PHYs" +		select B43_FW_5_10 +		default n +		help +		  Currently borken. + +		  If unsure, say N. + +	config PACKAGE_B43_PHY_LCN +		bool "Enable support for LCN-PHYs" +		select B43_FW_5_10 +		default n +		help +		  Currently borken. +  		  If unsure, say N.  	endmenu @@ -1045,7 +1062,12 @@ BUILDFLAGS:= \  	$(if $(CONFIG_ATH_USER_REGD),-DATH_USER_REGD=1) \  	$(if $(CONFIG_PACKAGE_B43_DEBUG),-DCONFIG_B43_DEBUG) \  	$(if $(CONFIG_PACKAGE_B43_PIO),-DCONFIG_B43_PIO) \ +	$(if $(CONFIG_PACKAGE_B43_PIO),-DCONFIG_B43_BCMA_PIO) \  	$(if $(CONFIG_PACKAGE_B43_PHY_N),-DCONFIG_B43_PHY_N) \ +	$(if $(CONFIG_PACKAGE_B43_PHY_HT),-DCONFIG_B43_PHY_HT) \ +	$(if $(CONFIG_PACKAGE_B43_PHY_LCN),-DCONFIG_B43_PHY_LCN) \ +	-DCONFIG_B43_BCMA \ +	-DCONFIG_B43_SSB \  	$(if $(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS),-DCONFIG_RT2X00_LIB_DEBUGFS) \  	$(if $(CONFIG_PACKAGE_RT2X00_DEBUG),-DCONFIG_RT2X00_DEBUG) \  	$(if $(NEED_RT2X00_LIB_HT),-DCONFIG_RT2X00_LIB_HT) \ @@ -1081,7 +1103,12 @@ MAKE_OPTS:= \  	CONFIG_B43LEGACY=$(if $(CONFIG_PACKAGE_kmod-b43legacy),m) \  	CONFIG_B43_DEBUG=$(if $(CONFIG_PACKAGE_B43_DEBUG),y) \  	CONFIG_B43_PIO=$(if $(CONFIG_PACKAGE_B43_PIO),y) \ +	CONFIG_B43_BCMA_PIO=$(if $(CONFIG_PACKAGE_B43_PIO),y) \  	CONFIG_B43_PHY_N=$(if $(CONFIG_PACKAGE_B43_PHY_N),y) \ +	CONFIG_B43_PHY_HT=$(if $(CONFIG_PACKAGE_B43_PHY_HT),y) \ +	CONFIG_B43_PHY_LCN=$(if $(CONFIG_PACKAGE_B43_PHY_LCN),y) \ +	CONFIG_B43_BCMA=y \ +	CONFIG_B43_SSB=y \  	CONFIG_ATH_COMMON=$(if $(CONFIG_PACKAGE_kmod-ath),m) \  	CONFIG_ATH_DEBUG=$(if $(CONFIG_PACKAGE_ATH_DEBUG),y) \  	CONFIG_ATH9K_PKTLOG=$(if $(CONFIG_PACKAGE_ATH_DEBUG),y) \ @@ -1199,6 +1226,7 @@ define Build/Prepare  	$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2  	$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_LINUX_FIRMWARE_SOURCE)  	rm -rf $(PKG_BUILD_DIR)/include/linux/ssb +	rm -rf $(PKG_BUILD_DIR)/include/linux/bcma  	rm -f $(PKG_BUILD_DIR)/include/net/ieee80211.h  endef diff --git a/package/mac80211/patches/40-fix-compile-on-2-6-30.patch b/package/mac80211/patches/40-fix-compile-on-2-6-30.patch new file mode 100644 index 000000000..277358524 --- /dev/null +++ b/package/mac80211/patches/40-fix-compile-on-2-6-30.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/b43/main.c~	2011-07-23 00:33:46.573306410 +0200 ++++ b/drivers/net/wireless/b43/main.c	2011-07-23 00:36:14.657726075 +0200 +@@ -4955,7 +4955,7 @@ + static void b43_wireless_core_detach(struct b43_wldev *dev) + { + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) +-	if (dev->sdev->bus->bustype != SSB_BUSTYPE_SDIO) ++	if (dev->dev->sdev->bus->bustype != SSB_BUSTYPE_SDIO) + 		compat_destroy_threaded_irq(&dev->irq_compat); + #endif + 	/* We release firmware that late to not be required to re-request diff --git a/package/mac80211/patches/820-b43-backport.patch b/package/mac80211/patches/820-b43-backport.patch new file mode 100644 index 000000000..ec3b1440c --- /dev/null +++ b/package/mac80211/patches/820-b43-backport.patch @@ -0,0 +1,2568 @@ +--- a/drivers/net/wireless/b43/Kconfig ++++ b/drivers/net/wireless/b43/Kconfig +@@ -90,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 +@@ -125,6 +131,14 @@ config B43_PHY_HT +  + 	  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 +--- a/drivers/net/wireless/b43/Makefile ++++ b/drivers/net/wireless/b43/Makefile +@@ -11,7 +11,9 @@ 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 +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -433,6 +433,12 @@ enum { + #define  B43_BCMA_IOCTL_PHY_BW_40MHZ	0x00000080	/* 40 MHz bandwidth, 160 MHz PHY */ + #define B43_BCMA_IOCTL_GMODE		0x00002000	/* G Mode Enable */ +  ++/* BCMA 802.11 core specific IO status (BCMA_IOST) flags */ ++#define B43_BCMA_IOST_2G_PHY		0x00000001	/* 2.4G capable phy */ ++#define B43_BCMA_IOST_5G_PHY		0x00000002	/* 5G capable phy */ ++#define B43_BCMA_IOST_FASTCLKA		0x00000004	/* Fast Clock Available */ ++#define B43_BCMA_IOST_DUALB_PHY		0x00000008	/* Dualband phy */ ++ + /* 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) */ +@@ -588,6 +594,7 @@ struct b43_dma { + 	struct b43_dmaring *rx_ring; +  + 	u32 translation; /* Routing bits */ ++	bool parity; /* Check for parity */ + }; +  + struct b43_pio_txqueue; +@@ -726,7 +733,6 @@ enum { +  + /* Data structure for one wireless device (802.11 core) */ + struct b43_wldev { +-	struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */ + 	struct b43_bus_dev *dev; + 	struct b43_wl *wl; +  +--- a/drivers/net/wireless/b43/bus.c ++++ b/drivers/net/wireless/b43/bus.c +@@ -23,58 +23,155 @@ + #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) ++static 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, ++static 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) ++static 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, ++static 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, ++static 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) ++static 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) ++static 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) ++static 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) ++static 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) ++static 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 ++static + void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer, + 			     size_t count, u16 offset, u8 reg_width) + { +@@ -125,3 +222,32 @@ struct b43_bus_dev *b43_bus_dev_ssb_init + 	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 ++	} ++} +--- a/drivers/net/wireless/b43/bus.h ++++ b/drivers/net/wireless/b43/bus.h +@@ -2,12 +2,16 @@ + #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; + 	}; +  +@@ -57,6 +61,10 @@ static inline bool b43_bus_host_is_sdio( + 		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_ */ +--- a/drivers/net/wireless/b43/dma.c ++++ b/drivers/net/wireless/b43/dma.c +@@ -174,7 +174,7 @@ static void op64_fill_descriptor(struct + 	addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); + 	addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) + 	    >> SSB_DMA_TRANSLATION_SHIFT; +-	addrhi |= (ring->dev->dma.translation << 1); ++	addrhi |= ring->dev->dma.translation; + 	if (slot == ring->nr_slots - 1) + 		ctl0 |= B43_DMA64_DCTL0_DTABLEEND; + 	if (start) +@@ -659,6 +659,7 @@ static int dmacontroller_setup(struct b4 + 	u32 value; + 	u32 addrext; + 	u32 trans = ring->dev->dma.translation; ++	bool parity = ring->dev->dma.parity; +  + 	if (ring->tx) { + 		if (ring->type == B43_DMA_64BIT) { +@@ -669,13 +670,15 @@ static int dmacontroller_setup(struct b4 + 			value = B43_DMA64_TXENABLE; + 			value |= (addrext << B43_DMA64_TXADDREXT_SHIFT) + 			    & B43_DMA64_TXADDREXT_MASK; ++			if (!parity) ++				value |= B43_DMA64_TXPARITYDISABLE; + 			b43_dma_write(ring, B43_DMA64_TXCTL, value); + 			b43_dma_write(ring, B43_DMA64_TXRINGLO, + 				      (ringbase & 0xFFFFFFFF)); + 			b43_dma_write(ring, B43_DMA64_TXRINGHI, + 				      ((ringbase >> 32) & + 				       ~SSB_DMA_TRANSLATION_MASK) +-				      | (trans << 1)); ++				      | trans); + 		} else { + 			u32 ringbase = (u32) (ring->dmabase); +  +@@ -684,6 +687,8 @@ static int dmacontroller_setup(struct b4 + 			value = B43_DMA32_TXENABLE; + 			value |= (addrext << B43_DMA32_TXADDREXT_SHIFT) + 			    & B43_DMA32_TXADDREXT_MASK; ++			if (!parity) ++				value |= B43_DMA32_TXPARITYDISABLE; + 			b43_dma_write(ring, B43_DMA32_TXCTL, value); + 			b43_dma_write(ring, B43_DMA32_TXRING, + 				      (ringbase & ~SSB_DMA_TRANSLATION_MASK) +@@ -702,13 +707,15 @@ static int dmacontroller_setup(struct b4 + 			value |= B43_DMA64_RXENABLE; + 			value |= (addrext << B43_DMA64_RXADDREXT_SHIFT) + 			    & B43_DMA64_RXADDREXT_MASK; ++			if (!parity) ++				value |= B43_DMA64_RXPARITYDISABLE; + 			b43_dma_write(ring, B43_DMA64_RXCTL, value); + 			b43_dma_write(ring, B43_DMA64_RXRINGLO, + 				      (ringbase & 0xFFFFFFFF)); + 			b43_dma_write(ring, B43_DMA64_RXRINGHI, + 				      ((ringbase >> 32) & + 				       ~SSB_DMA_TRANSLATION_MASK) +-				      | (trans << 1)); ++				      | trans); + 			b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots * + 				      sizeof(struct b43_dmadesc64)); + 		} else { +@@ -720,6 +727,8 @@ static int dmacontroller_setup(struct b4 + 			value |= B43_DMA32_RXENABLE; + 			value |= (addrext << B43_DMA32_RXADDREXT_SHIFT) + 			    & B43_DMA32_RXADDREXT_MASK; ++			if (!parity) ++				value |= B43_DMA32_RXPARITYDISABLE; + 			b43_dma_write(ring, B43_DMA32_RXCTL, value); + 			b43_dma_write(ring, B43_DMA32_RXRING, + 				      (ringbase & ~SSB_DMA_TRANSLATION_MASK) +@@ -1055,7 +1064,26 @@ 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_BCMA ++	case B43_BUS_BCMA: ++		dma->translation = bcma_core_dma_translation(dev->dev->bdev); ++		break; ++#endif ++#ifdef CONFIG_B43_SSB ++	case B43_BUS_SSB: ++		dma->translation = ssb_dma_translation(dev->dev->sdev); ++		break; ++#endif ++	} ++ ++	dma->parity = true; ++#ifdef CONFIG_B43_BCMA ++	/* TODO: find out which SSB devices need disabling parity */ ++	if (dev->dev->bus_type == B43_BUS_BCMA) ++		dma->parity = false; ++#endif +  + 	err = -ENOMEM; + 	/* setup TX DMA channels. */ +@@ -1600,6 +1628,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; + } +--- a/drivers/net/wireless/b43/dma.h ++++ b/drivers/net/wireless/b43/dma.h +@@ -20,6 +20,7 @@ + #define		B43_DMA32_TXSUSPEND			0x00000002 + #define		B43_DMA32_TXLOOPBACK		0x00000004 + #define		B43_DMA32_TXFLUSH			0x00000010 ++#define		B43_DMA32_TXPARITYDISABLE		0x00000800 + #define		B43_DMA32_TXADDREXT_MASK		0x00030000 + #define		B43_DMA32_TXADDREXT_SHIFT		16 + #define B43_DMA32_TXRING				0x04 +@@ -44,6 +45,7 @@ + #define		B43_DMA32_RXFROFF_MASK		0x000000FE + #define		B43_DMA32_RXFROFF_SHIFT		1 + #define		B43_DMA32_RXDIRECTFIFO		0x00000100 ++#define		B43_DMA32_RXPARITYDISABLE		0x00000800 + #define		B43_DMA32_RXADDREXT_MASK		0x00030000 + #define		B43_DMA32_RXADDREXT_SHIFT		16 + #define B43_DMA32_RXRING				0x14 +@@ -84,6 +86,7 @@ struct b43_dmadesc32 { + #define		B43_DMA64_TXSUSPEND			0x00000002 + #define		B43_DMA64_TXLOOPBACK		0x00000004 + #define		B43_DMA64_TXFLUSH			0x00000010 ++#define		B43_DMA64_TXPARITYDISABLE		0x00000800 + #define		B43_DMA64_TXADDREXT_MASK		0x00030000 + #define		B43_DMA64_TXADDREXT_SHIFT		16 + #define B43_DMA64_TXINDEX				0x04 +@@ -111,6 +114,7 @@ struct b43_dmadesc32 { + #define		B43_DMA64_RXFROFF_MASK		0x000000FE + #define		B43_DMA64_RXFROFF_SHIFT		1 + #define		B43_DMA64_RXDIRECTFIFO		0x00000100 ++#define		B43_DMA64_RXPARITYDISABLE		0x00000800 + #define		B43_DMA64_RXADDREXT_MASK		0x00030000 + #define		B43_DMA64_RXADDREXT_SHIFT		16 + #define B43_DMA64_RXINDEX				0x24 +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -1136,6 +1136,41 @@ void b43_power_saving_ctl_bits(struct b4 + 	} + } +  ++#ifdef CONFIG_B43_BCMA ++static void b43_bcma_phy_reset(struct b43_wldev *dev) ++{ ++	u32 flags; ++ ++	/* Put PHY into reset */ ++	flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); ++	flags |= B43_BCMA_IOCTL_PHY_RESET; ++	flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */ ++	bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags); ++	udelay(2); ++ ++	/* Take PHY out of reset */ ++	flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); ++	flags &= ~B43_BCMA_IOCTL_PHY_RESET; ++	flags |= BCMA_IOCTL_FGC; ++	bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags); ++	udelay(1); ++ ++	/* Do not force clock anymore */ ++	flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); ++	flags &= ~BCMA_IOCTL_FGC; ++	bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags); ++	udelay(1); ++} ++ ++static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode) ++{ ++	b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN); ++	bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); ++	b43_bcma_phy_reset(dev); ++	bcma_core_pll_ctl(dev->dev->bdev, 0x300, 0x3000000, true); ++} ++#endif ++ + static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) + { + 	struct ssb_device *sdev = dev->dev->sdev; +@@ -1168,7 +1203,18 @@ void b43_wireless_core_reset(struct b43_ + { + 	u32 macctl; +  +-	b43_ssb_wireless_core_reset(dev, gmode); ++	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 +@@ -1921,7 +1967,7 @@ static irqreturn_t b43_do_interrupt(stru + 		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; +@@ -2116,21 +2162,43 @@ static int b43_try_request_fw(struct b43 + 	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; +@@ -2189,6 +2257,18 @@ static int b43_try_request_fw(struct b43 + 		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; + 	} +@@ -2236,6 +2316,18 @@ static int b43_try_request_fw(struct b43 + 		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; + 	} +@@ -2607,11 +2699,24 @@ static int b43_gpio_init(struct b43_wlde + 	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; + } +@@ -2621,9 +2726,21 @@ static void b43_gpio_cleanup(struct b43_ + { + 	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 */ +@@ -2695,12 +2812,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_aread32(dev->dev->bdev, BCMA_IOCTL); ++		if (on) ++			tmp |= B43_BCMA_IOCTL_MACPHYCLKEN; ++		else ++			tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN; ++		bcma_awrite32(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) +@@ -2939,8 +3074,20 @@ static int b43_chip_init(struct b43_wlde +  + 	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"); +@@ -3456,21 +3603,33 @@ static void b43_op_set_tsf(struct ieee80 +  + 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) +@@ -4100,6 +4259,12 @@ static int b43_phy_versioning(struct b43 + 			unsupported = 1; + 		break; + #endif ++#ifdef CONFIG_B43_PHY_LCN ++	case B43_PHYTYPE_LCN: ++		if (phy_rev > 1) ++			unsupported = 1; ++		break; ++#endif + 	default: + 		unsupported = 1; + 	}; +@@ -4113,22 +4278,42 @@ static int b43_phy_versioning(struct b43 + 	       analog_type, phy_type, phy_rev); +  + 	/* Get RADIO versioning */ +-	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; ++	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) { +@@ -4160,6 +4345,10 @@ static int b43_phy_versioning(struct b43 + 		if (radio_ver != 0x2059) + 			unsupported = 1; + 		break; ++	case B43_PHYTYPE_LCN: ++		if (radio_ver != 0x2064) ++			unsupported = 1; ++		break; + 	default: + 		B43_WARN_ON(1); + 	} +@@ -4343,7 +4532,6 @@ static void b43_wireless_core_exit(struc + /* 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 = dev->dev->bus_sprom; + 	struct b43_phy *phy = &dev->phy; + 	int err; +@@ -4362,7 +4550,20 @@ static int b43_wireless_core_init(struct + 	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); +@@ -4393,8 +4594,9 @@ static int b43_wireless_core_init(struct + 	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; +@@ -4764,9 +4966,9 @@ static void b43_wireless_core_detach(str + 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; ++	u32 tmp; + 	bool have_2ghz_phy = 0, have_5ghz_phy = 0; +  + 	/* Do NOT do any device initialization here. +@@ -4776,20 +4978,38 @@ static int b43_wireless_core_attach(stru + 	 * that in core_init(), too. + 	 */ +  ++#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->dev->core_rev >= 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: ++		tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST); ++		have_2ghz_phy = !!(tmp & B43_BCMA_IOST_2G_PHY); ++		have_5ghz_phy = !!(tmp & B43_BCMA_IOST_5G_PHY); ++		break; ++#endif ++#ifdef CONFIG_B43_SSB ++	case B43_BUS_SSB: ++		if (dev->dev->core_rev >= 5) { ++			tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); ++			have_2ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_2GHZ_PHY); ++			have_5ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_5GHZ_PHY); ++		} else ++			B43_WARN_ON(1); ++		break; ++#endif ++	} +  + 	dev->phy.gmode = have_2ghz_phy; + 	dev->phy.radio_on = 1; +@@ -4815,6 +5035,8 @@ static int b43_wireless_core_attach(stru + #endif + 		case B43_PHYTYPE_G: + 		case B43_PHYTYPE_N: ++		case B43_PHYTYPE_HT: ++		case B43_PHYTYPE_LCN: + 			have_2ghz_phy = 1; + 			break; + 		default: +@@ -4877,13 +5099,13 @@ static void b43_one_core_detach(struct b + 	/* Do not cancel ieee80211-workqueue based work here. + 	 * See comment in b43_remove(). */ +  +-	wldev = ssb_get_drvdata(dev->sdev); ++	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->sdev, NULL); ++	b43_bus_set_wldev(dev, NULL); + 	kfree(wldev); + } +  +@@ -4898,7 +5120,6 @@ static int b43_one_core_attach(struct b4 +  + 	wldev->use_pio = b43_modparam_pio; + 	wldev->dev = dev; +-	wldev->sdev = dev->sdev; /* TODO: Remove when not needed */ + 	wldev->wl = wl; + 	b43_set_status(wldev, B43_STAT_UNINIT); + 	wldev->bad_frames_preempt = modparam_bad_frames_preempt; +@@ -4910,7 +5131,7 @@ static int b43_one_core_attach(struct b4 +  + 	list_add(&wldev->list, &wl->devlist); + 	wl->nr_devs++; +-	ssb_set_drvdata(dev->sdev, wldev); ++	b43_bus_set_wldev(dev, wldev); + 	b43_debugfs_add_device(wldev); +  +       out: +@@ -4959,11 +5180,12 @@ static void b43_wireless_exit(struct b43 + 	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; ++	char chip_name[6]; +  + 	hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); + 	if (!hw) { +@@ -5002,21 +5224,70 @@ static struct b43_wl *b43_wireless_init( + 	INIT_WORK(&wl->tx_work, b43_tx_work); + 	skb_queue_head_init(&wl->tx_queue); +  +-	b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", +-		dev->bus->chip_id, dev->id.revision); ++	snprintf(chip_name, ARRAY_SIZE(chip_name), ++		 (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id); ++	b43info(wl, "Broadcom %s WLAN found (core revision %u)\n", chip_name, ++		dev->core_rev); + 	return wl; + } +  + #ifdef CONFIG_B43_BCMA + static int b43_bcma_probe(struct bcma_device *core) + { +-	b43err(NULL, "BCMA is not supported yet!"); +-	return -EOPNOTSUPP; ++	struct b43_bus_dev *dev; ++	struct b43_wl *wl; ++	int err; ++ ++	dev = b43_bus_dev_bcma_init(core); ++	if (!dev) ++		return -ENODEV; ++ ++	wl = b43_wireless_init(dev); ++	if (IS_ERR(wl)) { ++		err = PTR_ERR(wl); ++		goto bcma_out; ++	} ++ ++	err = b43_one_core_attach(dev, wl); ++	if (err) ++		goto bcma_err_wireless_exit; ++ ++	err = ieee80211_register_hw(wl->hw); ++	if (err) ++		goto bcma_err_one_core_detach; ++	b43_leds_register(wl->current_dev); ++ ++bcma_out: ++	return err; ++ ++bcma_err_one_core_detach: ++	b43_one_core_detach(dev); ++bcma_err_wireless_exit: ++	ieee80211_free_hw(wl->hw); ++	return err; + } +  + static void b43_bcma_remove(struct bcma_device *core) + { +-	/* TODO */ ++	struct b43_wldev *wldev = bcma_get_drvdata(core); ++	struct b43_wl *wl = wldev->wl; ++ ++	/* We must cancel any work here before unregistering from ieee80211, ++	 * as the ieee80211 unreg will destroy the workqueue. */ ++	cancel_work_sync(&wldev->restart_work); ++ ++	/* Restore the queues count before unregistering, because firmware detect ++	 * might have modified it. Restoring is important, so the networking ++	 * stack can properly free resources. */ ++	wl->hw->queues = wl->mac80211_initially_registered_queues; ++	b43_leds_stop(wldev); ++	ieee80211_unregister_hw(wl->hw); ++ ++	b43_one_core_detach(wldev->dev); ++ ++	b43_leds_unregister(wl); ++ ++	ieee80211_free_hw(wl->hw); + } +  + static struct bcma_driver b43_bcma_driver = { +@@ -5045,7 +5316,7 @@ int b43_ssb_probe(struct ssb_device *sde + 		/* Probing the first core. Must setup common struct b43_wl */ + 		first = 1; + 		b43_sprom_fixup(sdev->bus); +-		wl = b43_wireless_init(sdev); ++		wl = b43_wireless_init(dev); + 		if (IS_ERR(wl)) { + 			err = PTR_ERR(wl); + 			goto out; +--- a/drivers/net/wireless/b43/phy_common.c ++++ b/drivers/net/wireless/b43/phy_common.c +@@ -32,6 +32,7 @@ + #include "phy_n.h" + #include "phy_lp.h" + #include "phy_ht.h" ++#include "phy_lcn.h" + #include "b43.h" + #include "main.h" +  +@@ -65,6 +66,11 @@ int b43_phy_allocate(struct b43_wldev *d + 		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; +--- a/drivers/net/wireless/b43/phy_common.h ++++ b/drivers/net/wireless/b43/phy_common.h +@@ -198,6 +198,7 @@ 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. */ +@@ -222,6 +223,8 @@ struct b43_phy { + 		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. */ +--- a/drivers/net/wireless/b43/phy_ht.c ++++ b/drivers/net/wireless/b43/phy_ht.c +@@ -24,9 +24,14 @@ +  + #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) + { +@@ -56,7 +61,7 @@ static void b43_radio_2059_channel_setup + 	b43_radio_write(dev, 0x98, e->radio_syn98); +  + 	for (i = 0; i < 2; i++) { +-		routing = i ? 0x800 : 0x400; ++		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); +@@ -78,11 +83,120 @@ static void b43_radio_2059_channel_setup + 	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) + { +-	/* TODO */ ++	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, +@@ -139,6 +253,13 @@ static void b43_phy_ht_op_prepare_struct + 	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; +@@ -155,13 +276,25 @@ static void b43_phy_ht_op_software_rfkil + 	if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) + 		b43err(dev->wl, "MAC not suspended\n"); +  ++	/* In the following PHY ops we copy wl's dummy behaviour. ++	 * TODO: Find out if reads (currently hidden in masks/masksets) are ++	 * needed and replace following ops with just writes or w&r. ++	 * Note: B43_PHY_HT_RF_CTL1 register is tricky, wrong operation can ++	 * cause delayed (!) machine lock up. */ + 	if (blocked) { +-		b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); ++		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); ++		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); ++ ++		b43_switch_channel(dev, dev->phy.channel); + 	} + } +  +@@ -203,7 +336,7 @@ static int b43_phy_ht_op_switch_channel( + 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 11; + 	return 36; + } +  +@@ -247,6 +380,16 @@ static void b43_phy_ht_op_radio_write(st + 	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. +  **************************************************/ +@@ -255,9 +398,7 @@ const struct b43_phy_operations b43_phyo + 	.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, +@@ -267,8 +408,6 @@ const struct b43_phy_operations b43_phyo + 	.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, +-	*/ + }; +--- a/drivers/net/wireless/b43/phy_ht.h ++++ b/drivers/net/wireless/b43/phy_ht.h +@@ -4,9 +4,16 @@ + #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) +  +@@ -20,7 +27,12 @@ +  + /* Values for PHY registers used on channel switching */ + struct b43_phy_ht_channeltab_e_phy { +-	/* TODO */ ++	u16 bw1; ++	u16 bw2; ++	u16 bw3; ++	u16 bw4; ++	u16 bw5; ++	u16 bw6; + }; +  +  +--- /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, ++	*/ ++}; +--- /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 +--- a/drivers/net/wireless/b43/phy_n.c ++++ b/drivers/net/wireless/b43/phy_n.c +@@ -603,17 +603,33 @@ static void b43_nphy_tx_lp_fbw(struct b4 + /* 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_aread32(dev->dev->bdev, BCMA_IOCTL); ++		if (force) ++			tmp |= BCMA_IOCTL_FGC; ++		else ++			tmp &= ~BCMA_IOCTL_FGC; ++		bcma_awrite32(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 */ +@@ -958,8 +974,21 @@ static void b43_nphy_superswitch_init(st + 		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); +@@ -3600,7 +3629,20 @@ int b43_phy_initn(struct b43_wldev *dev) + 	if ((dev->phy.rev >= 3) && + 	   (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); +--- a/drivers/net/wireless/b43/radio_2059.c ++++ b/drivers/net/wireless/b43/radio_2059.c +@@ -23,8 +23,152 @@ + #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) + { ++	const struct b43_phy_ht_channeltab_e_radio2059 *e; ++	unsigned int i; ++ ++	e = b43_phy_ht_channeltab_radio2059; ++	for (i = 0; i < ARRAY_SIZE(b43_phy_ht_channeltab_radio2059); i++, e++) { ++		if (e->freq == freq) ++			return e; ++	} ++ + 	return NULL; + } +--- a/drivers/net/wireless/b43/radio_2059.h ++++ b/drivers/net/wireless/b43/radio_2059.h +@@ -5,6 +5,11 @@ +  + #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 */ +--- /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); ++} +--- /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_ */ +--- /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) ++{ ++} +--- /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/package/mac80211/patches/830-b43-read-correct-register-on-bcma-bus.patch b/package/mac80211/patches/830-b43-read-correct-register-on-bcma-bus.patch new file mode 100644 index 000000000..8d88a66b5 --- /dev/null +++ b/package/mac80211/patches/830-b43-read-correct-register-on-bcma-bus.patch @@ -0,0 +1,40 @@ +From f706821596d8a3dcda314c38b13d91f108fdc435 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Fri, 22 Jul 2011 17:10:29 +0200 +Subject: [PATCH 21/22] b43: read correct register on bcma bus. + + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + drivers/net/wireless/b43/dma.c |   20 +++++++++++++++++--- + 1 files changed, 17 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/b43/dma.c ++++ b/drivers/net/wireless/b43/dma.c +@@ -795,9 +795,23 @@ static u64 supported_dma_mask(struct b43 + 	u32 tmp; + 	u16 mmio_base; +  +-	tmp = b43_read32(dev, SSB_TMSHIGH); +-	if (tmp & SSB_TMSHIGH_DMA64) +-		return DMA_BIT_MASK(64); ++	switch (dev->dev->bus_type) { ++#ifdef CONFIG_B43_BCMA ++	case B43_BUS_BCMA: ++		tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST); ++		if (tmp & BCMA_IOST_DMA64) ++			return DMA_BIT_MASK(64); ++		break; ++#endif ++#ifdef CONFIG_B43_SSB ++	case B43_BUS_SSB: ++		tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); ++		if (tmp & SSB_TMSHIGH_DMA64) ++			return DMA_BIT_MASK(64); ++		break; ++#endif ++	} ++ + 	mmio_base = b43_dmacontroller_base(0, 0); + 	b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK); + 	tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL); diff --git a/package/mac80211/patches/840-b43-bus_fix_memory_corruption_when_setting_drivers.patch b/package/mac80211/patches/840-b43-bus_fix_memory_corruption_when_setting_drivers.patch new file mode 100644 index 000000000..77a48dbc1 --- /dev/null +++ b/package/mac80211/patches/840-b43-bus_fix_memory_corruption_when_setting_drivers.patch @@ -0,0 +1,26 @@ +Fixes bug described in:
 +https://bugzilla.kernel.org/show_bug.cgi?id=39172
 +
 +Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 +---
 +John: this is trivial and fixes quite ugly memory (linked list exactly)
 +corruption. I believe this fix should be taken for 3.1.
 +---
 + drivers/net/wireless/b43/bus.c |    2 ++
 + 1 files changed, 2 insertions(+), 0 deletions(-)
 +
 +--- a/drivers/net/wireless/b43/bus.c ++++ b/drivers/net/wireless/b43/bus.c +@@ -244,10 +244,12 @@ void b43_bus_set_wldev(struct b43_bus_de + #ifdef CONFIG_B43_BCMA + 	case B43_BUS_BCMA: + 		bcma_set_drvdata(dev->bdev, wldev); ++		break; + #endif + #ifdef CONFIG_B43_SSB + 	case B43_BUS_SSB: + 		ssb_set_drvdata(dev->sdev, wldev); ++		break; + #endif + 	} + } diff --git a/package/mac80211/patches/850-b43-add-core-rev-17-used-on-bcma-SoC.patch b/package/mac80211/patches/850-b43-add-core-rev-17-used-on-bcma-SoC.patch new file mode 100644 index 000000000..24a38b596 --- /dev/null +++ b/package/mac80211/patches/850-b43-add-core-rev-17-used-on-bcma-SoC.patch @@ -0,0 +1,21 @@ +From 46c79b0cdc60a974da409d641a69086694046ea0 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Fri, 22 Jul 2011 17:47:46 +0200 +Subject: [PATCH 23/23] b43: add core rev 17 used on bcma SoC + + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + drivers/net/wireless/b43/main.c |    1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -120,6 +120,7 @@ MODULE_PARM_DESC(pio, "Use PIO accesses +  + #ifdef CONFIG_B43_BCMA + static const struct bcma_device_id b43_bcma_tbl[] = { ++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS), + 	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), | 
