linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 1/10] Port of bcm43xx from softmac to mac80211
@ 2007-08-02 15:53 Larry Finger
  2007-08-03 14:30 ` Stefano Brivio
  0 siblings, 1 reply; 3+ messages in thread
From: Larry Finger @ 2007-08-02 15:53 UTC (permalink / raw)
  To: Michael Buesch; +Cc: Bcm43xx-dev, linux-wireless

This if file 1 of 10 of the port of the bcm43xx driver from softmac
to mac80211.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---

Index: linux-2.6/drivers/net/wireless/bcm43xx/Kconfig
===================================================================
--- linux-2.6.orig/drivers/net/wireless/bcm43xx/Kconfig
+++ linux-2.6/drivers/net/wireless/bcm43xx/Kconfig
@@ -1,16 +1,18 @@
 config BCM43XX
-	tristate "Broadcom BCM43xx wireless support"
-	depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL
-	select WIRELESS_EXT
+	tristate "Broadcom BCM43xx wireless support (mac80211 stack)"
+	depends on MAC80211 && WLAN_80211 && EXPERIMENTAL && HAS_IOMEM
 	select FW_LOADER
+	select SSB
 	select HW_RANDOM
 	---help---
-	  This is an experimental driver for the Broadcom 43xx wireless chip,
+	  This is a port of the original driver for the Broadcom 43xx wireless
+	  chip from SoftMAC to the better mac80211 MAC layer. This device is
 	  found in the Apple Airport Extreme and various other devices.
 
 config BCM43XX_DEBUG
 	bool "Broadcom BCM43xx debugging (RECOMMENDED)"
 	depends on BCM43XX
+	select SSB_DEBUG if !SSB_SILENT
 	default y
 	---help---
 	  Broadcom 43xx debugging messages.
Index: linux-2.6/drivers/net/wireless/bcm43xx/Makefile
===================================================================
--- linux-2.6.orig/drivers/net/wireless/bcm43xx/Makefile
+++ linux-2.6/drivers/net/wireless/bcm43xx/Makefile
@@ -4,9 +4,11 @@ bcm43xx-obj-$(CONFIG_BCM43XX_DEBUG) += b
 bcm43xx-obj-$(CONFIG_BCM43XX_DMA) += bcm43xx_dma.o
 bcm43xx-obj-$(CONFIG_BCM43XX_PIO) += bcm43xx_pio.o
 
-bcm43xx-objs := bcm43xx_main.o bcm43xx_ilt.o \
-		bcm43xx_radio.o bcm43xx_phy.o \
-		bcm43xx_power.o bcm43xx_wx.o \
-		bcm43xx_leds.o bcm43xx_ethtool.o \
-		bcm43xx_xmit.o bcm43xx_sysfs.o \
-		$(bcm43xx-obj-y)
+bcm43xx-objs := 	bcm43xx_main.o \
+			bcm43xx_ilt.o \
+			bcm43xx_leds.o \
+		        bcm43xx_phy.o \
+			bcm43xx_radio.o \
+	        	bcm43xx_sysfs.o \
+			bcm43xx_xmit.o \
+			$(bcm43xx-obj-y)
Index: linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx.h
===================================================================
--- linux-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -2,35 +2,29 @@
 #define BCM43xx_H_
 
 #include <linux/hw_random.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/stringify.h>
+#include <linux/netdevice.h>
 #include <linux/pci.h>
-#include <net/ieee80211.h>
-#include <net/ieee80211softmac.h>
 #include <asm/atomic.h>
 #include <asm/io.h>
 
+#include <linux/ssb/ssb.h>
+#include <linux/ssb/ssb_driver_chipcommon.h>
+
+#include <linux/wireless.h>
+#include <net/mac80211.h>
 
 #include "bcm43xx_debugfs.h"
 #include "bcm43xx_leds.h"
+#include "bcm43xx_phy.h"
 
 
-#define PFX				KBUILD_MODNAME ": "
-
-#define BCM43xx_SWITCH_CORE_MAX_RETRIES	50
 #define BCM43xx_IRQWAIT_MAX_RETRIES	100
 
-#define BCM43xx_IO_SIZE			8192
-
-/* Active Core PCI Configuration Register. */
-#define BCM43xx_PCICFG_ACTIVE_CORE	0x80
-/* SPROM control register. */
-#define BCM43xx_PCICFG_SPROMCTL		0x88
-/* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */
-#define BCM43xx_PCICFG_ICR		0x94
+#define BCM43xx_RX_MAX_SSI		60
 
 /* MMIO offsets */
 #define BCM43xx_MMIO_DMA0_REASON	0x20
@@ -45,6 +39,7 @@
 #define BCM43xx_MMIO_DMA4_IRQ_MASK	0x44
 #define BCM43xx_MMIO_DMA5_REASON	0x48
 #define BCM43xx_MMIO_DMA5_IRQ_MASK	0x4C
+#define BCM43xx_MMIO_MACCTL		0x120
 #define BCM43xx_MMIO_STATUS_BITFIELD	0x120
 #define BCM43xx_MMIO_STATUS2_BITFIELD	0x124
 #define BCM43xx_MMIO_GEN_IRQ_REASON	0x128
@@ -83,6 +78,7 @@
 
 #define BCM43xx_MMIO_PHY_VER		0x3E0
 #define BCM43xx_MMIO_PHY_RADIO		0x3E2
+#define BCM43xx_MMIO_PHY0		0x3E6
 #define BCM43xx_MMIO_ANTENNA		0x3E8
 #define BCM43xx_MMIO_CHANNEL		0x3F0
 #define BCM43xx_MMIO_CHANNEL_EXT	0x3F4
@@ -93,6 +89,7 @@
 #define BCM43xx_MMIO_PHY_DATA		0x3FE
 #define BCM43xx_MMIO_MACFILTER_CONTROL	0x420
 #define BCM43xx_MMIO_MACFILTER_DATA	0x422
+#define BCM43xx_MMIO_RCMTA_COUNT	0x43C
 #define BCM43xx_MMIO_RADIO_HWENABLED_LO	0x49A
 #define BCM43xx_MMIO_GPIO_CONTROL	0x49C
 #define BCM43xx_MMIO_GPIO_MASK		0x49E
@@ -103,214 +100,72 @@
 #define BCM43xx_MMIO_RNG		0x65A
 #define BCM43xx_MMIO_POWERUP_DELAY	0x6A8
 
-/* SPROM offsets. */
-#define BCM43xx_SPROM_BASE		0x1000
-#define BCM43xx_SPROM_BOARDFLAGS2	0x1c
-#define BCM43xx_SPROM_IL0MACADDR	0x24
-#define BCM43xx_SPROM_ET0MACADDR	0x27
-#define BCM43xx_SPROM_ET1MACADDR	0x2a
-#define BCM43xx_SPROM_ETHPHY		0x2d
-#define BCM43xx_SPROM_BOARDREV		0x2e
-#define BCM43xx_SPROM_PA0B0		0x2f
-#define BCM43xx_SPROM_PA0B1		0x30
-#define BCM43xx_SPROM_PA0B2		0x31
-#define BCM43xx_SPROM_WL0GPIO0		0x32
-#define BCM43xx_SPROM_WL0GPIO2		0x33
-#define BCM43xx_SPROM_MAXPWR		0x34
-#define BCM43xx_SPROM_PA1B0		0x35
-#define BCM43xx_SPROM_PA1B1		0x36
-#define BCM43xx_SPROM_PA1B2		0x37
-#define BCM43xx_SPROM_IDL_TSSI_TGT	0x38
-#define BCM43xx_SPROM_BOARDFLAGS	0x39
-#define BCM43xx_SPROM_ANTENNA_GAIN	0x3a
-#define BCM43xx_SPROM_VERSION		0x3f
-
-/* BCM43xx_SPROM_BOARDFLAGS values */
-#define BCM43xx_BFL_BTCOEXIST		0x0001 /* implements Bluetooth coexistance */
-#define BCM43xx_BFL_PACTRL		0x0002 /* GPIO 9 controlling the PA */
-#define BCM43xx_BFL_AIRLINEMODE		0x0004 /* implements GPIO 13 radio disable indication */
-#define BCM43xx_BFL_RSSI		0x0008 /* software calculates nrssi slope. */
-#define BCM43xx_BFL_ENETSPI		0x0010 /* has ephy roboswitch spi */
-#define BCM43xx_BFL_XTAL_NOSLOW		0x0020 /* no slow clock available */
-#define BCM43xx_BFL_CCKHIPWR		0x0040 /* can do high power CCK transmission */
-#define BCM43xx_BFL_ENETADM		0x0080 /* has ADMtek switch */
-#define BCM43xx_BFL_ENETVLAN		0x0100 /* can do vlan */
-#define BCM43xx_BFL_AFTERBURNER		0x0200 /* supports Afterburner mode */
-#define BCM43xx_BFL_NOPCI		0x0400 /* leaves PCI floating */
-#define BCM43xx_BFL_FEM			0x0800 /* supports the Front End Module */
-#define BCM43xx_BFL_EXTLNA		0x1000 /* has an external LNA */
-#define BCM43xx_BFL_HGPA		0x2000 /* had high gain PA */
-#define BCM43xx_BFL_BTCMOD		0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */
-#define BCM43xx_BFL_ALTIQ		0x8000 /* alternate I/Q settings */
+/* SPROM boardflags_lo values */
+#define BCM43xx_BFL_PACTRL		0x0002
+#define BCM43xx_BFL_RSSI		0x0008
+#define BCM43xx_BFL_EXTLNA		0x1000
 
 /* GPIO register offset, in both ChipCommon and PCI core. */
 #define BCM43xx_GPIO_CONTROL		0x6c
 
 /* SHM Routing */
-#define BCM43xx_SHM_SHARED		0x0001
-#define BCM43xx_SHM_WIRELESS		0x0002
-#define BCM43xx_SHM_PCM			0x0003
-#define BCM43xx_SHM_HWMAC		0x0004
-#define BCM43xx_SHM_UCODE		0x0300
-
-/* MacFilter offsets. */
-#define BCM43xx_MACFILTER_SELF		0x0000
-#define BCM43xx_MACFILTER_ASSOC		0x0003
+#define	BCM43xx_SHM_SHARED		0x0001
+#define	BCM43xx_SHM_WIRELESS		0x0002
+#define	BCM43xx_SHM_HW			0x0004
+#define	BCM43xx_SHM_UCODE		0x0300
+
+/* SHM Routing modifiers */
+#define BCM43xx_SHM_AUTOINC_R		0x0200 /* Read Auto-increment */
+#define BCM43xx_SHM_AUTOINC_W		0x0100 /* Write Auto-increment */
+#define BCM43xx_SHM_AUTOINC_RW		(BCM43xx_SHM_AUTOINC_R | \
+					 BCM43xx_SHM_AUTOINC_W)
+
+/* Misc SHM_SHARED offsets */
+#define BCM43xx_SHM_SH_WLCOREREV	0x0016 /* 802.11 core revision */
+#define BCM43xx_SHM_SH_HOSTFLO		0x005E /* Hostflags ucode opts (low) */
+#define BCM43xx_SHM_SH_HOSTFHI		0x0060 /* Hostflags ucode opts (high) */
+/* SHM_SHARED crypto engine */
+#define BCM43xx_SHM_SH_KEYIDXBLOCK	0x05D4 /* Key index/algorithm block */
+/* SHM_SHARED beacon variables */
+#define BCM43xx_SHM_SH_BEACPHYCTL	0x0054 /* Beacon PHY TX control word */
+/* SHM_SHARED ACK/CTS control */
+#define BCM43xx_SHM_SH_ACKCTSPHYCTL	0x0022 /* ACK/CTS PHY control word */
+/* SHM_SHARED probe response variables */
+#define BCM43xx_SHM_SH_PRPHYCTL		0x0188 /* Probe Resp PHY TX control */
+/* SHM_SHARED rate tables */
+/* SHM_SHARED microcode soft registers */
+#define BCM43xx_SHM_SH_UCODEREV		0x0000 /* Microcode revision */
+#define BCM43xx_SHM_SH_UCODEPATCH	0x0002 /* Microcode patchlevel */
+#define BCM43xx_SHM_SH_UCODEDATE	0x0004 /* Microcode date */
+#define BCM43xx_SHM_SH_UCODETIME	0x0006 /* Microcode time */
 
-/* Chipcommon registers. */
-#define BCM43xx_CHIPCOMMON_CAPABILITIES 	0x04
-#define BCM43xx_CHIPCOMMON_CTL			0x28
-#define BCM43xx_CHIPCOMMON_PLLONDELAY		0xB0
-#define BCM43xx_CHIPCOMMON_FREFSELDELAY		0xB4
-#define BCM43xx_CHIPCOMMON_SLOWCLKCTL		0xB8
-#define BCM43xx_CHIPCOMMON_SYSCLKCTL		0xC0
-
-/* PCI core specific registers. */
-#define BCM43xx_PCICORE_BCAST_ADDR	0x50
-#define BCM43xx_PCICORE_BCAST_DATA	0x54
-#define BCM43xx_PCICORE_SBTOPCI2	0x108
-
-/* SBTOPCI2 values. */
-#define BCM43xx_SBTOPCI2_PREFETCH	0x4
-#define BCM43xx_SBTOPCI2_BURST		0x8
-#define BCM43xx_SBTOPCI2_MEMREAD_MULTI	0x20
-
-/* PCI-E core registers. */
-#define BCM43xx_PCIECORE_REG_ADDR      0x0130
-#define BCM43xx_PCIECORE_REG_DATA      0x0134
-#define BCM43xx_PCIECORE_MDIO_CTL      0x0128
-#define BCM43xx_PCIECORE_MDIO_DATA     0x012C
-
-/* PCI-E registers. */
-#define BCM43xx_PCIE_TLP_WORKAROUND    0x0004
-#define BCM43xx_PCIE_DLLP_LINKCTL      0x0100
-
-/* PCI-E MDIO bits. */
-#define BCM43xx_PCIE_MDIO_ST   0x40000000
-#define BCM43xx_PCIE_MDIO_WT   0x10000000
-#define BCM43xx_PCIE_MDIO_DEV  22
-#define BCM43xx_PCIE_MDIO_REG  18
-#define BCM43xx_PCIE_MDIO_TA   0x00020000
-#define BCM43xx_PCIE_MDIO_TC   0x0100
-
-/* MDIO devices. */
-#define BCM43xx_MDIO_SERDES_RX	0x1F
-
-/* SERDES RX registers. */
-#define BCM43xx_SERDES_RXTIMER	0x2
-#define BCM43xx_SERDES_CDR	0x6
-#define BCM43xx_SERDES_CDR_BW	0x7
-
-/* Chipcommon capabilities. */
-#define BCM43xx_CAPABILITIES_PCTL		0x00040000
-#define BCM43xx_CAPABILITIES_PLLMASK		0x00030000
-#define BCM43xx_CAPABILITIES_PLLSHIFT		16
-#define BCM43xx_CAPABILITIES_FLASHMASK		0x00000700
-#define BCM43xx_CAPABILITIES_FLASHSHIFT		8
-#define BCM43xx_CAPABILITIES_EXTBUSPRESENT	0x00000040
-#define BCM43xx_CAPABILITIES_UARTGPIO		0x00000020
-#define BCM43xx_CAPABILITIES_UARTCLOCKMASK	0x00000018
-#define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT	3
-#define BCM43xx_CAPABILITIES_MIPSBIGENDIAN	0x00000004
-#define BCM43xx_CAPABILITIES_NRUARTSMASK	0x00000003
-
-/* PowerControl */
-#define BCM43xx_PCTL_IN			0xB0
-#define BCM43xx_PCTL_OUT		0xB4
-#define BCM43xx_PCTL_OUTENABLE		0xB8
-#define BCM43xx_PCTL_XTAL_POWERUP	0x40
-#define BCM43xx_PCTL_PLL_POWERDOWN	0x80
-
-/* PowerControl Clock Modes */
-#define BCM43xx_PCTL_CLK_FAST		0x00
-#define BCM43xx_PCTL_CLK_SLOW		0x01
-#define BCM43xx_PCTL_CLK_DYNAMIC	0x02
-
-#define BCM43xx_PCTL_FORCE_SLOW		0x0800
-#define BCM43xx_PCTL_FORCE_PLL		0x1000
-#define BCM43xx_PCTL_DYN_XTAL		0x2000
-
-/* COREIDs */
-#define BCM43xx_COREID_CHIPCOMMON	0x800
-#define BCM43xx_COREID_ILINE20          0x801
-#define BCM43xx_COREID_SDRAM            0x803
-#define BCM43xx_COREID_PCI		0x804
-#define BCM43xx_COREID_MIPS             0x805
-#define BCM43xx_COREID_ETHERNET         0x806
-#define BCM43xx_COREID_V90		0x807
-#define BCM43xx_COREID_USB11_HOSTDEV    0x80a
-#define BCM43xx_COREID_IPSEC            0x80b
-#define BCM43xx_COREID_PCMCIA		0x80d
-#define BCM43xx_COREID_EXT_IF           0x80f
-#define BCM43xx_COREID_80211		0x812
-#define BCM43xx_COREID_MIPS_3302        0x816
-#define BCM43xx_COREID_USB11_HOST       0x817
-#define BCM43xx_COREID_USB11_DEV        0x818
-#define BCM43xx_COREID_USB20_HOST       0x819
-#define BCM43xx_COREID_USB20_DEV        0x81a
-#define BCM43xx_COREID_SDIO_HOST        0x81b
-#define BCM43xx_COREID_PCIE		0x820
+#define BCM43xx_UCODEFLAGS_OFFSET       0x005E
 
-/* Core Information Registers */
-#define BCM43xx_CIR_BASE		0xf00
-#define BCM43xx_CIR_SBTPSFLAG		(BCM43xx_CIR_BASE + 0x18)
-#define BCM43xx_CIR_SBIMSTATE		(BCM43xx_CIR_BASE + 0x90)
-#define BCM43xx_CIR_SBINTVEC		(BCM43xx_CIR_BASE + 0x94)
-#define BCM43xx_CIR_SBTMSTATELOW	(BCM43xx_CIR_BASE + 0x98)
-#define BCM43xx_CIR_SBTMSTATEHIGH	(BCM43xx_CIR_BASE + 0x9c)
-#define BCM43xx_CIR_SBIMCONFIGLOW	(BCM43xx_CIR_BASE + 0xa8)
-#define BCM43xx_CIR_SB_ID_HI		(BCM43xx_CIR_BASE + 0xfc)
-
-/* Mask to get the Backplane Flag Number from SBTPSFLAG. */
-#define BCM43xx_BACKPLANE_FLAG_NR_MASK	0x3f
-
-/* SBIMCONFIGLOW values/masks. */
-#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK		0x00000007
-#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT	0
-#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK		0x00000070
-#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT	4
-#define BCM43xx_SBIMCONFIGLOW_CONNID_MASK		0x00ff0000
-#define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT		16
-
-/* sbtmstatelow state flags */
-#define BCM43xx_SBTMSTATELOW_RESET		0x01
-#define BCM43xx_SBTMSTATELOW_REJECT		0x02
-#define BCM43xx_SBTMSTATELOW_CLOCK		0x10000
-#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK	0x20000
-#define BCM43xx_SBTMSTATELOW_G_MODE_ENABLE	0x20000000
+/* Hardware Radio Enable masks */
+#define BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK (1 << 16)
+#define BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4)
 
-/* sbtmstatehigh state flags */
-#define BCM43xx_SBTMSTATEHIGH_SERROR		0x00000001
-#define BCM43xx_SBTMSTATEHIGH_BUSY		0x00000004
-#define BCM43xx_SBTMSTATEHIGH_TIMEOUT		0x00000020
-#define BCM43xx_SBTMSTATEHIGH_G_PHY_AVAIL	0x00010000
-#define BCM43xx_SBTMSTATEHIGH_A_PHY_AVAIL	0x00020000
-#define BCM43xx_SBTMSTATEHIGH_COREFLAGS		0x1FFF0000
-#define BCM43xx_SBTMSTATEHIGH_DMA64BIT		0x10000000
-#define BCM43xx_SBTMSTATEHIGH_GATEDCLK		0x20000000
-#define BCM43xx_SBTMSTATEHIGH_BISTFAILED	0x40000000
-#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE	0x80000000
+/* HostFlags. See bcm43xx_hf_read/write() */
+#define BCM43xx_HF_SYMW			0x00000002 /* G-PHY SYM workaround */
+#define BCM43xx_HF_GDCW			0x00000020 /* G-PHY DV cancel filter */
+#define BCM43xx_HF_OFDMPABOOST		0x00000040 /* Enable PA boost OFDM */
+#define BCM43xx_HF_EDCF			0x00000100 /* on if WME/MAC suspended */
 
-/* sbimstate flags */
-#define BCM43xx_SBIMSTATE_IB_ERROR		0x20000
-#define BCM43xx_SBIMSTATE_TIMEOUT		0x40000
+/* MacFilter offsets. */
+#define BCM43xx_MACFILTER_SELF		0x0000
+#define BCM43xx_MACFILTER_BSSID		0x0003
+#define BCM43xx_MACFILTER_MAC		0x0010
 
 /* PHYVersioning */
-#define BCM43xx_PHYTYPE_A		0x00
 #define BCM43xx_PHYTYPE_B		0x01
 #define BCM43xx_PHYTYPE_G		0x02
 
 /* PHYRegisters */
-#define BCM43xx_PHY_ILT_A_CTRL		0x0072
-#define BCM43xx_PHY_ILT_A_DATA1		0x0073
-#define BCM43xx_PHY_ILT_A_DATA2		0x0074
 #define BCM43xx_PHY_G_LO_CONTROL	0x0810
 #define BCM43xx_PHY_ILT_G_CTRL		0x0472
 #define BCM43xx_PHY_ILT_G_DATA1		0x0473
 #define BCM43xx_PHY_ILT_G_DATA2		0x0474
-#define BCM43xx_PHY_A_PCTL		0x007B
 #define BCM43xx_PHY_G_PCTL		0x0029
-#define BCM43xx_PHY_A_CRS		0x0029
 #define BCM43xx_PHY_RADIO_BITFIELD	0x0401
 #define BCM43xx_PHY_G_CRS		0x0429
 #define BCM43xx_PHY_NRSSILT_CTRL	0x0803
@@ -319,13 +174,20 @@
 /* RadioRegisters */
 #define BCM43xx_RADIOCTL_ID		0x01
 
+/* MAC Control bitfield */
+#define BCM43xx_MACCTL_IHR_ENABLED	0x00000400 /* IHR Region Enabled */
+#define BCM43xx_MACCTL_INFRA		0x00020000 /* Infrastructure mode */
+#define BCM43xx_MACCTL_AP		0x00040000 /* AccessPoint mode */
+#define BCM43xx_MACCTL_KEEP_BADPLCP	0x00200000 /* Keep bad PLCP frames */
+#define BCM43xx_MACCTL_KEEP_CTL		0x00400000 /* Keep control frames */
+#define BCM43xx_MACCTL_KEEP_BAD		0x00800000 /* Keep bad frames (FCS) */
+#define BCM43xx_MACCTL_PROMISC		0x01000000 /* Promiscuous mode */
+#define BCM43xx_MACCTL_GMODE		0x80000000 /* G Mode */
+
 /* StatusBitField */
 #define BCM43xx_SBF_MAC_ENABLED		0x00000001
-#define BCM43xx_SBF_2			0x00000002 /*FIXME: fix name*/
 #define BCM43xx_SBF_CORE_READY		0x00000004
 #define BCM43xx_SBF_400			0x00000400 /*FIXME: fix name*/
-#define BCM43xx_SBF_4000		0x00004000 /*FIXME: fix name*/
-#define BCM43xx_SBF_8000		0x00008000 /*FIXME: fix name*/
 #define BCM43xx_SBF_XFER_REG_BYTESWAP	0x00010000
 #define BCM43xx_SBF_MODE_NOTADHOC	0x00020000
 #define BCM43xx_SBF_MODE_AP		0x00040000
@@ -336,142 +198,146 @@
 #define BCM43xx_SBF_PS2			0x04000000
 #define BCM43xx_SBF_NO_SSID_BCAST	0x08000000
 #define BCM43xx_SBF_TIME_UPDATE		0x10000000
-#define BCM43xx_SBF_MODE_G		0x80000000
 
-/* Microcode */
-#define BCM43xx_UCODE_REVISION		0x0000
-#define BCM43xx_UCODE_PATCHLEVEL	0x0002
-#define BCM43xx_UCODE_DATE		0x0004
-#define BCM43xx_UCODE_TIME		0x0006
-#define BCM43xx_UCODE_STATUS		0x0040
-
-/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
-#define BCM43xx_UCODEFLAGS_OFFSET	0x005E
-
-#define BCM43xx_UCODEFLAG_AUTODIV	0x0001
-#define BCM43xx_UCODEFLAG_UNKBGPHY	0x0002
-#define BCM43xx_UCODEFLAG_UNKBPHY	0x0004
-#define BCM43xx_UCODEFLAG_UNKGPHY	0x0020
-#define BCM43xx_UCODEFLAG_UNKPACTRL	0x0040
-#define BCM43xx_UCODEFLAG_JAPAN		0x0080
+/* 802.11 core specific TM State Low flags */
+#define BCM43xx_TMSLOW_GMODE		0x20000000 /* G Mode Enable */
+#define BCM43xx_TMSLOW_PLLREFSEL	0x00200000 /* PLL Freq Ref Select */
+#define BCM43xx_TMSLOW_MACPHYCLKEN	0x00100000 /* MAC PHY Clock Ctrl Enbl */
+#define BCM43xx_TMSLOW_PHYRESET		0x00080000 /* PHY Reset */
+#define BCM43xx_TMSLOW_PHYCLKEN		0x00040000 /* PHY Clock Enable */
+
+/* 802.11 core specific TM State High flags */
+#define BCM43xx_TMSHIGH_FCLOCK		0x00040000 /* Fast Clock Available */
+#define BCM43xx_TMSHIGH_GPHY		0x00010000 /* G-PHY avail (rev >= 5) */
 
-/* Hardware Radio Enable masks */
-#define BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK (1 << 16)
-#define BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4)
+#define BCM43xx_UCODEFLAG_AUTODIV        0x0001
 
 /* Generic-Interrupt reasons. */
-#define BCM43xx_IRQ_READY		(1 << 0)
-#define BCM43xx_IRQ_BEACON		(1 << 1)
-#define BCM43xx_IRQ_PS			(1 << 2)
-#define BCM43xx_IRQ_REG124		(1 << 5)
-#define BCM43xx_IRQ_PMQ			(1 << 6)
-#define BCM43xx_IRQ_PIO_WORKAROUND	(1 << 8)
-#define BCM43xx_IRQ_XMIT_ERROR		(1 << 11)
-#define BCM43xx_IRQ_RX			(1 << 15)
-#define BCM43xx_IRQ_SCAN		(1 << 16)
-#define BCM43xx_IRQ_NOISE		(1 << 18)
-#define BCM43xx_IRQ_XMIT_STATUS		(1 << 29)
-
-#define BCM43xx_IRQ_ALL			0xffffffff
-#define BCM43xx_IRQ_INITIAL		(BCM43xx_IRQ_PS |		\
-					 BCM43xx_IRQ_REG124 |		\
+#define BCM43xx_IRQ_MAC_SUSPENDED	0x00000001
+#define BCM43xx_IRQ_BEACON		0x00000002
+#define BCM43xx_IRQ_TBTT_INDI		0x00000004
+#define BCM43xx_IRQ_BEACON_TX_OK	0x00000008
+#define BCM43xx_IRQ_BEACON_CANCEL	0x00000010
+#define BCM43xx_IRQ_ATIM_END		0x00000020
+#define BCM43xx_IRQ_PMQ			0x00000040
+#define BCM43xx_IRQ_PIO_WORKAROUND	0x00000100
+#define BCM43xx_IRQ_MAC_TXERR		0x00000200
+#define BCM43xx_IRQ_PHY_TXERR		0x00000800
+#define BCM43xx_IRQ_PMEVENT		0x00001000
+#define BCM43xx_IRQ_TIMER0		0x00002000
+#define BCM43xx_IRQ_TIMER1		0x00004000
+#define BCM43xx_IRQ_DMA			0x00008000
+#define BCM43xx_IRQ_TXFIFO_FLUSH_OK	0x00010000
+#define BCM43xx_IRQ_CCA_MEASURE_OK	0x00020000
+#define BCM43xx_IRQ_NOISESAMPLE_OK	0x00040000
+#define BCM43xx_IRQ_UCODE_DEBUG		0x08000000
+#define BCM43xx_IRQ_RFKILL		0x10000000
+#define BCM43xx_IRQ_TX_OK		0x20000000
+#define BCM43xx_IRQ_PHY_G_CHANGED	0x40000000
+#define BCM43xx_IRQ_TIMEOUT		0x80000000
+
+#define BCM43xx_IRQ_ALL			0xFFFFFFFF
+#define BCM43xx_IRQ_MASKTEMPLATE	(BCM43xx_IRQ_MAC_SUSPENDED |	\
+					 BCM43xx_IRQ_BEACON |		\
+					 BCM43xx_IRQ_TBTT_INDI |	\
+					 BCM43xx_IRQ_ATIM_END |		\
 					 BCM43xx_IRQ_PMQ |		\
-					 BCM43xx_IRQ_XMIT_ERROR |	\
-					 BCM43xx_IRQ_RX |		\
-					 BCM43xx_IRQ_SCAN |		\
-					 BCM43xx_IRQ_NOISE |		\
-					 BCM43xx_IRQ_XMIT_STATUS)
-					 
-
-/* Initial default iw_mode */
-#define BCM43xx_INITIAL_IWMODE			IW_MODE_INFRA
-
-/* Bus type PCI. */
-#define BCM43xx_BUSTYPE_PCI	0
-/* Bus type Silicone Backplane Bus. */
-#define BCM43xx_BUSTYPE_SB	1
-/* Bus type PCMCIA. */
-#define BCM43xx_BUSTYPE_PCMCIA	2
-
-/* Threshold values. */
-#define BCM43xx_MIN_RTS_THRESHOLD		1U
-#define BCM43xx_MAX_RTS_THRESHOLD		2304U
-#define BCM43xx_DEFAULT_RTS_THRESHOLD		BCM43xx_MAX_RTS_THRESHOLD
+					 BCM43xx_IRQ_MAC_TXERR |	\
+					 BCM43xx_IRQ_PHY_TXERR |	\
+					 BCM43xx_IRQ_DMA |		\
+					 BCM43xx_IRQ_TXFIFO_FLUSH_OK |	\
+					 BCM43xx_IRQ_NOISESAMPLE_OK |	\
+					 BCM43xx_IRQ_UCODE_DEBUG |	\
+					 BCM43xx_IRQ_RFKILL |		\
+					 BCM43xx_IRQ_TX_OK)
+
+/* Device specific rate values.
+ * The actual values defined here are (rate_in_mbps * 2).
+ * Some code depends on this. Don't change it. */
+#define BCM43xx_CCK_RATE_1MB		2
+#define BCM43xx_CCK_RATE_2MB		4
+#define BCM43xx_CCK_RATE_5MB		11
+#define BCM43xx_CCK_RATE_11MB		22
+#define BCM43xx_OFDM_RATE_6MB		12
+#define BCM43xx_OFDM_RATE_9MB		18
+#define BCM43xx_OFDM_RATE_12MB		24
+#define BCM43xx_OFDM_RATE_18MB		36
+#define BCM43xx_OFDM_RATE_24MB		48
+#define BCM43xx_OFDM_RATE_36MB		72
+#define BCM43xx_OFDM_RATE_48MB		96
+#define BCM43xx_OFDM_RATE_54MB		108
+/* Convert a bcm43xx rate value to a rate in 100kbps */
+#define BCM43xx_RATE_TO_100KBPS(rate)	(((rate) * 10) / 2)
+
 
 #define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT	7
 #define BCM43xx_DEFAULT_LONG_RETRY_LIMIT	4
 
-/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
-#define RX_RSSI_MAX				60
-
 /* Max size of a security key */
 #define BCM43xx_SEC_KEYSIZE			16
 /* Security algorithms. */
 enum {
 	BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */
-	BCM43xx_SEC_ALGO_WEP,
-	BCM43xx_SEC_ALGO_UNKNOWN,
+	BCM43xx_SEC_ALGO_WEP40,
+	BCM43xx_SEC_ALGO_TKIP,
 	BCM43xx_SEC_ALGO_AES,
 	BCM43xx_SEC_ALGO_WEP104,
-	BCM43xx_SEC_ALGO_TKIP,
+	BCM43xx_SEC_ALGO_AES_LEGACY,
 };
 
-#ifdef assert
-# undef assert
-#endif
-#ifdef CONFIG_BCM43XX_DEBUG
-#define assert(expr) \
-	do {									\
-		if (unlikely(!(expr))) {					\
-		printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n",	\
-			#expr, __FILE__, __LINE__, __FUNCTION__);		\
-		}								\
-	} while (0)
-#else
-#define assert(expr)	do { /* nothing */ } while (0)
-#endif
+/* Core Information Registers */
+#define BCM43xx_CIR_BASE                0xf00
+#define BCM43xx_CIR_SBTPSFLAG           (BCM43xx_CIR_BASE + 0x18)
+#define BCM43xx_CIR_SBIMSTATE           (BCM43xx_CIR_BASE + 0x90)
+#define BCM43xx_CIR_SBINTVEC            (BCM43xx_CIR_BASE + 0x94)
+#define BCM43xx_CIR_SBTMSTATELOW        (BCM43xx_CIR_BASE + 0x98)
+#define BCM43xx_CIR_SBTMSTATEHIGH       (BCM43xx_CIR_BASE + 0x9c)
+#define BCM43xx_CIR_SBIMCONFIGLOW       (BCM43xx_CIR_BASE + 0xa8)
+#define BCM43xx_CIR_SB_ID_HI            (BCM43xx_CIR_BASE + 0xfc)
 
-/* rate limited printk(). */
-#ifdef printkl
-# undef printkl
-#endif
-#define printkl(f, x...)  do { if (printk_ratelimit()) printk(f ,##x); } while (0)
-/* rate limited printk() for debugging */
-#ifdef dprintkl
-# undef dprintkl
-#endif
-#ifdef CONFIG_BCM43XX_DEBUG
-# define dprintkl		printkl
-#else
-# define dprintkl(f, x...)	do { /* nothing */ } while (0)
-#endif
+/* sbtmstatehigh state flags */
+#define BCM43xx_SBTMSTATEHIGH_SERROR		0x00000001
+#define BCM43xx_SBTMSTATEHIGH_BUSY		0x00000004
+#define BCM43xx_SBTMSTATEHIGH_TIMEOUT		0x00000020
+#define BCM43xx_SBTMSTATEHIGH_G_PHY_AVAIL	0x00010000
+#define BCM43xx_SBTMSTATEHIGH_COREFLAGS		0x1FFF0000
+#define BCM43xx_SBTMSTATEHIGH_DMA64BIT		0x10000000
+#define BCM43xx_SBTMSTATEHIGH_GATEDCLK		0x20000000
+#define BCM43xx_SBTMSTATEHIGH_BISTFAILED	0x40000000
+#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE	0x80000000
 
-/* Helper macro for if branches.
- * An if branch marked with this macro is only taken in DEBUG mode.
- * Example:
- *	if (DEBUG_ONLY(foo == bar)) {
- *		do something
- *	}
- *	In DEBUG mode, the branch will be taken if (foo == bar).
- *	In non-DEBUG mode, the branch will never be taken.
- */
-#ifdef DEBUG_ONLY
-# undef DEBUG_ONLY
-#endif
-#ifdef CONFIG_BCM43XX_DEBUG
-# define DEBUG_ONLY(x)	(x)
-#else
-# define DEBUG_ONLY(x)	0
-#endif
+/* sbimstate flags */
+#define BCM43xx_SBIMSTATE_IB_ERROR		0x20000
+#define BCM43xx_SBIMSTATE_TIMEOUT		0x40000
 
-/* debugging printk() */
-#ifdef dprintk
-# undef dprintk
+#define PFX		KBUILD_MODNAME ": "
+#ifdef assert
+# undef assert
 #endif
 #ifdef CONFIG_BCM43XX_DEBUG
-# define dprintk(f, x...)  do { printk(f ,##x); } while (0)
+# define BCM43xx_WARN_ON(expr)						\
+	do {								\
+		if (unlikely((expr))) {					\
+			printk(KERN_INFO PFX "Test (%s) failed at:"	\
+					      " %s:%d:%s()\n",		\
+					      #expr, __FILE__,		\
+					      __LINE__, __FUNCTION__);	\
+			WARN_ON(expr);					\
+		}							\
+	} while (0)
+# define BCM43xx_BUG_ON(expr)						\
+	do {								\
+		if (unlikely((expr))) {				\
+			printk(KERN_INFO PFX "Test (%s) failed\n",	\
+					      #expr);			\
+			BUG_ON(expr);					\
+		}							\
+	} while (0)
+# define BCM43xx_DEBUG	1
 #else
-# define dprintk(f, x...)  do { /* nothing */ } while (0)
+# define BCM43xx_WARN_ON(x)	do { /* nothing */ } while (0)
+# define BCM43xx_BUG_ON(x)	do { /* nothing */ } while (0)
+# define BCM43xx_DEBUG	0
 #endif
 
 
@@ -486,52 +352,9 @@ struct bcm43xx_initval {
 	u32 value;
 } __attribute__((__packed__));
 
-/* Values for bcm430x_sprominfo.locale */
-enum {
-	BCM43xx_LOCALE_WORLD = 0,
-	BCM43xx_LOCALE_THAILAND,
-	BCM43xx_LOCALE_ISRAEL,
-	BCM43xx_LOCALE_JORDAN,
-	BCM43xx_LOCALE_CHINA,
-	BCM43xx_LOCALE_JAPAN,
-	BCM43xx_LOCALE_USA_CANADA_ANZ,
-	BCM43xx_LOCALE_EUROPE,
-	BCM43xx_LOCALE_USA_LOW,
-	BCM43xx_LOCALE_JAPAN_HIGH,
-	BCM43xx_LOCALE_ALL,
-	BCM43xx_LOCALE_NONE,
-};
-
-#define BCM43xx_SPROM_SIZE	64 /* in 16-bit words. */
-struct bcm43xx_sprominfo {
-	u16 boardflags2;
-	u8 il0macaddr[6];
-	u8 et0macaddr[6];
-	u8 et1macaddr[6];
-	u8 et0phyaddr:5;
-	u8 et1phyaddr:5;
-	u8 boardrev;
-	u8 locale:4;
-	u8 antennas_aphy:2;
-	u8 antennas_bgphy:2;
-	u16 pa0b0;
-	u16 pa0b1;
-	u16 pa0b2;
-	u8 wl0gpio0;
-	u8 wl0gpio1;
-	u8 wl0gpio2;
-	u8 wl0gpio3;
-	u8 maxpower_aphy;
-	u8 maxpower_bgphy;
-	u16 pa1b0;
-	u16 pa1b1;
-	u16 pa1b2;
-	u8 idle_tssi_tgt_aphy;
-	u8 idle_tssi_tgt_bgphy;
-	u16 boardflags;
-	u16 antennagain_aphy;
-	u16 antennagain_bgphy;
-};
+#define BCM43xx_PHYMODE(phytype)	(1 << (phytype))
+#define BCM43xx_PHYMODE_B		BCM43xx_PHYMODE(BCM43xx_PHYTYPE_B)
+#define BCM43xx_PHYMODE_G		BCM43xx_PHYMODE(BCM43xx_PHYTYPE_G)
 
 /* Value pair to measure the LocalOscillator. */
 struct bcm43xx_lopair {
@@ -541,67 +364,96 @@ struct bcm43xx_lopair {
 };
 #define BCM43xx_LO_COUNT	(14*4)
 
-struct bcm43xx_phyinfo {
-	/* Hardware Data */
+struct bcm43xx_phy {
+	/* Possible PHYMODEs on this PHY */
+	u8 possible_phymodes;
+	/* GMODE bit enabled? */
+	bool gmode;
+	/* Possible ieee80211 subsystem hwmodes for this PHY.
+	 * Which mode is selected, depends on thr GMODE enabled bit */
+#define BCM43xx_MAX_PHYHWMODES	2
+	struct ieee80211_hw_mode hwmodes[BCM43xx_MAX_PHYHWMODES];
+
+	/* Analog Type */
 	u8 analog;
+	/* BCM43xx_PHYTYPE_ */
 	u8 type;
+	/* PHY revision number. */
 	u8 rev;
+
 	u16 antenna_diversity;
 	u16 savedpctlreg;
+	/* Radio versioning */
+	u16 radio_manuf;	/* Radio manufacturer */
+	u16 radio_ver;		/* Radio version */
+	u8 calibrated:1;
+	u8 radio_rev;		/* Radio revision */
+
+	bool radio_on;		/* Radio switched on/off */
+	bool locked;		/* Only used in bcm43xx_phy_{un}lock() */
+	bool dyn_tssi_tbl;	/* tssi2dbm is kmalloc()ed. */
+
+	/* ACI (adjacent channel interference) flags. */
+	bool aci_enable;
+	bool aci_wlan_automatic;
+	bool aci_hw_rssi;
+
 	u16 minlowsig[2];
 	u16 minlowsigpos[2];
-	u8 connected:1,
-	   calibrated:1,
-	   is_locked:1, /* used in bcm43xx_phy_{un}lock() */
-	   dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */
+
 	/* LO Measurement Data.
 	 * Use bcm43xx_get_lopair() to get a value.
 	 */
 	struct bcm43xx_lopair *_lo_pairs;
-
 	/* TSSI to dBm table in use */
 	const s8 *tssi2dbm;
 	/* idle TSSI value */
 	s8 idle_tssi;
+	/* Target idle TSSI */
+	int tgt_idle_tssi;
+	/* Current idle TSSI */
+	int cur_idle_tssi;
 
+	/* LocalOscillator control values. */
+	struct bcm43xx_txpower_lo_control *lo_control;
 	/* Values from bcm43xx_calc_loopback_gain() */
-	u16 loopback_gain[2];
+	s16 max_lb_gain;	/* Maximum Loopback gain in hdB */
+	s16 trsw_rx_gain;	/* TRSW RX gain in hdB */
+	s16 lna_lod_gain;	/* LNA lod */
+	s16 lna_gain;		/* LNA */
+	s16 pga_gain;		/* PGA */
 
 	/* PHY lock for core.rev < 3
 	 * This lock is only used by bcm43xx_phy_{un}lock()
 	 */
 	spinlock_t lock;
 
-	/* Firmware. */
-	const struct firmware *ucode;
-	const struct firmware *pcm;
-	const struct firmware *initvals0;
-	const struct firmware *initvals1;
-};
-
+	/* Desired TX power level (in dBm).
+	 * This is set by the user and adjusted in bcm43xx_phy_xmitpower(). */
+	u8 power_level;
 
-struct bcm43xx_radioinfo {
-	u16 manufact;
-	u16 version;
-	u8 revision;
+	/* Values from bcm43xx_calc_loopback_gain() */
+	u16 loopback_gain[2];
 
-	/* Desired TX power in dBm Q5.2 */
-	u16 txpower_desired;
 	/* TX Power control values. */
-	union {
-		/* B/G PHY */
-		struct {
-			u16 baseband_atten;
-			u16 radio_atten;
-			u16 txctl1;
-			u16 txctl2;
-		};
-		/* A PHY */
-		struct {
-			u16 txpwr_offset;
-		};
+	/* B/G PHY */
+	struct {
+		/* Current Radio Attenuation for TXpower recalculation. */
+		u16 rfatt;
+		/* Current Baseband Attenuation for TXpower recalculation. */
+		u16 bbatt;
+		/* Current TXpower control value for TXpower recalculation. */
+		u16 txctl1;
+		u16 txctl2;
+	};
+	/* A PHY */
+	struct {
+		u16 txpwr_offset;
 	};
 
+#ifdef CONFIG_BCM43XX_DEBUG
+	bool manual_txpower_control; /* Manual TX-power control enabled? */
+#endif
 	/* Current Interference Mitigation mode */
 	int interfmode;
 	/* Stack of saved values from the Interference Mitigation code.
@@ -612,7 +464,7 @@ struct bcm43xx_radioinfo {
 	 * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
 	 */
 #define BCM43xx_INTERFSTACK_SIZE	26
-	u32 interfstack[BCM43xx_INTERFSTACK_SIZE];
+	u32 interfstack[BCM43xx_INTERFSTACK_SIZE];/* FIXME: use a data struct */
 
 	/* Saved values from the NRSSI Slope calculation */
 	s16 nrssi[2];
@@ -622,17 +474,10 @@ struct bcm43xx_radioinfo {
 
 	/* current channel */
 	u8 channel;
-	u8 initial_channel;
 
 	u16 lofcal;
 
 	u16 initval;
-
-	u8 enabled:1;
-	/* ACI (adjacent channel interference) flags. */
-	u8 aci_enable:1,
-	   aci_wlan_automatic:1,
-	   aci_hw_rssi:1;
 };
 
 /* Data structures for DMA transmission, per 80211 core. */
@@ -656,147 +501,145 @@ struct bcm43xx_pio {
 	struct bcm43xx_pioqueue *queue3;
 };
 
-#define BCM43xx_MAX_80211_CORES		2
-
-/* Generic information about a core. */
-struct bcm43xx_coreinfo {
-	u8 available:1,
-	   enabled:1,
-	   initialized:1;
-	/** core_rev revision number */
-	u8 rev;
-	/** Index number for _switch_core() */
-	u8 index;
-	/** core_id ID number */
-	u16 id;
-	/** Core-specific data. */
-	void *priv;
-};
-
-/* Additional information for each 80211 core. */
-struct bcm43xx_coreinfo_80211 {
-	/* PHY device. */
-	struct bcm43xx_phyinfo phy;
-	/* Radio device. */
-	struct bcm43xx_radioinfo radio;
-	union {
-		/* DMA context. */
-		struct bcm43xx_dma dma;
-		/* PIO context. */
-		struct bcm43xx_pio pio;
-	};
-};
-
 /* Context information for a noise calculation (Link Quality). */
 struct bcm43xx_noise_calculation {
-	struct bcm43xx_coreinfo *core_at_start;
 	u8 channel_at_start;
-	u8 calculation_running:1;
+	bool calculation_running;
 	u8 nr_samples;
 	s8 samples[8][4];
 };
 
 struct bcm43xx_stats {
-	u8 noise;
-	struct iw_statistics wstats;
+	u8 link_noise;
 	/* Store the last TX/RX times here for updating the leds. */
 	unsigned long last_tx;
 	unsigned long last_rx;
 };
 
 struct bcm43xx_key {
-	u8 enabled:1;
+	bool enabled;
 	u8 algorithm;
+	u8 address[6];
 };
 
-/* Driver initialization status. */
+struct bcm43xx_wldev;
+
+/* Data structure for the WLAN parts (802.11 cores) of the bcm43xx chip. */
+struct bcm43xx_wl {
+	/* Pointer to the active wireless device on this chip */
+	struct bcm43xx_wldev *current_dev;
+	/* Pointer to the ieee80211 hardware data structure */
+	struct ieee80211_hw *hw;
+
+	spinlock_t irq_lock;		/* locks IRQ */
+	struct mutex mutex;		/* locks ? */
+	spinlock_t leds_lock;		/* lock for leds */
+
+	/* We can only have one operating interface (802.11 core)
+	 * at a time. General information about this interface follows.
+	 */
+
+	/* Opaque ID of the operating interface (!= monitor
+	 * interface) from the ieee80211 subsystem.
+	 * Do not modify.
+	 */
+	int if_id;
+	/* MAC address (can be NULL). */
+	const u8 *mac_addr;
+	/* Current BSSID (can be NULL). */
+	const u8 *bssid;
+	/* Interface type. (IEEE80211_IF_TYPE_XXX) */
+	int if_type;
+	/* Counter of active monitor interfaces. */
+	int monitor;
+	/* Is the card operating in AP, STA or IBSS mode? */
+	bool operating;
+	/* Promisc mode active?
+	 * Note that (monitor != 0) implies promisc.
+	 */
+	bool promisc;
+	/* Stats about the wireless interface */
+	struct ieee80211_low_level_stats ieee_stats;
+
+	struct hwrng rng;
+	u8 rng_initialized;
+	char rng_name[30 + 1];
+
+	/* List of all wireless devices on this chip */
+	struct list_head devlist;
+	u8 nr_devs;
+};
+
+/* Pointers to the firmware data and meta information about it. */
+struct bcm43xx_firmware {
+	/* Microcode */
+	const struct firmware *ucode;
+	/* PCM code */
+	const struct firmware *pcm;
+	/* Initial MMIO values 0 */
+	const struct firmware *initvals0;
+	/* Initial MMIO values 1 */
+	const struct firmware *initvals1;
+	/* Firmware revision */
+	u16 rev;
+	/* Firmware patchlevel */
+	u16 patch;
+};
+
+/* Device (802.11 core) initialization status. */
 enum {
-	BCM43xx_STAT_UNINIT,		/* Uninitialized. */
-	BCM43xx_STAT_INITIALIZING,	/* init_board() in progress. */
-	BCM43xx_STAT_INITIALIZED,	/* Fully operational. */
-	BCM43xx_STAT_SHUTTINGDOWN,	/* free_board() in progress. */
-	BCM43xx_STAT_RESTARTING,	/* controller_restart() called. */
-};
-#define bcm43xx_status(bcm)		atomic_read(&(bcm)->init_status)
-#define bcm43xx_set_status(bcm, stat)	do {			\
-		atomic_set(&(bcm)->init_status, (stat));	\
+	BCM43xx_STAT_UNINIT		= 0, /* Uninitialized. */
+	BCM43xx_STAT_INITIALIZED	= 1, /* Initialized, not yet started */
+	BCM43xx_STAT_STARTED		= 2, /* Up and running. */
+};
+#define bcm43xx_status(wldev)		atomic_read(&(wldev)->__init_status)
+#define bcm43xx_set_status(wldev, stat)	do {			\
+		atomic_set(&(wldev)->__init_status, (stat));	\
 		smp_wmb();					\
 					} while (0)
 
-/*    *** THEORY OF LOCKING ***
+/* XXX---   HOW LOCKING WORKS IN BCM43xx   ---XXX
  *
- * We have two different locks in the bcm43xx driver.
- * => bcm->mutex:    General sleeping mutex. Protects struct bcm43xx_private
- *                   and the device registers. This mutex does _not_ protect
- *                   against concurrency from the IRQ handler.
- * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
- *
- * Please note that, if you only take the irq_lock, you are not protected
- * against concurrency from the periodic work handlers.
- * Most times you want to take _both_ locks.
+ * You should always acquire both, wl->mutex and wl->irq_lock unless:
+ * - You don't need to acquire wl->irq_lock, if the interface is stopped.
+ * - You don't need to acquire wl->mutex in the IRQ handler, IRQ tasklet
+ *   and packet TX path (and _ONLY_ there.)
  */
 
-struct bcm43xx_private {
-	struct ieee80211_device *ieee;
-	struct ieee80211softmac_device *softmac;
-
-	struct net_device *net_dev;
-	struct pci_dev *pci_dev;
-	unsigned int irq;
-
-	void __iomem *mmio_addr;
-
-	spinlock_t irq_lock;
-	struct mutex mutex;
-
-	/* Driver initialization status BCM43xx_STAT_*** */
-	atomic_t init_status;
-
-	u16 was_initialized:1,		/* for PCI suspend/resume. */
-	    __using_pio:1,		/* Internal, use bcm43xx_using_pio(). */
-	    bad_frames_preempt:1,	/* Use "Bad Frames Preemption" (default off) */
-	    reg124_set_0x4:1,		/* Some variable to keep track of IRQ stuff. */
-	    short_preamble:1,		/* TRUE, if short preamble is enabled. */
-	    firmware_norelease:1,	/* Do not release the firmware. Used on suspend. */
-	    radio_hw_enable:1;		/* TRUE if radio is hardware enabled */
-
-	struct bcm43xx_stats stats;
+/* Data structure for one wireless device (802.11 core) */
+struct bcm43xx_wldev {
+	struct ssb_device *dev;
+	struct bcm43xx_wl *wl;
+
+	/* The device initialization status.
+	 * Use bcm43xx_status() to query. */
+	atomic_t __init_status;
+	/* Saved init status for handling suspend. */
+	int suspend_init_status;
+
+	bool __using_pio;		/* iUse bcm43xx_using_pio(). */
+	bool bad_frames_preempt;	/* Use "Bad Frames Preemption" */
+	bool reg124_set_0x4;		/* Variable to keep track of IRQ */
+	bool short_preamble;		/* TRUE if short preamble enabled. */
+	bool short_slot;		/* TRUE if short slot timing enabled. */
+	bool radio_hw_enable;		/* state of radio hardware enable bit */
+	u8 short_retry_limit;
+	u8 long_retry_limit;
 
-	/* Bus type we are connected to.
-	 * This is currently always BCM43xx_BUSTYPE_PCI
-	 */
-	u8 bustype;
-	u64 dma_mask;
+	/* PHY/Radio device. */
+	struct bcm43xx_phy phy;
+	union {
+		/* DMA engines. */
+		struct bcm43xx_dma dma;
+		/* PIO engines. */
+		struct bcm43xx_pio pio;
+	};
 
-	u16 board_vendor;
-	u16 board_type;
-	u16 board_revision;
-
-	u16 chip_id;
-	u8 chip_rev;
-	u8 chip_package;
+	/* Various statistics about the physical device. */
+	struct bcm43xx_stats stats;
 
-	struct bcm43xx_sprominfo sprom;
 #define BCM43xx_NR_LEDS		4
 	struct bcm43xx_led leds[BCM43xx_NR_LEDS];
-	spinlock_t leds_lock;
-
-	/* The currently active core. */
-	struct bcm43xx_coreinfo *current_core;
-	struct bcm43xx_coreinfo *active_80211_core;
-	/* coreinfo structs for all possible cores follow.
-	 * Note that a core might not exist.
-	 * So check the coreinfo flags before using it.
-	 */
-	struct bcm43xx_coreinfo core_chipcommon;
-	struct bcm43xx_coreinfo core_pci;
-	struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
-	/* Additional information, specific to the 80211 cores. */
-	struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
-	/* Number of available 80211 cores. */
-	int nr_80211_available;
-
-	u32 chipcommon_capabilities;
 
 	/* Reason code of the last interrupt. */
 	u32 irq_reason;
@@ -808,10 +651,6 @@ struct bcm43xx_private {
 	/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
 	int mac_suspended;
 
-	/* Threshold values. */
-	//TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
-	u32 rts_threshold;
-
 	/* Interrupt Service Routine tasklet (bottom-half) */
 	struct tasklet_struct isr_tasklet;
 
@@ -821,17 +660,19 @@ struct bcm43xx_private {
 
 	struct work_struct restart_work;
 
-	/* Informational stuff. */
-	char nick[IW_ESSID_MAX_SIZE + 1];
-
 	/* encryption/decryption */
-	u16 security_offset;
-	struct bcm43xx_key key[54];
-	u8 default_key_idx;
+	u16 ktp; /* Key table pointer */
+	u8 max_nr_keys;
+	struct bcm43xx_key key[58];
 
-	/* Random Number Generator. */
-	struct hwrng rng;
-	char rng_name[20 + 1];
+	/* Cached beacon template while uploading the template. */
+	struct sk_buff *cached_beacon;
+
+	/* Firmware data */
+	struct bcm43xx_firmware fw;
+
+	/* Devicelist in struct bcm43xx_wl (all 802.11 cores) */
+	struct list_head list;
 
 	/* Debugging stuff follows. */
 #ifdef CONFIG_BCM43XX_DEBUG
@@ -841,44 +682,29 @@ struct bcm43xx_private {
 
 
 static inline
-struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
-{
-	return ieee80211softmac_priv(dev);
-}
-
-struct device;
-
-static inline
-struct bcm43xx_private * dev_to_bcm(struct device *dev)
+struct bcm43xx_wl *hw_to_bcm43xx_wl(struct ieee80211_hw *hw)
 {
-	struct net_device *net_dev;
-	struct bcm43xx_private *bcm;
-
-	net_dev = dev_get_drvdata(dev);
-	bcm = bcm43xx_priv(net_dev);
-
-	return bcm;
+	return hw->priv;
 }
 
-
 /* Helper function, which returns a boolean.
  * TRUE, if PIO is used; FALSE, if DMA is used.
  */
 #if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
 static inline
-int bcm43xx_using_pio(struct bcm43xx_private *bcm)
+int bcm43xx_using_pio(struct bcm43xx_wldev *dev)
 {
-	return bcm->__using_pio;
+	return dev->__using_pio;
 }
 #elif defined(CONFIG_BCM43XX_DMA)
 static inline
-int bcm43xx_using_pio(struct bcm43xx_private *bcm)
+int bcm43xx_using_pio(struct bcm43xx_wldev *dev)
 {
 	return 0;
 }
 #elif defined(CONFIG_BCM43XX_PIO)
 static inline
-int bcm43xx_using_pio(struct bcm43xx_private *bcm)
+int bcm43xx_using_pio(struct bcm43xx_wldev *dev)
 {
 	return 1;
 }
@@ -886,97 +712,79 @@ int bcm43xx_using_pio(struct bcm43xx_pri
 # error "Using neither DMA nor PIO? Confused..."
 #endif
 
-/* Helper functions to access data structures private to the 80211 cores.
- * Note that we _must_ have an 80211 core mapped when calling
- * any of these functions.
- */
-static inline
-struct bcm43xx_coreinfo_80211 *
-bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
-{
-	assert(bcm->current_core->id == BCM43xx_COREID_80211);
-	return bcm->current_core->priv;
-}
-static inline
-struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
-{
-	assert(bcm43xx_using_pio(bcm));
-	return &(bcm43xx_current_80211_priv(bcm)->pio);
-}
-static inline
-struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
-{
-	assert(!bcm43xx_using_pio(bcm));
-	return &(bcm43xx_current_80211_priv(bcm)->dma);
-}
-static inline
-struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
-{
-	return &(bcm43xx_current_80211_priv(bcm)->phy);
-}
-static inline
-struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
-{
-	return &(bcm43xx_current_80211_priv(bcm)->radio);
-}
-
 
 static inline
-struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,
-					   u16 radio_attenuation,
-					   u16 baseband_attenuation)
+struct bcm43xx_wldev *dev_to_bcm43xx_wldev(struct device *dev)
 {
-	return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2));
+	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
+	return ssb_get_drvdata(ssb_dev);
 }
 
-
+/* Is the device operating in a specified mode (IEEE80211_IF_TYPE_XXX). */
 static inline
-u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset)
+int bcm43xx_is_mode(struct bcm43xx_wl *wl, int type)
 {
-	return ioread16(bcm->mmio_addr + offset);
+	if (type == IEEE80211_IF_TYPE_MNTR)
+		return !!(wl->monitor);
+	return (wl->operating &&
+		wl->if_type == type);
 }
 
 static inline
-void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value)
+bool is_bcm_board_vendor(struct bcm43xx_wldev *dev)
 {
-	iowrite16(value, bcm->mmio_addr + offset);
+	return  (dev->dev->bus->boardinfo.vendor == PCI_VENDOR_ID_BROADCOM);
 }
 
 static inline
-u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset)
+u16 bcm43xx_read16(struct bcm43xx_wldev *dev, u16 offset)
 {
-	return ioread32(bcm->mmio_addr + offset);
+	return ssb_read16(dev->dev, offset);
 }
 
 static inline
-void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value)
+void bcm43xx_write16(struct bcm43xx_wldev *dev, u16 offset, u16 value)
 {
-	iowrite32(value, bcm->mmio_addr + offset);
+	ssb_write16(dev->dev, offset, value);
 }
 
 static inline
-int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value)
+u32 bcm43xx_read32(struct bcm43xx_wldev *dev, u16 offset)
 {
-	return pci_read_config_word(bcm->pci_dev, offset, value);
+	return ssb_read32(dev->dev, offset);
 }
 
 static inline
-int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value)
+void bcm43xx_write32(struct bcm43xx_wldev *dev, u16 offset, u32 value)
 {
-	return pci_read_config_dword(bcm->pci_dev, offset, value);
+	ssb_write32(dev->dev, offset, value);
 }
 
 static inline
-int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value)
+struct bcm43xx_lopair *bcm43xx_get_lopair(struct bcm43xx_phy *phy,
+					   u16 radio_attenuation,
+					   u16 baseband_attenuation)
 {
-	return pci_write_config_word(bcm->pci_dev, offset, value);
+	return phy->_lo_pairs + (radio_attenuation
+			+ 14 * (baseband_attenuation / 2));
 }
 
-static inline
-int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value)
-{
-	return pci_write_config_dword(bcm->pci_dev, offset, value);
-}
+
+
+/* Message printing */
+void bcminfo(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+void bcmerr(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+void bcmwarn(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+#if BCM43xx_DEBUG
+void bcmdbg(struct bcm43xx_wl *wl, const char *fmt, ...)
+		__attribute__((format(printf, 2, 3)));
+#else /* DEBUG */
+# define bcmdbg(wl, fmt...) do { /* nothing */ } while (0)
+#endif /* DEBUG */
+
 
 /** Limit a value between two limits */
 #ifdef limit_value
@@ -985,19 +793,17 @@ int bcm43xx_pci_write_config32(struct bc
 #define limit_value(value, min, max)  \
 	({						\
 		typeof(value) __value = (value);	\
-	 	typeof(value) __min = (min);		\
-	 	typeof(value) __max = (max);		\
-	 	if (__value < __min)			\
-	 		__value = __min;		\
-	 	else if (__value > __max)		\
-	 		__value = __max;		\
-	 	__value;				\
+		typeof(value) __min = (min);		\
+		typeof(value) __max = (max);		\
+		if (__value < __min)			\
+			__value = __min;		\
+		else if (__value > __max)		\
+			__value = __max;		\
+		__value;				\
 	})
 
-/** Helpers to print MAC addresses. */
-#define BCM43xx_MACFMT		"%02x:%02x:%02x:%02x:%02x:%02x"
-#define BCM43xx_MACARG(x)	((u8*)(x))[0], ((u8*)(x))[1], \
-				((u8*)(x))[2], ((u8*)(x))[3], \
-				((u8*)(x))[4], ((u8*)(x))[5]
+/* Macros for printing a value in Q5.2 format */
+#define Q52_FMT		"%u.%u"
+#define Q52_ARG(q52)	((q52) / 4), ((((q52) & 3) * 100) / 4)
 
 #endif /* BCM43xx_H_ */


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC 1/10] Port of bcm43xx from softmac to mac80211
  2007-08-02 15:53 [RFC 1/10] Port of bcm43xx from softmac to mac80211 Larry Finger
@ 2007-08-03 14:30 ` Stefano Brivio
  2007-08-03 16:13   ` Larry Finger
  0 siblings, 1 reply; 3+ messages in thread
From: Stefano Brivio @ 2007-08-03 14:30 UTC (permalink / raw)
  To: Larry Finger; +Cc: Michael Buesch, Bcm43xx-dev, linux-wireless

[Just a quick review, mostly about coding style. If it works, I ACK this.]

On Thu, 02 Aug 2007 10:53:11 -0500
Larry Finger <Larry.Finger@lwfinger.net> wrote:

> +#define BCM43xx_RX_MAX_SSI		60

A comment here wouldn't hurt.

>  /* MMIO offsets */
>  #define BCM43xx_MMIO_DMA0_REASON	0x20
> @@ -45,6 +39,7 @@
>  #define BCM43xx_MMIO_DMA4_IRQ_MASK	0x44
>  #define BCM43xx_MMIO_DMA5_REASON	0x48
>  #define BCM43xx_MMIO_DMA5_IRQ_MASK	0x4C
> +#define BCM43xx_MMIO_MACCTL		0x120
>  #define BCM43xx_MMIO_STATUS_BITFIELD	0x120
>  #define BCM43xx_MMIO_STATUS2_BITFIELD	0x124
>  #define BCM43xx_MMIO_GEN_IRQ_REASON	0x128
> @@ -83,6 +78,7 @@
>  
>  #define BCM43xx_MMIO_PHY_VER		0x3E0
>  #define BCM43xx_MMIO_PHY_RADIO		0x3E2
> +#define BCM43xx_MMIO_PHY0		0x3E6
>  #define BCM43xx_MMIO_ANTENNA		0x3E8
>  #define BCM43xx_MMIO_CHANNEL		0x3F0
>  #define BCM43xx_MMIO_CHANNEL_EXT	0x3F4
> @@ -93,6 +89,7 @@
>  #define BCM43xx_MMIO_PHY_DATA		0x3FE
>  #define BCM43xx_MMIO_MACFILTER_CONTROL	0x420
>  #define BCM43xx_MMIO_MACFILTER_DATA	0x422
> +#define BCM43xx_MMIO_RCMTA_COUNT	0x43C

Ditto, the meaning of RCMTA isn't obvious.

>  /* PHYVersioning */
> -#define BCM43xx_PHYTYPE_A		0x00

So OK, let's remove support for A PHYs. I never got done with it and maybe it
had to be rewritten from scratch anyway.

> +#define BCM43xx_IRQ_TBTT_INDI		0x00000004

A comment here would be nice.

>  #define BCM43xx_INTERFSTACK_SIZE	26
> -	u32 interfstack[BCM43xx_INTERFSTACK_SIZE];
> +	u32 interfstack[BCM43xx_INTERFSTACK_SIZE];/* FIXME: use a data
> struct */

Why?

> +/* Data structure for the WLAN parts (802.11 cores) of the bcm43xx chip.
> */ +struct bcm43xx_wl {
> +	/* Pointer to the active wireless device on this chip */
> +	struct bcm43xx_wldev *current_dev;
> +	/* Pointer to the ieee80211 hardware data structure */
> +	struct ieee80211_hw *hw;
> +
> +	spinlock_t irq_lock;		/* locks IRQ */
> +	struct mutex mutex;		/* locks ? */

What?

> -		atomic_set(&(bcm)->init_status, (stat));	\
> +	BCM43xx_STAT_UNINIT		= 0, /* Uninitialized. */
> +	BCM43xx_STAT_INITIALIZED	= 1, /* Initialized, not yet
> started */

"Initialized, not yet started."

> -/*    *** THEORY OF LOCKING ***
> +/* XXX---   HOW LOCKING WORKS IN BCM43xx   ---XXX

I'd prefer "***" but this isn't relevant. :)

> +struct bcm43xx_wldev {
> +	struct ssb_device *dev;
> +	struct bcm43xx_wl *wl;
> +
> +	/* The device initialization status.
> +	 * Use bcm43xx_status() to query. */
> +	atomic_t __init_status;
> +	/* Saved init status for handling suspend. */
> +	int suspend_init_status;
> +
> +	bool __using_pio;		/* iUse bcm43xx_using_pio(). */

An evolution of the iRack? :P

> +	bool bad_frames_preempt;	/* Use "Bad Frames Preemption" */

Dot at the end.

> +	bool reg124_set_0x4;		/* Variable to keep track of
> IRQ */

Ditto.

> +	bool short_preamble;		/* TRUE if short preamble
> enabled. */

"True".

> +	bool short_slot;		/* TRUE if short slot timing
> enabled. */

Ditto.

> +	bool radio_hw_enable;		/* state of radio hardware
> enable bit */

"State of the radio hardware enable bit."

> +/* Macros for printing a value in Q5.2 format */
> +#define Q52_FMT		"%u.%u"
> +#define Q52_ARG(q52)	((q52) / 4), ((((q52) & 3) * 100) / 4)

#define Q52_ARG(q52) ((q52) / 4), (((q52) & 3) * 100 / 4)


--
Ciao
Stefano


-- 
Ciao
Stefano

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC 1/10] Port of bcm43xx from softmac to mac80211
  2007-08-03 14:30 ` Stefano Brivio
@ 2007-08-03 16:13   ` Larry Finger
  0 siblings, 0 replies; 3+ messages in thread
From: Larry Finger @ 2007-08-03 16:13 UTC (permalink / raw)
  To: Stefano Brivio; +Cc: Michael Buesch, Bcm43xx-dev, linux-wireless

Stefano,

Thanks for taking the time to review the patches. As Michael wrote, the bulk of the patch comes from 
his V4 code, but it's good to have it looked through.



Stefano Brivio wrote:

>>  /* PHYVersioning */
>> -#define BCM43xx_PHYTYPE_A		0x00
> 
> So OK, let's remove support for A PHYs. I never got done with it and maybe it
> had to be rewritten from scratch anyway.

This removal is _ONLY_ for the driver that uses V3 firmware. It will ultimately be limited to B PHYs 
and removal of the A PHY stuff will happen anyway. AFAIK, support of A PHYs will be implemented 
(eventually) in the V4 driver.

All suggestions implemented.

Larry


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-08-03 16:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-02 15:53 [RFC 1/10] Port of bcm43xx from softmac to mac80211 Larry Finger
2007-08-03 14:30 ` Stefano Brivio
2007-08-03 16:13   ` Larry Finger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).