John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 1 | #ifndef BCM43xx_H_ |
| 2 | #define BCM43xx_H_ |
| 3 | |
Michael Buesch | 71c0cd7 | 2006-06-26 00:25:04 -0700 | [diff] [blame] | 4 | #include <linux/hw_random.h> |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 5 | #include <linux/version.h> |
| 6 | #include <linux/kernel.h> |
| 7 | #include <linux/spinlock.h> |
| 8 | #include <linux/interrupt.h> |
| 9 | #include <linux/stringify.h> |
| 10 | #include <linux/pci.h> |
| 11 | #include <net/ieee80211.h> |
| 12 | #include <net/ieee80211softmac.h> |
| 13 | #include <asm/atomic.h> |
| 14 | #include <asm/io.h> |
| 15 | |
| 16 | |
| 17 | #include "bcm43xx_debugfs.h" |
| 18 | #include "bcm43xx_leds.h" |
| 19 | |
| 20 | |
Michael Buesch | 65f3f19 | 2006-01-31 20:11:38 +0100 | [diff] [blame] | 21 | #define PFX KBUILD_MODNAME ": " |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 22 | |
Michael Buesch | 489423c | 2006-02-13 00:11:07 +0100 | [diff] [blame] | 23 | #define BCM43xx_SWITCH_CORE_MAX_RETRIES 50 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 24 | #define BCM43xx_IRQWAIT_MAX_RETRIES 50 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 25 | |
| 26 | #define BCM43xx_IO_SIZE 8192 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 27 | |
Michael Buesch | 489423c | 2006-02-13 00:11:07 +0100 | [diff] [blame] | 28 | /* Active Core PCI Configuration Register. */ |
| 29 | #define BCM43xx_PCICFG_ACTIVE_CORE 0x80 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 30 | /* SPROM control register. */ |
| 31 | #define BCM43xx_PCICFG_SPROMCTL 0x88 |
Michael Buesch | 489423c | 2006-02-13 00:11:07 +0100 | [diff] [blame] | 32 | /* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */ |
| 33 | #define BCM43xx_PCICFG_ICR 0x94 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 34 | |
| 35 | /* MMIO offsets */ |
Michael Buesch | 9218e02 | 2006-08-16 00:25:16 +0200 | [diff] [blame] | 36 | #define BCM43xx_MMIO_DMA0_REASON 0x20 |
| 37 | #define BCM43xx_MMIO_DMA0_IRQ_MASK 0x24 |
| 38 | #define BCM43xx_MMIO_DMA1_REASON 0x28 |
| 39 | #define BCM43xx_MMIO_DMA1_IRQ_MASK 0x2C |
| 40 | #define BCM43xx_MMIO_DMA2_REASON 0x30 |
| 41 | #define BCM43xx_MMIO_DMA2_IRQ_MASK 0x34 |
| 42 | #define BCM43xx_MMIO_DMA3_REASON 0x38 |
| 43 | #define BCM43xx_MMIO_DMA3_IRQ_MASK 0x3C |
| 44 | #define BCM43xx_MMIO_DMA4_REASON 0x40 |
| 45 | #define BCM43xx_MMIO_DMA4_IRQ_MASK 0x44 |
| 46 | #define BCM43xx_MMIO_DMA5_REASON 0x48 |
| 47 | #define BCM43xx_MMIO_DMA5_IRQ_MASK 0x4C |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 48 | #define BCM43xx_MMIO_STATUS_BITFIELD 0x120 |
| 49 | #define BCM43xx_MMIO_STATUS2_BITFIELD 0x124 |
| 50 | #define BCM43xx_MMIO_GEN_IRQ_REASON 0x128 |
| 51 | #define BCM43xx_MMIO_GEN_IRQ_MASK 0x12C |
| 52 | #define BCM43xx_MMIO_RAM_CONTROL 0x130 |
| 53 | #define BCM43xx_MMIO_RAM_DATA 0x134 |
| 54 | #define BCM43xx_MMIO_PS_STATUS 0x140 |
| 55 | #define BCM43xx_MMIO_RADIO_HWENABLED_HI 0x158 |
| 56 | #define BCM43xx_MMIO_SHM_CONTROL 0x160 |
| 57 | #define BCM43xx_MMIO_SHM_DATA 0x164 |
| 58 | #define BCM43xx_MMIO_SHM_DATA_UNALIGNED 0x166 |
| 59 | #define BCM43xx_MMIO_XMITSTAT_0 0x170 |
| 60 | #define BCM43xx_MMIO_XMITSTAT_1 0x174 |
| 61 | #define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */ |
| 62 | #define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */ |
Michael Buesch | 9218e02 | 2006-08-16 00:25:16 +0200 | [diff] [blame] | 63 | |
| 64 | /* 32-bit DMA */ |
| 65 | #define BCM43xx_MMIO_DMA32_BASE0 0x200 |
| 66 | #define BCM43xx_MMIO_DMA32_BASE1 0x220 |
| 67 | #define BCM43xx_MMIO_DMA32_BASE2 0x240 |
| 68 | #define BCM43xx_MMIO_DMA32_BASE3 0x260 |
| 69 | #define BCM43xx_MMIO_DMA32_BASE4 0x280 |
| 70 | #define BCM43xx_MMIO_DMA32_BASE5 0x2A0 |
| 71 | /* 64-bit DMA */ |
| 72 | #define BCM43xx_MMIO_DMA64_BASE0 0x200 |
| 73 | #define BCM43xx_MMIO_DMA64_BASE1 0x240 |
| 74 | #define BCM43xx_MMIO_DMA64_BASE2 0x280 |
| 75 | #define BCM43xx_MMIO_DMA64_BASE3 0x2C0 |
| 76 | #define BCM43xx_MMIO_DMA64_BASE4 0x300 |
| 77 | #define BCM43xx_MMIO_DMA64_BASE5 0x340 |
| 78 | /* PIO */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 79 | #define BCM43xx_MMIO_PIO1_BASE 0x300 |
| 80 | #define BCM43xx_MMIO_PIO2_BASE 0x310 |
| 81 | #define BCM43xx_MMIO_PIO3_BASE 0x320 |
| 82 | #define BCM43xx_MMIO_PIO4_BASE 0x330 |
Michael Buesch | 9218e02 | 2006-08-16 00:25:16 +0200 | [diff] [blame] | 83 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 84 | #define BCM43xx_MMIO_PHY_VER 0x3E0 |
| 85 | #define BCM43xx_MMIO_PHY_RADIO 0x3E2 |
| 86 | #define BCM43xx_MMIO_ANTENNA 0x3E8 |
| 87 | #define BCM43xx_MMIO_CHANNEL 0x3F0 |
| 88 | #define BCM43xx_MMIO_CHANNEL_EXT 0x3F4 |
| 89 | #define BCM43xx_MMIO_RADIO_CONTROL 0x3F6 |
| 90 | #define BCM43xx_MMIO_RADIO_DATA_HIGH 0x3F8 |
| 91 | #define BCM43xx_MMIO_RADIO_DATA_LOW 0x3FA |
| 92 | #define BCM43xx_MMIO_PHY_CONTROL 0x3FC |
| 93 | #define BCM43xx_MMIO_PHY_DATA 0x3FE |
| 94 | #define BCM43xx_MMIO_MACFILTER_CONTROL 0x420 |
| 95 | #define BCM43xx_MMIO_MACFILTER_DATA 0x422 |
| 96 | #define BCM43xx_MMIO_RADIO_HWENABLED_LO 0x49A |
| 97 | #define BCM43xx_MMIO_GPIO_CONTROL 0x49C |
| 98 | #define BCM43xx_MMIO_GPIO_MASK 0x49E |
| 99 | #define BCM43xx_MMIO_TSF_0 0x632 /* core rev < 3 only */ |
| 100 | #define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */ |
| 101 | #define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */ |
| 102 | #define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */ |
Michael Buesch | 71c0cd7 | 2006-06-26 00:25:04 -0700 | [diff] [blame] | 103 | #define BCM43xx_MMIO_RNG 0x65A |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 104 | #define BCM43xx_MMIO_POWERUP_DELAY 0x6A8 |
| 105 | |
| 106 | /* SPROM offsets. */ |
| 107 | #define BCM43xx_SPROM_BASE 0x1000 |
| 108 | #define BCM43xx_SPROM_BOARDFLAGS2 0x1c |
| 109 | #define BCM43xx_SPROM_IL0MACADDR 0x24 |
| 110 | #define BCM43xx_SPROM_ET0MACADDR 0x27 |
| 111 | #define BCM43xx_SPROM_ET1MACADDR 0x2a |
| 112 | #define BCM43xx_SPROM_ETHPHY 0x2d |
| 113 | #define BCM43xx_SPROM_BOARDREV 0x2e |
| 114 | #define BCM43xx_SPROM_PA0B0 0x2f |
| 115 | #define BCM43xx_SPROM_PA0B1 0x30 |
| 116 | #define BCM43xx_SPROM_PA0B2 0x31 |
| 117 | #define BCM43xx_SPROM_WL0GPIO0 0x32 |
| 118 | #define BCM43xx_SPROM_WL0GPIO2 0x33 |
| 119 | #define BCM43xx_SPROM_MAXPWR 0x34 |
| 120 | #define BCM43xx_SPROM_PA1B0 0x35 |
| 121 | #define BCM43xx_SPROM_PA1B1 0x36 |
| 122 | #define BCM43xx_SPROM_PA1B2 0x37 |
| 123 | #define BCM43xx_SPROM_IDL_TSSI_TGT 0x38 |
| 124 | #define BCM43xx_SPROM_BOARDFLAGS 0x39 |
| 125 | #define BCM43xx_SPROM_ANTENNA_GAIN 0x3a |
| 126 | #define BCM43xx_SPROM_VERSION 0x3f |
| 127 | |
| 128 | /* BCM43xx_SPROM_BOARDFLAGS values */ |
| 129 | #define BCM43xx_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */ |
| 130 | #define BCM43xx_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */ |
| 131 | #define BCM43xx_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */ |
| 132 | #define BCM43xx_BFL_RSSI 0x0008 /* software calculates nrssi slope. */ |
| 133 | #define BCM43xx_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */ |
| 134 | #define BCM43xx_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */ |
| 135 | #define BCM43xx_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */ |
| 136 | #define BCM43xx_BFL_ENETADM 0x0080 /* has ADMtek switch */ |
| 137 | #define BCM43xx_BFL_ENETVLAN 0x0100 /* can do vlan */ |
| 138 | #define BCM43xx_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */ |
| 139 | #define BCM43xx_BFL_NOPCI 0x0400 /* leaves PCI floating */ |
| 140 | #define BCM43xx_BFL_FEM 0x0800 /* supports the Front End Module */ |
Michael Buesch | b3db5e5 | 2006-03-15 16:31:45 +0100 | [diff] [blame] | 141 | #define BCM43xx_BFL_EXTLNA 0x1000 /* has an external LNA */ |
| 142 | #define BCM43xx_BFL_HGPA 0x2000 /* had high gain PA */ |
| 143 | #define BCM43xx_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */ |
| 144 | #define BCM43xx_BFL_ALTIQ 0x8000 /* alternate I/Q settings */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 145 | |
| 146 | /* GPIO register offset, in both ChipCommon and PCI core. */ |
| 147 | #define BCM43xx_GPIO_CONTROL 0x6c |
| 148 | |
| 149 | /* SHM Routing */ |
| 150 | #define BCM43xx_SHM_SHARED 0x0001 |
| 151 | #define BCM43xx_SHM_WIRELESS 0x0002 |
| 152 | #define BCM43xx_SHM_PCM 0x0003 |
| 153 | #define BCM43xx_SHM_HWMAC 0x0004 |
| 154 | #define BCM43xx_SHM_UCODE 0x0300 |
| 155 | |
| 156 | /* MacFilter offsets. */ |
| 157 | #define BCM43xx_MACFILTER_SELF 0x0000 |
| 158 | #define BCM43xx_MACFILTER_ASSOC 0x0003 |
| 159 | |
| 160 | /* Chipcommon registers. */ |
| 161 | #define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 |
Stefano Brivio | f3d1fca | 2006-10-15 23:18:11 -0500 | [diff] [blame] | 162 | #define BCM43xx_CHIPCOMMON_CTL 0x28 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 163 | #define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 |
| 164 | #define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 |
| 165 | #define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 |
| 166 | #define BCM43xx_CHIPCOMMON_SYSCLKCTL 0xC0 |
| 167 | |
| 168 | /* PCI core specific registers. */ |
| 169 | #define BCM43xx_PCICORE_BCAST_ADDR 0x50 |
| 170 | #define BCM43xx_PCICORE_BCAST_DATA 0x54 |
| 171 | #define BCM43xx_PCICORE_SBTOPCI2 0x108 |
| 172 | |
| 173 | /* SBTOPCI2 values. */ |
| 174 | #define BCM43xx_SBTOPCI2_PREFETCH 0x4 |
| 175 | #define BCM43xx_SBTOPCI2_BURST 0x8 |
Stefano Brivio | f3d1fca | 2006-10-15 23:18:11 -0500 | [diff] [blame] | 176 | #define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20 |
| 177 | |
| 178 | /* PCI-E core registers. */ |
| 179 | #define BCM43xx_PCIECORE_REG_ADDR 0x0130 |
| 180 | #define BCM43xx_PCIECORE_REG_DATA 0x0134 |
| 181 | #define BCM43xx_PCIECORE_MDIO_CTL 0x0128 |
| 182 | #define BCM43xx_PCIECORE_MDIO_DATA 0x012C |
| 183 | |
| 184 | /* PCI-E registers. */ |
| 185 | #define BCM43xx_PCIE_TLP_WORKAROUND 0x0004 |
| 186 | #define BCM43xx_PCIE_DLLP_LINKCTL 0x0100 |
| 187 | |
| 188 | /* PCI-E MDIO bits. */ |
| 189 | #define BCM43xx_PCIE_MDIO_ST 0x40000000 |
| 190 | #define BCM43xx_PCIE_MDIO_WT 0x10000000 |
| 191 | #define BCM43xx_PCIE_MDIO_DEV 22 |
| 192 | #define BCM43xx_PCIE_MDIO_REG 18 |
| 193 | #define BCM43xx_PCIE_MDIO_TA 0x00020000 |
| 194 | #define BCM43xx_PCIE_MDIO_TC 0x0100 |
| 195 | |
| 196 | /* MDIO devices. */ |
| 197 | #define BCM43xx_MDIO_SERDES_RX 0x1F |
| 198 | |
| 199 | /* SERDES RX registers. */ |
| 200 | #define BCM43xx_SERDES_RXTIMER 0x2 |
| 201 | #define BCM43xx_SERDES_CDR 0x6 |
| 202 | #define BCM43xx_SERDES_CDR_BW 0x7 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 203 | |
| 204 | /* Chipcommon capabilities. */ |
| 205 | #define BCM43xx_CAPABILITIES_PCTL 0x00040000 |
| 206 | #define BCM43xx_CAPABILITIES_PLLMASK 0x00030000 |
| 207 | #define BCM43xx_CAPABILITIES_PLLSHIFT 16 |
| 208 | #define BCM43xx_CAPABILITIES_FLASHMASK 0x00000700 |
| 209 | #define BCM43xx_CAPABILITIES_FLASHSHIFT 8 |
| 210 | #define BCM43xx_CAPABILITIES_EXTBUSPRESENT 0x00000040 |
| 211 | #define BCM43xx_CAPABILITIES_UARTGPIO 0x00000020 |
| 212 | #define BCM43xx_CAPABILITIES_UARTCLOCKMASK 0x00000018 |
| 213 | #define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT 3 |
| 214 | #define BCM43xx_CAPABILITIES_MIPSBIGENDIAN 0x00000004 |
| 215 | #define BCM43xx_CAPABILITIES_NRUARTSMASK 0x00000003 |
| 216 | |
| 217 | /* PowerControl */ |
| 218 | #define BCM43xx_PCTL_IN 0xB0 |
| 219 | #define BCM43xx_PCTL_OUT 0xB4 |
| 220 | #define BCM43xx_PCTL_OUTENABLE 0xB8 |
| 221 | #define BCM43xx_PCTL_XTAL_POWERUP 0x40 |
| 222 | #define BCM43xx_PCTL_PLL_POWERDOWN 0x80 |
| 223 | |
| 224 | /* PowerControl Clock Modes */ |
| 225 | #define BCM43xx_PCTL_CLK_FAST 0x00 |
| 226 | #define BCM43xx_PCTL_CLK_SLOW 0x01 |
| 227 | #define BCM43xx_PCTL_CLK_DYNAMIC 0x02 |
| 228 | |
| 229 | #define BCM43xx_PCTL_FORCE_SLOW 0x0800 |
| 230 | #define BCM43xx_PCTL_FORCE_PLL 0x1000 |
| 231 | #define BCM43xx_PCTL_DYN_XTAL 0x2000 |
| 232 | |
| 233 | /* COREIDs */ |
| 234 | #define BCM43xx_COREID_CHIPCOMMON 0x800 |
| 235 | #define BCM43xx_COREID_ILINE20 0x801 |
| 236 | #define BCM43xx_COREID_SDRAM 0x803 |
| 237 | #define BCM43xx_COREID_PCI 0x804 |
| 238 | #define BCM43xx_COREID_MIPS 0x805 |
| 239 | #define BCM43xx_COREID_ETHERNET 0x806 |
| 240 | #define BCM43xx_COREID_V90 0x807 |
| 241 | #define BCM43xx_COREID_USB11_HOSTDEV 0x80a |
| 242 | #define BCM43xx_COREID_IPSEC 0x80b |
| 243 | #define BCM43xx_COREID_PCMCIA 0x80d |
| 244 | #define BCM43xx_COREID_EXT_IF 0x80f |
| 245 | #define BCM43xx_COREID_80211 0x812 |
| 246 | #define BCM43xx_COREID_MIPS_3302 0x816 |
| 247 | #define BCM43xx_COREID_USB11_HOST 0x817 |
| 248 | #define BCM43xx_COREID_USB11_DEV 0x818 |
| 249 | #define BCM43xx_COREID_USB20_HOST 0x819 |
| 250 | #define BCM43xx_COREID_USB20_DEV 0x81a |
| 251 | #define BCM43xx_COREID_SDIO_HOST 0x81b |
Stefano Brivio | f3d1fca | 2006-10-15 23:18:11 -0500 | [diff] [blame] | 252 | #define BCM43xx_COREID_PCIE 0x820 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 253 | |
| 254 | /* Core Information Registers */ |
| 255 | #define BCM43xx_CIR_BASE 0xf00 |
| 256 | #define BCM43xx_CIR_SBTPSFLAG (BCM43xx_CIR_BASE + 0x18) |
| 257 | #define BCM43xx_CIR_SBIMSTATE (BCM43xx_CIR_BASE + 0x90) |
| 258 | #define BCM43xx_CIR_SBINTVEC (BCM43xx_CIR_BASE + 0x94) |
| 259 | #define BCM43xx_CIR_SBTMSTATELOW (BCM43xx_CIR_BASE + 0x98) |
| 260 | #define BCM43xx_CIR_SBTMSTATEHIGH (BCM43xx_CIR_BASE + 0x9c) |
| 261 | #define BCM43xx_CIR_SBIMCONFIGLOW (BCM43xx_CIR_BASE + 0xa8) |
| 262 | #define BCM43xx_CIR_SB_ID_HI (BCM43xx_CIR_BASE + 0xfc) |
| 263 | |
| 264 | /* Mask to get the Backplane Flag Number from SBTPSFLAG. */ |
| 265 | #define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f |
| 266 | |
| 267 | /* SBIMCONFIGLOW values/masks. */ |
| 268 | #define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK 0x00000007 |
| 269 | #define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT 0 |
| 270 | #define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK 0x00000070 |
| 271 | #define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT 4 |
| 272 | #define BCM43xx_SBIMCONFIGLOW_CONNID_MASK 0x00ff0000 |
| 273 | #define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT 16 |
| 274 | |
| 275 | /* sbtmstatelow state flags */ |
| 276 | #define BCM43xx_SBTMSTATELOW_RESET 0x01 |
| 277 | #define BCM43xx_SBTMSTATELOW_REJECT 0x02 |
| 278 | #define BCM43xx_SBTMSTATELOW_CLOCK 0x10000 |
| 279 | #define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000 |
| 280 | |
| 281 | /* sbtmstatehigh state flags */ |
Michael Buesch | 9218e02 | 2006-08-16 00:25:16 +0200 | [diff] [blame] | 282 | #define BCM43xx_SBTMSTATEHIGH_SERROR 0x00000001 |
| 283 | #define BCM43xx_SBTMSTATEHIGH_BUSY 0x00000004 |
| 284 | #define BCM43xx_SBTMSTATEHIGH_TIMEOUT 0x00000020 |
| 285 | #define BCM43xx_SBTMSTATEHIGH_COREFLAGS 0x1FFF0000 |
| 286 | #define BCM43xx_SBTMSTATEHIGH_DMA64BIT 0x10000000 |
| 287 | #define BCM43xx_SBTMSTATEHIGH_GATEDCLK 0x20000000 |
| 288 | #define BCM43xx_SBTMSTATEHIGH_BISTFAILED 0x40000000 |
| 289 | #define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE 0x80000000 |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 290 | |
| 291 | /* sbimstate flags */ |
| 292 | #define BCM43xx_SBIMSTATE_IB_ERROR 0x20000 |
| 293 | #define BCM43xx_SBIMSTATE_TIMEOUT 0x40000 |
| 294 | |
| 295 | /* PHYVersioning */ |
| 296 | #define BCM43xx_PHYTYPE_A 0x00 |
| 297 | #define BCM43xx_PHYTYPE_B 0x01 |
| 298 | #define BCM43xx_PHYTYPE_G 0x02 |
| 299 | |
| 300 | /* PHYRegisters */ |
| 301 | #define BCM43xx_PHY_ILT_A_CTRL 0x0072 |
| 302 | #define BCM43xx_PHY_ILT_A_DATA1 0x0073 |
| 303 | #define BCM43xx_PHY_ILT_A_DATA2 0x0074 |
| 304 | #define BCM43xx_PHY_G_LO_CONTROL 0x0810 |
| 305 | #define BCM43xx_PHY_ILT_G_CTRL 0x0472 |
| 306 | #define BCM43xx_PHY_ILT_G_DATA1 0x0473 |
| 307 | #define BCM43xx_PHY_ILT_G_DATA2 0x0474 |
| 308 | #define BCM43xx_PHY_A_PCTL 0x007B |
| 309 | #define BCM43xx_PHY_G_PCTL 0x0029 |
| 310 | #define BCM43xx_PHY_A_CRS 0x0029 |
| 311 | #define BCM43xx_PHY_RADIO_BITFIELD 0x0401 |
| 312 | #define BCM43xx_PHY_G_CRS 0x0429 |
| 313 | #define BCM43xx_PHY_NRSSILT_CTRL 0x0803 |
| 314 | #define BCM43xx_PHY_NRSSILT_DATA 0x0804 |
| 315 | |
| 316 | /* RadioRegisters */ |
| 317 | #define BCM43xx_RADIOCTL_ID 0x01 |
| 318 | |
| 319 | /* StatusBitField */ |
| 320 | #define BCM43xx_SBF_MAC_ENABLED 0x00000001 |
| 321 | #define BCM43xx_SBF_2 0x00000002 /*FIXME: fix name*/ |
| 322 | #define BCM43xx_SBF_CORE_READY 0x00000004 |
| 323 | #define BCM43xx_SBF_400 0x00000400 /*FIXME: fix name*/ |
| 324 | #define BCM43xx_SBF_4000 0x00004000 /*FIXME: fix name*/ |
| 325 | #define BCM43xx_SBF_8000 0x00008000 /*FIXME: fix name*/ |
| 326 | #define BCM43xx_SBF_XFER_REG_BYTESWAP 0x00010000 |
| 327 | #define BCM43xx_SBF_MODE_NOTADHOC 0x00020000 |
| 328 | #define BCM43xx_SBF_MODE_AP 0x00040000 |
| 329 | #define BCM43xx_SBF_RADIOREG_LOCK 0x00080000 |
| 330 | #define BCM43xx_SBF_MODE_MONITOR 0x00400000 |
| 331 | #define BCM43xx_SBF_MODE_PROMISC 0x01000000 |
| 332 | #define BCM43xx_SBF_PS1 0x02000000 |
| 333 | #define BCM43xx_SBF_PS2 0x04000000 |
| 334 | #define BCM43xx_SBF_NO_SSID_BCAST 0x08000000 |
| 335 | #define BCM43xx_SBF_TIME_UPDATE 0x10000000 |
| 336 | #define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/ |
| 337 | |
Larry Finger | 1ef4583 | 2006-09-04 17:13:57 -0500 | [diff] [blame] | 338 | /* Microcode */ |
Larry Finger | 87d2632 | 2006-09-07 10:12:11 -0500 | [diff] [blame] | 339 | #define BCM43xx_UCODE_REVISION 0x0000 |
| 340 | #define BCM43xx_UCODE_PATCHLEVEL 0x0002 |
| 341 | #define BCM43xx_UCODE_DATE 0x0004 |
| 342 | #define BCM43xx_UCODE_TIME 0x0006 |
| 343 | #define BCM43xx_UCODE_STATUS 0x0040 |
Larry Finger | 1ef4583 | 2006-09-04 17:13:57 -0500 | [diff] [blame] | 344 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 345 | /* MicrocodeFlagsBitfield (addr + lo-word values?)*/ |
| 346 | #define BCM43xx_UCODEFLAGS_OFFSET 0x005E |
| 347 | |
| 348 | #define BCM43xx_UCODEFLAG_AUTODIV 0x0001 |
| 349 | #define BCM43xx_UCODEFLAG_UNKBGPHY 0x0002 |
| 350 | #define BCM43xx_UCODEFLAG_UNKBPHY 0x0004 |
| 351 | #define BCM43xx_UCODEFLAG_UNKGPHY 0x0020 |
| 352 | #define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040 |
| 353 | #define BCM43xx_UCODEFLAG_JAPAN 0x0080 |
| 354 | |
| 355 | /* Generic-Interrupt reasons. */ |
| 356 | #define BCM43xx_IRQ_READY (1 << 0) |
| 357 | #define BCM43xx_IRQ_BEACON (1 << 1) |
| 358 | #define BCM43xx_IRQ_PS (1 << 2) |
| 359 | #define BCM43xx_IRQ_REG124 (1 << 5) |
| 360 | #define BCM43xx_IRQ_PMQ (1 << 6) |
| 361 | #define BCM43xx_IRQ_PIO_WORKAROUND (1 << 8) |
| 362 | #define BCM43xx_IRQ_XMIT_ERROR (1 << 11) |
| 363 | #define BCM43xx_IRQ_RX (1 << 15) |
| 364 | #define BCM43xx_IRQ_SCAN (1 << 16) |
| 365 | #define BCM43xx_IRQ_NOISE (1 << 18) |
| 366 | #define BCM43xx_IRQ_XMIT_STATUS (1 << 29) |
| 367 | |
| 368 | #define BCM43xx_IRQ_ALL 0xffffffff |
| 369 | #define BCM43xx_IRQ_INITIAL (BCM43xx_IRQ_PS | \ |
| 370 | BCM43xx_IRQ_REG124 | \ |
| 371 | BCM43xx_IRQ_PMQ | \ |
| 372 | BCM43xx_IRQ_XMIT_ERROR | \ |
| 373 | BCM43xx_IRQ_RX | \ |
| 374 | BCM43xx_IRQ_SCAN | \ |
| 375 | BCM43xx_IRQ_NOISE | \ |
| 376 | BCM43xx_IRQ_XMIT_STATUS) |
| 377 | |
| 378 | |
| 379 | /* Initial default iw_mode */ |
| 380 | #define BCM43xx_INITIAL_IWMODE IW_MODE_INFRA |
| 381 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 382 | /* Bus type PCI. */ |
| 383 | #define BCM43xx_BUSTYPE_PCI 0 |
| 384 | /* Bus type Silicone Backplane Bus. */ |
| 385 | #define BCM43xx_BUSTYPE_SB 1 |
| 386 | /* Bus type PCMCIA. */ |
| 387 | #define BCM43xx_BUSTYPE_PCMCIA 2 |
| 388 | |
| 389 | /* Threshold values. */ |
| 390 | #define BCM43xx_MIN_RTS_THRESHOLD 1U |
| 391 | #define BCM43xx_MAX_RTS_THRESHOLD 2304U |
| 392 | #define BCM43xx_DEFAULT_RTS_THRESHOLD BCM43xx_MAX_RTS_THRESHOLD |
| 393 | |
| 394 | #define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7 |
| 395 | #define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4 |
| 396 | |
Larry Finger | f04e2be | 2006-09-25 15:33:20 -0500 | [diff] [blame] | 397 | /* FIXME: the next line is a guess as to what the maximum RSSI value might be */ |
| 398 | #define RX_RSSI_MAX 60 |
| 399 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 400 | /* Max size of a security key */ |
| 401 | #define BCM43xx_SEC_KEYSIZE 16 |
| 402 | /* Security algorithms. */ |
| 403 | enum { |
| 404 | BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */ |
| 405 | BCM43xx_SEC_ALGO_WEP, |
| 406 | BCM43xx_SEC_ALGO_UNKNOWN, |
| 407 | BCM43xx_SEC_ALGO_AES, |
| 408 | BCM43xx_SEC_ALGO_WEP104, |
| 409 | BCM43xx_SEC_ALGO_TKIP, |
| 410 | }; |
| 411 | |
| 412 | #ifdef assert |
| 413 | # undef assert |
| 414 | #endif |
| 415 | #ifdef CONFIG_BCM43XX_DEBUG |
| 416 | #define assert(expr) \ |
| 417 | do { \ |
| 418 | if (unlikely(!(expr))) { \ |
| 419 | printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \ |
| 420 | #expr, __FILE__, __LINE__, __FUNCTION__); \ |
| 421 | } \ |
| 422 | } while (0) |
| 423 | #else |
| 424 | #define assert(expr) do { /* nothing */ } while (0) |
| 425 | #endif |
| 426 | |
| 427 | /* rate limited printk(). */ |
| 428 | #ifdef printkl |
| 429 | # undef printkl |
| 430 | #endif |
| 431 | #define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0) |
| 432 | /* rate limited printk() for debugging */ |
| 433 | #ifdef dprintkl |
| 434 | # undef dprintkl |
| 435 | #endif |
| 436 | #ifdef CONFIG_BCM43XX_DEBUG |
| 437 | # define dprintkl printkl |
| 438 | #else |
| 439 | # define dprintkl(f, x...) do { /* nothing */ } while (0) |
| 440 | #endif |
| 441 | |
| 442 | /* Helper macro for if branches. |
| 443 | * An if branch marked with this macro is only taken in DEBUG mode. |
| 444 | * Example: |
| 445 | * if (DEBUG_ONLY(foo == bar)) { |
| 446 | * do something |
| 447 | * } |
| 448 | * In DEBUG mode, the branch will be taken if (foo == bar). |
| 449 | * In non-DEBUG mode, the branch will never be taken. |
| 450 | */ |
| 451 | #ifdef DEBUG_ONLY |
| 452 | # undef DEBUG_ONLY |
| 453 | #endif |
| 454 | #ifdef CONFIG_BCM43XX_DEBUG |
| 455 | # define DEBUG_ONLY(x) (x) |
| 456 | #else |
| 457 | # define DEBUG_ONLY(x) 0 |
| 458 | #endif |
| 459 | |
| 460 | /* debugging printk() */ |
| 461 | #ifdef dprintk |
| 462 | # undef dprintk |
| 463 | #endif |
| 464 | #ifdef CONFIG_BCM43XX_DEBUG |
| 465 | # define dprintk(f, x...) do { printk(f ,##x); } while (0) |
| 466 | #else |
| 467 | # define dprintk(f, x...) do { /* nothing */ } while (0) |
| 468 | #endif |
| 469 | |
| 470 | |
| 471 | struct net_device; |
| 472 | struct pci_dev; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 473 | struct bcm43xx_dmaring; |
| 474 | struct bcm43xx_pioqueue; |
| 475 | |
| 476 | struct bcm43xx_initval { |
| 477 | u16 offset; |
| 478 | u16 size; |
| 479 | u32 value; |
| 480 | } __attribute__((__packed__)); |
| 481 | |
| 482 | /* Values for bcm430x_sprominfo.locale */ |
| 483 | enum { |
| 484 | BCM43xx_LOCALE_WORLD = 0, |
| 485 | BCM43xx_LOCALE_THAILAND, |
| 486 | BCM43xx_LOCALE_ISRAEL, |
| 487 | BCM43xx_LOCALE_JORDAN, |
| 488 | BCM43xx_LOCALE_CHINA, |
| 489 | BCM43xx_LOCALE_JAPAN, |
| 490 | BCM43xx_LOCALE_USA_CANADA_ANZ, |
| 491 | BCM43xx_LOCALE_EUROPE, |
| 492 | BCM43xx_LOCALE_USA_LOW, |
| 493 | BCM43xx_LOCALE_JAPAN_HIGH, |
| 494 | BCM43xx_LOCALE_ALL, |
| 495 | BCM43xx_LOCALE_NONE, |
| 496 | }; |
| 497 | |
| 498 | #define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */ |
| 499 | struct bcm43xx_sprominfo { |
| 500 | u16 boardflags2; |
| 501 | u8 il0macaddr[6]; |
| 502 | u8 et0macaddr[6]; |
| 503 | u8 et1macaddr[6]; |
| 504 | u8 et0phyaddr:5; |
| 505 | u8 et1phyaddr:5; |
| 506 | u8 et0mdcport:1; |
| 507 | u8 et1mdcport:1; |
| 508 | u8 boardrev; |
| 509 | u8 locale:4; |
| 510 | u8 antennas_aphy:2; |
| 511 | u8 antennas_bgphy:2; |
| 512 | u16 pa0b0; |
| 513 | u16 pa0b1; |
| 514 | u16 pa0b2; |
| 515 | u8 wl0gpio0; |
| 516 | u8 wl0gpio1; |
| 517 | u8 wl0gpio2; |
| 518 | u8 wl0gpio3; |
| 519 | u8 maxpower_aphy; |
| 520 | u8 maxpower_bgphy; |
| 521 | u16 pa1b0; |
| 522 | u16 pa1b1; |
| 523 | u16 pa1b2; |
| 524 | u8 idle_tssi_tgt_aphy; |
| 525 | u8 idle_tssi_tgt_bgphy; |
| 526 | u16 boardflags; |
| 527 | u16 antennagain_aphy; |
| 528 | u16 antennagain_bgphy; |
| 529 | }; |
| 530 | |
| 531 | /* Value pair to measure the LocalOscillator. */ |
| 532 | struct bcm43xx_lopair { |
| 533 | s8 low; |
| 534 | s8 high; |
| 535 | u8 used:1; |
| 536 | }; |
| 537 | #define BCM43xx_LO_COUNT (14*4) |
| 538 | |
| 539 | struct bcm43xx_phyinfo { |
| 540 | /* Hardware Data */ |
| 541 | u8 version; |
| 542 | u8 type; |
| 543 | u8 rev; |
| 544 | u16 antenna_diversity; |
| 545 | u16 savedpctlreg; |
| 546 | u16 minlowsig[2]; |
| 547 | u16 minlowsigpos[2]; |
| 548 | u8 connected:1, |
| 549 | calibrated:1, |
| 550 | is_locked:1, /* used in bcm43xx_phy_{un}lock() */ |
| 551 | dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */ |
| 552 | /* LO Measurement Data. |
| 553 | * Use bcm43xx_get_lopair() to get a value. |
| 554 | */ |
| 555 | struct bcm43xx_lopair *_lo_pairs; |
| 556 | |
| 557 | /* TSSI to dBm table in use */ |
| 558 | const s8 *tssi2dbm; |
| 559 | /* idle TSSI value */ |
| 560 | s8 idle_tssi; |
Michael Buesch | adc40e9 | 2006-03-25 20:36:57 +0100 | [diff] [blame] | 561 | |
| 562 | /* Values from bcm43xx_calc_loopback_gain() */ |
| 563 | u16 loopback_gain[2]; |
| 564 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 565 | /* PHY lock for core.rev < 3 |
| 566 | * This lock is only used by bcm43xx_phy_{un}lock() |
| 567 | */ |
| 568 | spinlock_t lock; |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 569 | |
| 570 | /* Firmware. */ |
| 571 | const struct firmware *ucode; |
| 572 | const struct firmware *pcm; |
| 573 | const struct firmware *initvals0; |
| 574 | const struct firmware *initvals1; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 575 | }; |
| 576 | |
| 577 | |
| 578 | struct bcm43xx_radioinfo { |
| 579 | u16 manufact; |
| 580 | u16 version; |
| 581 | u8 revision; |
| 582 | |
Michael Buesch | 393344f | 2006-02-05 15:28:20 +0100 | [diff] [blame] | 583 | /* Desired TX power in dBm Q5.2 */ |
| 584 | u16 txpower_desired; |
Michael Buesch | 6ecb269 | 2006-03-20 00:01:04 +0100 | [diff] [blame] | 585 | /* TX Power control values. */ |
| 586 | union { |
| 587 | /* B/G PHY */ |
| 588 | struct { |
| 589 | u16 baseband_atten; |
| 590 | u16 radio_atten; |
| 591 | u16 txctl1; |
| 592 | u16 txctl2; |
| 593 | }; |
| 594 | /* A PHY */ |
| 595 | struct { |
| 596 | u16 txpwr_offset; |
| 597 | }; |
| 598 | }; |
| 599 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 600 | /* Current Interference Mitigation mode */ |
| 601 | int interfmode; |
Michael Buesch | e382c23 | 2006-03-21 18:16:28 +0100 | [diff] [blame] | 602 | /* Stack of saved values from the Interference Mitigation code. |
| 603 | * Each value in the stack is layed out as follows: |
| 604 | * bit 0-11: offset |
| 605 | * bit 12-15: register ID |
| 606 | * bit 16-32: value |
| 607 | * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT |
| 608 | */ |
| 609 | #define BCM43xx_INTERFSTACK_SIZE 26 |
| 610 | u32 interfstack[BCM43xx_INTERFSTACK_SIZE]; |
| 611 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 612 | /* Saved values from the NRSSI Slope calculation */ |
| 613 | s16 nrssi[2]; |
| 614 | s32 nrssislope; |
| 615 | /* In memory nrssi lookup table. */ |
| 616 | s8 nrssi_lt[64]; |
| 617 | |
| 618 | /* current channel */ |
| 619 | u8 channel; |
| 620 | u8 initial_channel; |
| 621 | |
| 622 | u16 lofcal; |
| 623 | |
| 624 | u16 initval; |
| 625 | |
| 626 | u8 enabled:1; |
| 627 | /* ACI (adjacent channel interference) flags. */ |
| 628 | u8 aci_enable:1, |
| 629 | aci_wlan_automatic:1, |
| 630 | aci_hw_rssi:1; |
| 631 | }; |
| 632 | |
| 633 | /* Data structures for DMA transmission, per 80211 core. */ |
| 634 | struct bcm43xx_dma { |
| 635 | struct bcm43xx_dmaring *tx_ring0; |
| 636 | struct bcm43xx_dmaring *tx_ring1; |
| 637 | struct bcm43xx_dmaring *tx_ring2; |
| 638 | struct bcm43xx_dmaring *tx_ring3; |
Michael Buesch | 9218e02 | 2006-08-16 00:25:16 +0200 | [diff] [blame] | 639 | struct bcm43xx_dmaring *tx_ring4; |
| 640 | struct bcm43xx_dmaring *tx_ring5; |
| 641 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 642 | struct bcm43xx_dmaring *rx_ring0; |
Michael Buesch | 9218e02 | 2006-08-16 00:25:16 +0200 | [diff] [blame] | 643 | struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 644 | }; |
| 645 | |
| 646 | /* Data structures for PIO transmission, per 80211 core. */ |
| 647 | struct bcm43xx_pio { |
| 648 | struct bcm43xx_pioqueue *queue0; |
| 649 | struct bcm43xx_pioqueue *queue1; |
| 650 | struct bcm43xx_pioqueue *queue2; |
| 651 | struct bcm43xx_pioqueue *queue3; |
| 652 | }; |
| 653 | |
| 654 | #define BCM43xx_MAX_80211_CORES 2 |
| 655 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 656 | #ifdef CONFIG_BCM947XX |
| 657 | #define core_offset(bcm) (bcm)->current_core_offset |
| 658 | #else |
| 659 | #define core_offset(bcm) 0 |
| 660 | #endif |
| 661 | |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 662 | /* Generic information about a core. */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 663 | struct bcm43xx_coreinfo { |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 664 | u8 available:1, |
| 665 | enabled:1, |
| 666 | initialized:1; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 667 | /** core_rev revision number */ |
| 668 | u8 rev; |
| 669 | /** Index number for _switch_core() */ |
| 670 | u8 index; |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 671 | /** core_id ID number */ |
| 672 | u16 id; |
| 673 | /** Core-specific data. */ |
| 674 | void *priv; |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 675 | }; |
| 676 | |
| 677 | /* Additional information for each 80211 core. */ |
| 678 | struct bcm43xx_coreinfo_80211 { |
| 679 | /* PHY device. */ |
| 680 | struct bcm43xx_phyinfo phy; |
| 681 | /* Radio device. */ |
| 682 | struct bcm43xx_radioinfo radio; |
| 683 | union { |
| 684 | /* DMA context. */ |
| 685 | struct bcm43xx_dma dma; |
| 686 | /* PIO context. */ |
| 687 | struct bcm43xx_pio pio; |
| 688 | }; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 689 | }; |
| 690 | |
| 691 | /* Context information for a noise calculation (Link Quality). */ |
| 692 | struct bcm43xx_noise_calculation { |
| 693 | struct bcm43xx_coreinfo *core_at_start; |
| 694 | u8 channel_at_start; |
| 695 | u8 calculation_running:1; |
| 696 | u8 nr_samples; |
| 697 | s8 samples[8][4]; |
| 698 | }; |
| 699 | |
| 700 | struct bcm43xx_stats { |
Michael Buesch | 72fb851 | 2006-03-22 18:10:19 +0100 | [diff] [blame] | 701 | u8 noise; |
| 702 | struct iw_statistics wstats; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 703 | /* Store the last TX/RX times here for updating the leds. */ |
| 704 | unsigned long last_tx; |
| 705 | unsigned long last_rx; |
| 706 | }; |
| 707 | |
| 708 | struct bcm43xx_key { |
| 709 | u8 enabled:1; |
| 710 | u8 algorithm; |
| 711 | }; |
| 712 | |
Michael Buesch | 78ff56a | 2006-06-05 20:24:10 +0200 | [diff] [blame] | 713 | /* Driver initialization status. */ |
| 714 | enum { |
| 715 | BCM43xx_STAT_UNINIT, /* Uninitialized. */ |
| 716 | BCM43xx_STAT_INITIALIZING, /* init_board() in progress. */ |
| 717 | BCM43xx_STAT_INITIALIZED, /* Fully operational. */ |
| 718 | BCM43xx_STAT_SHUTTINGDOWN, /* free_board() in progress. */ |
| 719 | BCM43xx_STAT_RESTARTING, /* controller_restart() called. */ |
| 720 | }; |
| 721 | #define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 722 | #define bcm43xx_set_status(bcm, stat) do { \ |
| 723 | atomic_set(&(bcm)->init_status, (stat)); \ |
| 724 | smp_wmb(); \ |
| 725 | } while (0) |
Michael Buesch | 78ff56a | 2006-06-05 20:24:10 +0200 | [diff] [blame] | 726 | |
Michael Buesch | efa6a37 | 2006-06-27 21:38:40 +0200 | [diff] [blame] | 727 | /* *** THEORY OF LOCKING *** |
| 728 | * |
| 729 | * We have two different locks in the bcm43xx driver. |
| 730 | * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private |
| 731 | * and the device registers. This mutex does _not_ protect |
| 732 | * against concurrency from the IRQ handler. |
| 733 | * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency. |
| 734 | * |
| 735 | * Please note that, if you only take the irq_lock, you are not protected |
| 736 | * against concurrency from the periodic work handlers. |
| 737 | * Most times you want to take _both_ locks. |
| 738 | */ |
| 739 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 740 | struct bcm43xx_private { |
| 741 | struct ieee80211_device *ieee; |
| 742 | struct ieee80211softmac_device *softmac; |
| 743 | |
| 744 | struct net_device *net_dev; |
| 745 | struct pci_dev *pci_dev; |
| 746 | unsigned int irq; |
| 747 | |
| 748 | void __iomem *mmio_addr; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 749 | |
Michael Buesch | 78ff56a | 2006-06-05 20:24:10 +0200 | [diff] [blame] | 750 | spinlock_t irq_lock; |
| 751 | struct mutex mutex; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 752 | |
Michael Buesch | 78ff56a | 2006-06-05 20:24:10 +0200 | [diff] [blame] | 753 | /* Driver initialization status BCM43xx_STAT_*** */ |
| 754 | atomic_t init_status; |
| 755 | |
| 756 | u16 was_initialized:1, /* for PCI suspend/resume. */ |
Michael Buesch | 77db31e | 2006-02-12 16:47:44 +0100 | [diff] [blame] | 757 | __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 758 | bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ |
| 759 | reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 760 | short_preamble:1, /* TRUE, if short preamble is enabled. */ |
| 761 | firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ |
| 762 | |
| 763 | struct bcm43xx_stats stats; |
| 764 | |
| 765 | /* Bus type we are connected to. |
| 766 | * This is currently always BCM43xx_BUSTYPE_PCI |
| 767 | */ |
| 768 | u8 bustype; |
Larry Finger | 4710303 | 2007-01-21 22:27:35 -0600 | [diff] [blame^] | 769 | u64 dma_mask; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 770 | |
| 771 | u16 board_vendor; |
| 772 | u16 board_type; |
| 773 | u16 board_revision; |
| 774 | |
| 775 | u16 chip_id; |
| 776 | u8 chip_rev; |
Michael Buesch | adc40e9 | 2006-03-25 20:36:57 +0100 | [diff] [blame] | 777 | u8 chip_package; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 778 | |
| 779 | struct bcm43xx_sprominfo sprom; |
| 780 | #define BCM43xx_NR_LEDS 4 |
| 781 | struct bcm43xx_led leds[BCM43xx_NR_LEDS]; |
Michael Buesch | efa6a37 | 2006-06-27 21:38:40 +0200 | [diff] [blame] | 782 | spinlock_t leds_lock; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 783 | |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 784 | /* The currently active core. */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 785 | struct bcm43xx_coreinfo *current_core; |
| 786 | #ifdef CONFIG_BCM947XX |
| 787 | /** current core memory offset */ |
| 788 | u32 current_core_offset; |
| 789 | #endif |
| 790 | struct bcm43xx_coreinfo *active_80211_core; |
| 791 | /* coreinfo structs for all possible cores follow. |
| 792 | * Note that a core might not exist. |
| 793 | * So check the coreinfo flags before using it. |
| 794 | */ |
| 795 | struct bcm43xx_coreinfo core_chipcommon; |
| 796 | struct bcm43xx_coreinfo core_pci; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 797 | struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ]; |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 798 | /* Additional information, specific to the 80211 cores. */ |
| 799 | struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ]; |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 800 | /* Number of available 80211 cores. */ |
| 801 | int nr_80211_available; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 802 | |
| 803 | u32 chipcommon_capabilities; |
| 804 | |
| 805 | /* Reason code of the last interrupt. */ |
| 806 | u32 irq_reason; |
Michael Buesch | 9218e02 | 2006-08-16 00:25:16 +0200 | [diff] [blame] | 807 | u32 dma_reason[6]; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 808 | /* saved irq enable/disable state bitfield. */ |
| 809 | u32 irq_savedstate; |
| 810 | /* Link Quality calculation context. */ |
| 811 | struct bcm43xx_noise_calculation noisecalc; |
Michael Buesch | 062caf4 | 2006-06-12 17:02:22 +0200 | [diff] [blame] | 812 | /* if > 0 MAC is suspended. if == 0 MAC is enabled. */ |
| 813 | int mac_suspended; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 814 | |
| 815 | /* Threshold values. */ |
| 816 | //TODO: The RTS thr has to be _used_. Currently, it is only set via WX. |
| 817 | u32 rts_threshold; |
| 818 | |
| 819 | /* Interrupt Service Routine tasklet (bottom-half) */ |
| 820 | struct tasklet_struct isr_tasklet; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 821 | |
| 822 | /* Periodic tasks */ |
David Howells | c402895 | 2006-11-22 14:57:56 +0000 | [diff] [blame] | 823 | struct delayed_work periodic_work; |
Michael Buesch | ab4977f | 2006-02-12 22:40:39 +0100 | [diff] [blame] | 824 | unsigned int periodic_state; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 825 | |
| 826 | struct work_struct restart_work; |
| 827 | |
| 828 | /* Informational stuff. */ |
| 829 | char nick[IW_ESSID_MAX_SIZE + 1]; |
| 830 | |
| 831 | /* encryption/decryption */ |
| 832 | u16 security_offset; |
| 833 | struct bcm43xx_key key[54]; |
| 834 | u8 default_key_idx; |
| 835 | |
Michael Buesch | 71c0cd7 | 2006-06-26 00:25:04 -0700 | [diff] [blame] | 836 | /* Random Number Generator. */ |
| 837 | struct hwrng rng; |
| 838 | char rng_name[20 + 1]; |
| 839 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 840 | /* Debugging stuff follows. */ |
| 841 | #ifdef CONFIG_BCM43XX_DEBUG |
| 842 | struct bcm43xx_dfsentry *dfsentry; |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 843 | #endif |
| 844 | }; |
| 845 | |
Michael Buesch | 78ff56a | 2006-06-05 20:24:10 +0200 | [diff] [blame] | 846 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 847 | static inline |
| 848 | struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) |
| 849 | { |
| 850 | return ieee80211softmac_priv(dev); |
| 851 | } |
| 852 | |
Michael Buesch | b35d649 | 2006-04-13 02:32:58 +0200 | [diff] [blame] | 853 | struct device; |
| 854 | |
| 855 | static inline |
| 856 | struct bcm43xx_private * dev_to_bcm(struct device *dev) |
| 857 | { |
| 858 | struct net_device *net_dev; |
| 859 | struct bcm43xx_private *bcm; |
| 860 | |
| 861 | net_dev = dev_get_drvdata(dev); |
| 862 | bcm = bcm43xx_priv(net_dev); |
| 863 | |
| 864 | return bcm; |
| 865 | } |
| 866 | |
Michael Buesch | 77db31e | 2006-02-12 16:47:44 +0100 | [diff] [blame] | 867 | |
| 868 | /* Helper function, which returns a boolean. |
| 869 | * TRUE, if PIO is used; FALSE, if DMA is used. |
| 870 | */ |
| 871 | #if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO) |
| 872 | static inline |
| 873 | int bcm43xx_using_pio(struct bcm43xx_private *bcm) |
| 874 | { |
| 875 | return bcm->__using_pio; |
| 876 | } |
| 877 | #elif defined(CONFIG_BCM43XX_DMA) |
| 878 | static inline |
| 879 | int bcm43xx_using_pio(struct bcm43xx_private *bcm) |
| 880 | { |
| 881 | return 0; |
| 882 | } |
| 883 | #elif defined(CONFIG_BCM43XX_PIO) |
| 884 | static inline |
| 885 | int bcm43xx_using_pio(struct bcm43xx_private *bcm) |
| 886 | { |
| 887 | return 1; |
| 888 | } |
| 889 | #else |
| 890 | # error "Using neither DMA nor PIO? Confused..." |
| 891 | #endif |
| 892 | |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 893 | /* Helper functions to access data structures private to the 80211 cores. |
| 894 | * Note that we _must_ have an 80211 core mapped when calling |
| 895 | * any of these functions. |
| 896 | */ |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 897 | static inline |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 898 | struct bcm43xx_coreinfo_80211 * |
| 899 | bcm43xx_current_80211_priv(struct bcm43xx_private *bcm) |
| 900 | { |
| 901 | assert(bcm->current_core->id == BCM43xx_COREID_80211); |
| 902 | return bcm->current_core->priv; |
| 903 | } |
| 904 | static inline |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 905 | struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm) |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 906 | { |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 907 | assert(bcm43xx_using_pio(bcm)); |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 908 | return &(bcm43xx_current_80211_priv(bcm)->pio); |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 909 | } |
| 910 | static inline |
| 911 | struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm) |
| 912 | { |
| 913 | assert(!bcm43xx_using_pio(bcm)); |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 914 | return &(bcm43xx_current_80211_priv(bcm)->dma); |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 915 | } |
| 916 | static inline |
| 917 | struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm) |
| 918 | { |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 919 | return &(bcm43xx_current_80211_priv(bcm)->phy); |
Michael Buesch | e9357c0 | 2006-03-13 19:27:34 +0100 | [diff] [blame] | 920 | } |
| 921 | static inline |
| 922 | struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) |
| 923 | { |
Michael Buesch | 58e5528 | 2006-07-08 22:02:18 +0200 | [diff] [blame] | 924 | return &(bcm43xx_current_80211_priv(bcm)->radio); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 925 | } |
| 926 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 927 | |
| 928 | static inline |
| 929 | struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, |
| 930 | u16 radio_attenuation, |
| 931 | u16 baseband_attenuation) |
| 932 | { |
| 933 | return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2)); |
| 934 | } |
| 935 | |
| 936 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 937 | static inline |
| 938 | u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset) |
| 939 | { |
Michael Buesch | 7ce942d | 2006-03-11 13:43:06 +0100 | [diff] [blame] | 940 | return ioread16(bcm->mmio_addr + core_offset(bcm) + offset); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 941 | } |
| 942 | |
| 943 | static inline |
| 944 | void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value) |
| 945 | { |
| 946 | iowrite16(value, bcm->mmio_addr + core_offset(bcm) + offset); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 947 | } |
| 948 | |
| 949 | static inline |
| 950 | u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset) |
| 951 | { |
Michael Buesch | 7ce942d | 2006-03-11 13:43:06 +0100 | [diff] [blame] | 952 | return ioread32(bcm->mmio_addr + core_offset(bcm) + offset); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 953 | } |
| 954 | |
| 955 | static inline |
| 956 | void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value) |
| 957 | { |
| 958 | iowrite32(value, bcm->mmio_addr + core_offset(bcm) + offset); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 959 | } |
| 960 | |
| 961 | static inline |
| 962 | int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value) |
| 963 | { |
Michael Buesch | 7ce942d | 2006-03-11 13:43:06 +0100 | [diff] [blame] | 964 | return pci_read_config_word(bcm->pci_dev, offset, value); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 965 | } |
| 966 | |
| 967 | static inline |
| 968 | int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value) |
| 969 | { |
Michael Buesch | 7ce942d | 2006-03-11 13:43:06 +0100 | [diff] [blame] | 970 | return pci_read_config_dword(bcm->pci_dev, offset, value); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 971 | } |
| 972 | |
| 973 | static inline |
| 974 | int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value) |
| 975 | { |
Michael Buesch | 7ce942d | 2006-03-11 13:43:06 +0100 | [diff] [blame] | 976 | return pci_write_config_word(bcm->pci_dev, offset, value); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 977 | } |
| 978 | |
| 979 | static inline |
| 980 | int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value) |
| 981 | { |
Michael Buesch | 7ce942d | 2006-03-11 13:43:06 +0100 | [diff] [blame] | 982 | return pci_write_config_dword(bcm->pci_dev, offset, value); |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 983 | } |
| 984 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 985 | /** Limit a value between two limits */ |
| 986 | #ifdef limit_value |
| 987 | # undef limit_value |
| 988 | #endif |
| 989 | #define limit_value(value, min, max) \ |
| 990 | ({ \ |
| 991 | typeof(value) __value = (value); \ |
| 992 | typeof(value) __min = (min); \ |
| 993 | typeof(value) __max = (max); \ |
| 994 | if (__value < __min) \ |
| 995 | __value = __min; \ |
| 996 | else if (__value > __max) \ |
| 997 | __value = __max; \ |
| 998 | __value; \ |
| 999 | }) |
| 1000 | |
Michael Buesch | f398f02 | 2006-02-23 21:15:39 +0100 | [diff] [blame] | 1001 | /** Helpers to print MAC addresses. */ |
| 1002 | #define BCM43xx_MACFMT "%02x:%02x:%02x:%02x:%02x:%02x" |
| 1003 | #define BCM43xx_MACARG(x) ((u8*)(x))[0], ((u8*)(x))[1], \ |
| 1004 | ((u8*)(x))[2], ((u8*)(x))[3], \ |
| 1005 | ((u8*)(x))[4], ((u8*)(x))[5] |
| 1006 | |
John W. Linville | f222313 | 2006-01-23 16:59:58 -0500 | [diff] [blame] | 1007 | #endif /* BCM43xx_H_ */ |