1 Index: linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_main.c
2 ===================================================================
3 --- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
4 +++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_main.c
5 @@ -130,6 +130,10 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for
6 { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
7 /* Broadcom 4307 802.11b */
8 { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
9 + /* Broadcom 4311 802.11(a)/b/g */
10 + { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11 + /* Broadcom 4312 802.11a/b/g */
12 + { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13 /* Broadcom 4318 802.11b/g */
14 { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15 /* Broadcom 4319 802.11a/b/g */
16 @@ -2582,8 +2586,9 @@ static int bcm43xx_probe_cores(struct bc
17 /* fetch sb_id_hi from core information registers */
18 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
20 - core_id = (sb_id_hi & 0xFFF0) >> 4;
21 - core_rev = (sb_id_hi & 0xF);
22 + core_id = (sb_id_hi & 0x8FF0) >> 4;
23 + core_rev = (sb_id_hi & 0x7000) >> 8;
24 + core_rev |= (sb_id_hi & 0xF);
25 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
27 /* if present, chipcommon is always core 0; read the chipid from it */
28 @@ -2693,6 +2698,7 @@ static int bcm43xx_probe_cores(struct bc
31 case BCM43xx_COREID_PCI:
32 + case BCM43xx_COREID_PCIE:
33 core = &bcm->core_pci;
34 if (core->available) {
35 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
36 @@ -2731,12 +2737,12 @@ static int bcm43xx_probe_cores(struct bc
43 - printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
44 + printk(KERN_WARNING PFX
45 + "Unsupported 80211 core revision %u\n",
50 bcm->nr_80211_available++;
51 core->priv = ext_80211;
52 @@ -2850,16 +2856,11 @@ static int bcm43xx_wireless_core_init(st
56 - if (bcm->chip_rev < 5) {
57 + if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) {
58 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
59 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
60 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
61 - if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
62 - sbimconfiglow |= 0x32;
63 - else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
64 - sbimconfiglow |= 0x53;
67 + sbimconfiglow |= 0x32;
68 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
71 @@ -2983,22 +2987,64 @@ static void bcm43xx_pcicore_broadcast_va
73 static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
76 - struct bcm43xx_coreinfo *old_core;
79 - old_core = bcm->current_core;
80 - err = bcm43xx_switch_core(bcm, &bcm->core_pci);
83 + bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
85 - bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
86 + if (bcm->core_chipcommon.available) {
87 + err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
91 + bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
93 + /* this function is always called when a PCI core is mapped */
94 + err = bcm43xx_switch_core(bcm, &bcm->core_pci);
98 + bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
100 + bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
102 - bcm43xx_switch_core(bcm, old_core);
108 +static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address)
110 + bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
111 + return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA);
114 +static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address,
117 + bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
118 + bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data);
121 +static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg,
126 + bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082);
127 + bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST |
128 + BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) |
129 + (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA |
133 + for (i = 0; i < 10; i++) {
134 + if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
135 + BCM43xx_PCIE_MDIO_TC)
139 + bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0);
142 /* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
143 * To enable core 0, pass a core_mask of 1<<0
145 @@ -3018,7 +3064,8 @@ static int bcm43xx_setup_backplane_pci_c
149 - if (bcm->core_pci.rev < 6) {
150 + if (bcm->current_core->rev < 6 ||
151 + bcm->current_core->id == BCM43xx_COREID_PCI) {
152 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
153 value |= (1 << backplane_flag_nr);
154 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
155 @@ -3036,21 +3083,46 @@ static int bcm43xx_setup_backplane_pci_c
159 - value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
160 - value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
161 - bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
163 - if (bcm->core_pci.rev < 5) {
164 - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
165 - value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
166 - & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
167 - value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
168 - & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
169 - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
170 - err = bcm43xx_pcicore_commit_settings(bcm);
172 + if (bcm->current_core->id == BCM43xx_COREID_PCI) {
173 + value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
174 + value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
175 + bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
177 + if (bcm->current_core->rev < 5) {
178 + value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
179 + value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
180 + & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
181 + value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
182 + & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
183 + bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
184 + err = bcm43xx_pcicore_commit_settings(bcm);
186 + } else if (bcm->current_core->rev >= 11) {
187 + value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
188 + value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI;
189 + bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
192 + if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) {
193 + value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND);
195 + bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND,
198 + if (bcm->current_core->rev == 0) {
199 + bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
200 + BCM43xx_SERDES_RXTIMER, 0x8128);
201 + bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
202 + BCM43xx_SERDES_CDR, 0x0100);
203 + bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
204 + BCM43xx_SERDES_CDR_BW, 0x1466);
205 + } else if (bcm->current_core->rev == 1) {
206 + value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL);
208 + bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL,
214 err = bcm43xx_switch_core(bcm, old_core);
216 @@ -3635,7 +3707,7 @@ static int bcm43xx_read_phyinfo(struct b
217 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
219 case BCM43xx_PHYTYPE_G:
223 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
224 IEEE80211_CCK_MODULATION;
225 Index: linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx.h
226 ===================================================================
227 --- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
228 +++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx.h
231 /* Chipcommon registers. */
232 #define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
233 +#define BCM43xx_CHIPCOMMON_CTL 0x28
234 #define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
235 #define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
236 #define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
238 /* SBTOPCI2 values. */
239 #define BCM43xx_SBTOPCI2_PREFETCH 0x4
240 #define BCM43xx_SBTOPCI2_BURST 0x8
241 +#define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20
243 +/* PCI-E core registers. */
244 +#define BCM43xx_PCIECORE_REG_ADDR 0x0130
245 +#define BCM43xx_PCIECORE_REG_DATA 0x0134
246 +#define BCM43xx_PCIECORE_MDIO_CTL 0x0128
247 +#define BCM43xx_PCIECORE_MDIO_DATA 0x012C
249 +/* PCI-E registers. */
250 +#define BCM43xx_PCIE_TLP_WORKAROUND 0x0004
251 +#define BCM43xx_PCIE_DLLP_LINKCTL 0x0100
253 +/* PCI-E MDIO bits. */
254 +#define BCM43xx_PCIE_MDIO_ST 0x40000000
255 +#define BCM43xx_PCIE_MDIO_WT 0x10000000
256 +#define BCM43xx_PCIE_MDIO_DEV 22
257 +#define BCM43xx_PCIE_MDIO_REG 18
258 +#define BCM43xx_PCIE_MDIO_TA 0x00020000
259 +#define BCM43xx_PCIE_MDIO_TC 0x0100
262 +#define BCM43xx_MDIO_SERDES_RX 0x1F
264 +/* SERDES RX registers. */
265 +#define BCM43xx_SERDES_RXTIMER 0x2
266 +#define BCM43xx_SERDES_CDR 0x6
267 +#define BCM43xx_SERDES_CDR_BW 0x7
269 /* Chipcommon capabilities. */
270 #define BCM43xx_CAPABILITIES_PCTL 0x00040000
272 #define BCM43xx_COREID_USB20_HOST 0x819
273 #define BCM43xx_COREID_USB20_DEV 0x81a
274 #define BCM43xx_COREID_SDIO_HOST 0x81b
275 +#define BCM43xx_COREID_PCIE 0x820
277 /* Core Information Registers */
278 #define BCM43xx_CIR_BASE 0xf00
279 Index: linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_power.c
280 ===================================================================
281 --- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_power.c
282 +++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_power.c
283 @@ -153,8 +153,6 @@ int bcm43xx_pctl_init(struct bcm43xx_pri
285 struct bcm43xx_coreinfo *old_core;
287 - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
289 old_core = bcm->current_core;
290 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
292 @@ -162,11 +160,27 @@ int bcm43xx_pctl_init(struct bcm43xx_pri
296 - maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
297 - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
298 - (maxfreq * 150 + 999999) / 1000000);
299 - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY,
300 - (maxfreq * 15 + 999999) / 1000000);
301 + if (bcm->chip_id == 0x4321) {
302 + if (bcm->chip_rev == 0)
303 + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4);
304 + if (bcm->chip_rev == 1)
305 + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4);
308 + if (bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) {
309 + if (bcm->current_core->rev >= 10) {
310 + /* Set Idle Power clock rate to 1Mhz */
311 + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL,
312 + (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL)
313 + & 0x0000FFFF) | 0x40000);
315 + maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
316 + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
317 + (maxfreq * 150 + 999999) / 1000000);
318 + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY,
319 + (maxfreq * 15 + 999999) / 1000000);
323 err = bcm43xx_switch_core(bcm, old_core);