2007-08-02 15:53:33

by Larry Finger

[permalink] [raw]
Subject: [RFC 1/10] Port of bcm43xx from softmac to mac80211

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

Signed-off-by: Larry Finger <[email protected]>
---

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_ */



2007-08-03 14:55:40

by Stefano Brivio

[permalink] [raw]
Subject: Re: [RFC 1/10] Port of bcm43xx from softmac to mac80211

[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 <[email protected]> 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

2007-08-03 16:13:10

by Larry Finger

[permalink] [raw]
Subject: Re: [RFC 1/10] Port of bcm43xx from softmac to mac80211

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