aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Buesch <mbuesch@freenet.de>2006-03-12 13:44:29 -0500
committerJohn W. Linville <linville@tuxdriver.com>2006-03-27 11:19:36 -0500
commit73733847beead47dc31b1f8e1532e5eea9f8ddd3 (patch)
tree6c1c9f05d1ca6a7053151e2104f7d825b26e4ffc /drivers
parent7ce942d0ff5df145831631f4df391c7207e676bb (diff)
[PATCH] bcm43xx: fix some stuff, add a few missing mmiowb(), remove dead code.
This may workaround the XMIT ERRORs some people are getting. Signed-off-by: Michael Buesch <mbuesch@freenet.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.h23
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.c42
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.h6
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c76
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c187
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c20
6 files changed, 167 insertions, 187 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
index cab8e2ba4c7e..c07e34689be1 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
@@ -9,27 +9,10 @@
9 9
10 10
11/* DMA-Interrupt reasons. */ 11/* DMA-Interrupt reasons. */
12/*TODO: add the missing ones. */ 12#define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
13#define BCM43xx_DMAIRQ_ERR0 (1 << 10) 13 | (1 << 14) | (1 << 15))
14#define BCM43xx_DMAIRQ_ERR1 (1 << 11) 14#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
15#define BCM43xx_DMAIRQ_ERR2 (1 << 12)
16#define BCM43xx_DMAIRQ_ERR3 (1 << 13)
17#define BCM43xx_DMAIRQ_ERR4 (1 << 14)
18#define BCM43xx_DMAIRQ_ERR5 (1 << 15)
19#define BCM43xx_DMAIRQ_RX_DONE (1 << 16) 15#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
20/* helpers */
21#define BCM43xx_DMAIRQ_ANYERR (BCM43xx_DMAIRQ_ERR0 | \
22 BCM43xx_DMAIRQ_ERR1 | \
23 BCM43xx_DMAIRQ_ERR2 | \
24 BCM43xx_DMAIRQ_ERR3 | \
25 BCM43xx_DMAIRQ_ERR4 | \
26 BCM43xx_DMAIRQ_ERR5)
27#define BCM43xx_DMAIRQ_FATALERR (BCM43xx_DMAIRQ_ERR0 | \
28 BCM43xx_DMAIRQ_ERR1 | \
29 BCM43xx_DMAIRQ_ERR2 | \
30 BCM43xx_DMAIRQ_ERR4 | \
31 BCM43xx_DMAIRQ_ERR5)
32#define BCM43xx_DMAIRQ_NONFATALERR BCM43xx_DMAIRQ_ERR3
33 16
34/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */ 17/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
35#define BCM43xx_DMA_TX_CONTROL 0x00 18#define BCM43xx_DMA_TX_CONTROL 0x00
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
index 22587e0e1a05..865ed5c33613 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
@@ -312,20 +312,22 @@ const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = {
312 312
313/**** Helper functions to access the device Internal Lookup Tables ****/ 313/**** Helper functions to access the device Internal Lookup Tables ****/
314 314
315void bcm43xx_ilt_write16(struct bcm43xx_private *bcm, u16 offset, u16 val) 315void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
316{ 316{
317 if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) { 317 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
318 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); 318 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
319 mmiowb();
319 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val); 320 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val);
320 } else { 321 } else {
321 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset); 322 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
323 mmiowb();
322 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val); 324 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val);
323 } 325 }
324} 326}
325 327
326u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset) 328u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
327{ 329{
328 if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) { 330 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
329 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); 331 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
330 return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1); 332 return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
331 } else { 333 } else {
@@ -333,35 +335,3 @@ u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset)
333 return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1); 335 return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
334 } 336 }
335} 337}
336
337void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val)
338{
339 if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) {
340 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
341 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA2, (u16)(val >> 16));
342 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, (u16)(val & 0x0000FFFF));
343 } else {
344 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
345 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA2, (u16)(val >> 16));
346 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, (u16)(val & 0x0000FFFF));
347 }
348}
349
350u32 bcm43xx_ilt_read32(struct bcm43xx_private *bcm, u16 offset)
351{
352 u32 ret;
353
354 if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) {
355 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
356 ret = bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA2);
357 ret <<= 16;
358 ret |= bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
359 } else {
360 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
361 ret = bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA2);
362 ret <<= 16;
363 ret |= bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
364 }
365
366 return ret;
367}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
index d92527fd83e9..464521abf73c 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
@@ -26,9 +26,7 @@ extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE];
26extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE]; 26extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
27 27
28 28
29void bcm43xx_ilt_write16(struct bcm43xx_private *bcm, u16 offset, u16 val); 29void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
30u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset); 30u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
31void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val);
32u32 bcm43xx_ilt_read32(struct bcm43xx_private *bcm, u16 offset);
33 31
34#endif /* BCM43xx_ILT_H_ */ 32#endif /* BCM43xx_ILT_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index f3cef345c8f9..a563258cad3d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -155,6 +155,7 @@ static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
155 val = swab32(val); 155 val = swab32(val);
156 156
157 bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset); 157 bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
158 mmiowb();
158 bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val); 159 bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
159} 160}
160 161
@@ -225,9 +226,12 @@ void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
225 if (offset & 0x0003) { 226 if (offset & 0x0003) {
226 /* Unaligned access */ 227 /* Unaligned access */
227 bcm43xx_shm_control_word(bcm, routing, offset >> 2); 228 bcm43xx_shm_control_word(bcm, routing, offset >> 2);
229 mmiowb();
228 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, 230 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
229 (value >> 16) & 0xffff); 231 (value >> 16) & 0xffff);
232 mmiowb();
230 bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1); 233 bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
234 mmiowb();
231 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, 235 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA,
232 value & 0xffff); 236 value & 0xffff);
233 return; 237 return;
@@ -235,6 +239,7 @@ void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
235 offset >>= 2; 239 offset >>= 2;
236 } 240 }
237 bcm43xx_shm_control_word(bcm, routing, offset); 241 bcm43xx_shm_control_word(bcm, routing, offset);
242 mmiowb();
238 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value); 243 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value);
239} 244}
240 245
@@ -246,6 +251,7 @@ void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
246 if (offset & 0x0003) { 251 if (offset & 0x0003) {
247 /* Unaligned access */ 252 /* Unaligned access */
248 bcm43xx_shm_control_word(bcm, routing, offset >> 2); 253 bcm43xx_shm_control_word(bcm, routing, offset >> 2);
254 mmiowb();
249 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, 255 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
250 value); 256 value);
251 return; 257 return;
@@ -253,6 +259,7 @@ void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
253 offset >>= 2; 259 offset >>= 2;
254 } 260 }
255 bcm43xx_shm_control_word(bcm, routing, offset); 261 bcm43xx_shm_control_word(bcm, routing, offset);
262 mmiowb();
256 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value); 263 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value);
257} 264}
258 265
@@ -311,6 +318,7 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
311 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); 318 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
312 status |= BCM43xx_SBF_TIME_UPDATE; 319 status |= BCM43xx_SBF_TIME_UPDATE;
313 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); 320 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
321 mmiowb();
314 322
315 /* Be careful with the in-progress timer. 323 /* Be careful with the in-progress timer.
316 * First zero out the low register, so we have a full 324 * First zero out the low register, so we have a full
@@ -320,9 +328,10 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
320 u32 lo = (tsf & 0x00000000FFFFFFFFULL); 328 u32 lo = (tsf & 0x00000000FFFFFFFFULL);
321 u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32; 329 u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
322 330
323 barrier();
324 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0); 331 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0);
332 mmiowb();
325 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi); 333 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi);
334 mmiowb();
326 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo); 335 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo);
327 } else { 336 } else {
328 u16 v0 = (tsf & 0x000000000000FFFFULL); 337 u16 v0 = (tsf & 0x000000000000FFFFULL);
@@ -330,11 +339,14 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
330 u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32; 339 u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
331 u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48; 340 u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
332 341
333 barrier();
334 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0); 342 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0);
343 mmiowb();
335 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3); 344 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3);
345 mmiowb();
336 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2); 346 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2);
347 mmiowb();
337 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1); 348 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1);
349 mmiowb();
338 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0); 350 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
339 } 351 }
340 352
@@ -974,6 +986,7 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
974void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm) 986void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
975{ 987{
976 struct bcm43xx_phyinfo *phy = bcm->current_core->phy; 988 struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
989 struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
977 unsigned int i, max_loop; 990 unsigned int i, max_loop;
978 u16 value = 0; 991 u16 value = 0;
979 u32 buffer[5] = { 992 u32 buffer[5] = {
@@ -984,6 +997,13 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
984 0x00000000, 997 0x00000000,
985 }; 998 };
986 999
1000/* FIXME: It seems like a dummy_transmission corrupts the DMA engines,
1001 * once they are initialized. So avoid doing a dummy_transmission,
1002 * if the DMA engines are running.
1003 */
1004if (bcm->initialized)
1005return;
1006
987 switch (phy->type) { 1007 switch (phy->type) {
988 case BCM43xx_PHYTYPE_A: 1008 case BCM43xx_PHYTYPE_A:
989 max_loop = 0x1E; 1009 max_loop = 0x1E;
@@ -1015,24 +1035,28 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
1015 bcm43xx_write16(bcm, 0x0500, 0x0000); 1035 bcm43xx_write16(bcm, 0x0500, 0x0000);
1016 bcm43xx_write16(bcm, 0x0502, 0x0030); 1036 bcm43xx_write16(bcm, 0x0502, 0x0030);
1017 1037
1038 if (radio->version == 0x2050 && radio->revision <= 0x5)
1039 bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
1018 for (i = 0x00; i < max_loop; i++) { 1040 for (i = 0x00; i < max_loop; i++) {
1019 value = bcm43xx_read16(bcm, 0x050E); 1041 value = bcm43xx_read16(bcm, 0x050E);
1020 if ((value & 0x0080) != 0) 1042 if (value & 0x0080)
1021 break; 1043 break;
1022 udelay(10); 1044 udelay(10);
1023 } 1045 }
1024 for (i = 0x00; i < 0x0A; i++) { 1046 for (i = 0x00; i < 0x0A; i++) {
1025 value = bcm43xx_read16(bcm, 0x050E); 1047 value = bcm43xx_read16(bcm, 0x050E);
1026 if ((value & 0x0400) != 0) 1048 if (value & 0x0400)
1027 break; 1049 break;
1028 udelay(10); 1050 udelay(10);
1029 } 1051 }
1030 for (i = 0x00; i < 0x0A; i++) { 1052 for (i = 0x00; i < 0x0A; i++) {
1031 value = bcm43xx_read16(bcm, 0x0690); 1053 value = bcm43xx_read16(bcm, 0x0690);
1032 if ((value & 0x0100) == 0) 1054 if (!(value & 0x0100))
1033 break; 1055 break;
1034 udelay(10); 1056 udelay(10);
1035 } 1057 }
1058 if (radio->version == 0x2050 && radio->revision <= 0x5)
1059 bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
1036} 1060}
1037 1061
1038static void key_write(struct bcm43xx_private *bcm, 1062static void key_write(struct bcm43xx_private *bcm,
@@ -1646,22 +1670,6 @@ static void handle_irq_beacon(struct bcm43xx_private *bcm)
1646 } 1670 }
1647} 1671}
1648 1672
1649/* Debug helper for irq bottom-half to print all reason registers. */
1650#define bcmirq_print_reasons(description) \
1651 do { \
1652 dprintkl(KERN_ERR PFX description "\n" \
1653 KERN_ERR PFX " Generic Reason: 0x%08x\n" \
1654 KERN_ERR PFX " DMA reasons: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n" \
1655 KERN_ERR PFX " DMA TX status: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", \
1656 reason, \
1657 dma_reason[0], dma_reason[1], \
1658 dma_reason[2], dma_reason[3], \
1659 bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_BASE + BCM43xx_DMA_TX_STATUS), \
1660 bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_BASE + BCM43xx_DMA_TX_STATUS), \
1661 bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_BASE + BCM43xx_DMA_TX_STATUS), \
1662 bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_BASE + BCM43xx_DMA_TX_STATUS)); \
1663 } while (0)
1664
1665/* Interrupt handler bottom-half */ 1673/* Interrupt handler bottom-half */
1666static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) 1674static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1667{ 1675{
@@ -1690,9 +1698,30 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1690 * on DMA or PIO queues. 1698 * on DMA or PIO queues.
1691 * Maybe we get this in other error conditions, too. 1699 * Maybe we get this in other error conditions, too.
1692 */ 1700 */
1693 bcmirq_print_reasons("XMIT ERROR"); 1701 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1694 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR); 1702 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1695 } 1703 }
1704 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
1705 (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
1706 (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
1707 (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
1708 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1709 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1710 dma_reason[0], dma_reason[1],
1711 dma_reason[2], dma_reason[3]);
1712 bcm43xx_controller_restart(bcm, "DMA error");
1713 bcm43xx_unlock_mmio(bcm, flags);
1714 return;
1715 }
1716 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
1717 (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
1718 (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
1719 (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
1720 printkl(KERN_ERR PFX "DMA error: "
1721 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1722 dma_reason[0], dma_reason[1],
1723 dma_reason[2], dma_reason[3]);
1724 }
1696 1725
1697 if (reason & BCM43xx_IRQ_PS) { 1726 if (reason & BCM43xx_IRQ_PS) {
1698 handle_irq_ps(bcm); 1727 handle_irq_ps(bcm);
@@ -1780,8 +1809,6 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1780 bcm43xx_unlock_mmio(bcm, flags); 1809 bcm43xx_unlock_mmio(bcm, flags);
1781} 1810}
1782 1811
1783#undef bcmirq_print_reasons
1784
1785static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, 1812static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm,
1786 u32 reason, u32 mask) 1813 u32 reason, u32 mask)
1787{ 1814{
@@ -3875,6 +3902,7 @@ failure:
3875void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) 3902void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
3876{ 3903{
3877 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 3904 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3905 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3878 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); 3906 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
3879 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); 3907 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
3880 schedule_work(&bcm->restart_work); 3908 schedule_work(&bcm->restart_work);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index d3c2fc1df375..dbbef6ccd153 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -126,6 +126,7 @@ u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset)
126void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val) 126void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
127{ 127{
128 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset); 128 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset);
129 mmiowb();
129 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_DATA, val); 130 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_DATA, val);
130} 131}
131 132
@@ -255,16 +256,16 @@ static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm)
255 if (phy->rev == 1) 256 if (phy->rev == 1)
256 offset = 0x4C00; 257 offset = 0x4C00;
257 258
258 bcm43xx_ilt_write16(bcm, offset, 0x00FE); 259 bcm43xx_ilt_write(bcm, offset, 0x00FE);
259 bcm43xx_ilt_write16(bcm, offset + 1, 0x000D); 260 bcm43xx_ilt_write(bcm, offset + 1, 0x000D);
260 bcm43xx_ilt_write16(bcm, offset + 2, 0x0013); 261 bcm43xx_ilt_write(bcm, offset + 2, 0x0013);
261 bcm43xx_ilt_write16(bcm, offset + 3, 0x0019); 262 bcm43xx_ilt_write(bcm, offset + 3, 0x0019);
262 263
263 if (phy->rev == 1) { 264 if (phy->rev == 1) {
264 bcm43xx_ilt_write16(bcm, 0x1800, 0x2710); 265 bcm43xx_ilt_write(bcm, 0x1800, 0x2710);
265 bcm43xx_ilt_write16(bcm, 0x1801, 0x9B83); 266 bcm43xx_ilt_write(bcm, 0x1801, 0x9B83);
266 bcm43xx_ilt_write16(bcm, 0x1802, 0x9B83); 267 bcm43xx_ilt_write(bcm, 0x1802, 0x9B83);
267 bcm43xx_ilt_write16(bcm, 0x1803, 0x0F8D); 268 bcm43xx_ilt_write(bcm, 0x1803, 0x0F8D);
268 bcm43xx_phy_write(bcm, 0x0455, 0x0004); 269 bcm43xx_phy_write(bcm, 0x0455, 0x0004);
269 } 270 }
270 271
@@ -317,10 +318,10 @@ static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm)
317 bcm43xx_phy_write(bcm, 0x048D, 0x0002); 318 bcm43xx_phy_write(bcm, 0x048D, 0x0002);
318 } 319 }
319 320
320 bcm43xx_ilt_write16(bcm, offset + 0x0800, 0); 321 bcm43xx_ilt_write(bcm, offset + 0x0800, 0);
321 bcm43xx_ilt_write16(bcm, offset + 0x0801, 7); 322 bcm43xx_ilt_write(bcm, offset + 0x0801, 7);
322 bcm43xx_ilt_write16(bcm, offset + 0x0802, 16); 323 bcm43xx_ilt_write(bcm, offset + 0x0802, 16);
323 bcm43xx_ilt_write16(bcm, offset + 0x0803, 28); 324 bcm43xx_ilt_write(bcm, offset + 0x0803, 28);
324} 325}
325 326
326static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) 327static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
@@ -337,11 +338,11 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
337 bcm43xx_phy_write(bcm, 0x0427, 0x001A); 338 bcm43xx_phy_write(bcm, 0x0427, 0x001A);
338 339
339 for (i = 0; i < BCM43xx_ILT_FINEFREQG_SIZE; i++) 340 for (i = 0; i < BCM43xx_ILT_FINEFREQG_SIZE; i++)
340 bcm43xx_ilt_write16(bcm, 0x5800 + i, bcm43xx_ilt_finefreqg[i]); 341 bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqg[i]);
341 for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++) 342 for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++)
342 bcm43xx_ilt_write16(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]); 343 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]);
343 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) 344 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
344 bcm43xx_ilt_write16(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); 345 bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
345 } else { 346 } else {
346 /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */ 347 /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */
347 bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654); 348 bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654);
@@ -357,36 +358,36 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
357 bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x800); 358 bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x800);
358 359
359 for (i = 0; i < 64; i++) 360 for (i = 0; i < 64; i++)
360 bcm43xx_ilt_write16(bcm, 0x4000 + i, i); 361 bcm43xx_ilt_write(bcm, 0x4000 + i, i);
361 for (i = 0; i < BCM43xx_ILT_NOISEG2_SIZE; i++) 362 for (i = 0; i < BCM43xx_ILT_NOISEG2_SIZE; i++)
362 bcm43xx_ilt_write16(bcm, 0x1800 + i, bcm43xx_ilt_noiseg2[i]); 363 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg2[i]);
363 } 364 }
364 365
365 if (phy->rev <= 2) 366 if (phy->rev <= 2)
366 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) 367 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
367 bcm43xx_ilt_write16(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]); 368 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]);
368 else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200)) 369 else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
369 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) 370 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
370 bcm43xx_ilt_write16(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]); 371 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]);
371 else 372 else
372 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) 373 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
373 bcm43xx_ilt_write16(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg2[i]); 374 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg2[i]);
374 375
375 if (phy->rev == 2) 376 if (phy->rev == 2)
376 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) 377 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
377 bcm43xx_ilt_write16(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); 378 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
378 else if ((phy->rev > 2) && (phy->rev <= 7)) 379 else if ((phy->rev > 2) && (phy->rev <= 7))
379 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) 380 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
380 bcm43xx_ilt_write16(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]); 381 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]);
381 382
382 if (phy->rev == 1) { 383 if (phy->rev == 1) {
383 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) 384 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
384 bcm43xx_ilt_write16(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); 385 bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
385 for (i = 0; i < 4; i++) { 386 for (i = 0; i < 4; i++) {
386 bcm43xx_ilt_write16(bcm, 0x5404 + i, 0x0020); 387 bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020);
387 bcm43xx_ilt_write16(bcm, 0x5408 + i, 0x0020); 388 bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020);
388 bcm43xx_ilt_write16(bcm, 0x540C + i, 0x0020); 389 bcm43xx_ilt_write(bcm, 0x540C + i, 0x0020);
389 bcm43xx_ilt_write16(bcm, 0x5410 + i, 0x0020); 390 bcm43xx_ilt_write(bcm, 0x5410 + i, 0x0020);
390 } 391 }
391 bcm43xx_phy_agcsetup(bcm); 392 bcm43xx_phy_agcsetup(bcm);
392 393
@@ -395,24 +396,24 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
395 (bcm->board_revision == 0x0017)) 396 (bcm->board_revision == 0x0017))
396 return; 397 return;
397 398
398 bcm43xx_ilt_write16(bcm, 0x5001, 0x0002); 399 bcm43xx_ilt_write(bcm, 0x5001, 0x0002);
399 bcm43xx_ilt_write16(bcm, 0x5002, 0x0001); 400 bcm43xx_ilt_write(bcm, 0x5002, 0x0001);
400 } else { 401 } else {
401 for (i = 0; i <= 0x2F; i++) 402 for (i = 0; i <= 0x2F; i++)
402 bcm43xx_ilt_write16(bcm, 0x1000 + i, 0x0820); 403 bcm43xx_ilt_write(bcm, 0x1000 + i, 0x0820);
403 bcm43xx_phy_agcsetup(bcm); 404 bcm43xx_phy_agcsetup(bcm);
404 bcm43xx_phy_read(bcm, 0x0400); /* dummy read */ 405 bcm43xx_phy_read(bcm, 0x0400); /* dummy read */
405 bcm43xx_phy_write(bcm, 0x0403, 0x1000); 406 bcm43xx_phy_write(bcm, 0x0403, 0x1000);
406 bcm43xx_ilt_write16(bcm, 0x3C02, 0x000F); 407 bcm43xx_ilt_write(bcm, 0x3C02, 0x000F);
407 bcm43xx_ilt_write16(bcm, 0x3C03, 0x0014); 408 bcm43xx_ilt_write(bcm, 0x3C03, 0x0014);
408 409
409 if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) && 410 if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) &&
410 (bcm->board_type == 0x0416) && 411 (bcm->board_type == 0x0416) &&
411 (bcm->board_revision == 0x0017)) 412 (bcm->board_revision == 0x0017))
412 return; 413 return;
413 414
414 bcm43xx_ilt_write16(bcm, 0x0401, 0x0002); 415 bcm43xx_ilt_write(bcm, 0x0401, 0x0002);
415 bcm43xx_ilt_write16(bcm, 0x0402, 0x0001); 416 bcm43xx_ilt_write(bcm, 0x0402, 0x0001);
416 } 417 }
417} 418}
418 419
@@ -456,11 +457,11 @@ static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm)
456 bcm43xx_phy_write(bcm, 0x0035, 0x03FF); 457 bcm43xx_phy_write(bcm, 0x0035, 0x03FF);
457 bcm43xx_phy_write(bcm, 0x0036, 0x0400); 458 bcm43xx_phy_write(bcm, 0x0036, 0x0400);
458 459
459 bcm43xx_ilt_write16(bcm, 0x3807, 0x0051); 460 bcm43xx_ilt_write(bcm, 0x3807, 0x0051);
460 461
461 bcm43xx_phy_write(bcm, 0x001C, 0x0FF9); 462 bcm43xx_phy_write(bcm, 0x001C, 0x0FF9);
462 bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F); 463 bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F);
463 bcm43xx_ilt_write16(bcm, 0x3C0C, 0x07BF); 464 bcm43xx_ilt_write(bcm, 0x3C0C, 0x07BF);
464 bcm43xx_radio_write16(bcm, 0x0002, 0x07BF); 465 bcm43xx_radio_write16(bcm, 0x0002, 0x07BF);
465 466
466 bcm43xx_phy_write(bcm, 0x0024, 0x4680); 467 bcm43xx_phy_write(bcm, 0x0024, 0x4680);
@@ -472,47 +473,47 @@ static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm)
472 bcm43xx_phy_write(bcm, 0x002B, bcm43xx_phy_read(bcm, 0x002B) & 0xFBFF); 473 bcm43xx_phy_write(bcm, 0x002B, bcm43xx_phy_read(bcm, 0x002B) & 0xFBFF);
473 bcm43xx_phy_write(bcm, 0x008E, 0x58C1); 474 bcm43xx_phy_write(bcm, 0x008E, 0x58C1);
474 475
475 bcm43xx_ilt_write16(bcm, 0x0803, 0x000F); 476 bcm43xx_ilt_write(bcm, 0x0803, 0x000F);
476 bcm43xx_ilt_write16(bcm, 0x0804, 0x001F); 477 bcm43xx_ilt_write(bcm, 0x0804, 0x001F);
477 bcm43xx_ilt_write16(bcm, 0x0805, 0x002A); 478 bcm43xx_ilt_write(bcm, 0x0805, 0x002A);
478 bcm43xx_ilt_write16(bcm, 0x0805, 0x0030); 479 bcm43xx_ilt_write(bcm, 0x0805, 0x0030);
479 bcm43xx_ilt_write16(bcm, 0x0807, 0x003A); 480 bcm43xx_ilt_write(bcm, 0x0807, 0x003A);
480 481
481 bcm43xx_ilt_write16(bcm, 0x0000, 0x0013); 482 bcm43xx_ilt_write(bcm, 0x0000, 0x0013);
482 bcm43xx_ilt_write16(bcm, 0x0001, 0x0013); 483 bcm43xx_ilt_write(bcm, 0x0001, 0x0013);
483 bcm43xx_ilt_write16(bcm, 0x0002, 0x0013); 484 bcm43xx_ilt_write(bcm, 0x0002, 0x0013);
484 bcm43xx_ilt_write16(bcm, 0x0003, 0x0013); 485 bcm43xx_ilt_write(bcm, 0x0003, 0x0013);
485 bcm43xx_ilt_write16(bcm, 0x0004, 0x0015); 486 bcm43xx_ilt_write(bcm, 0x0004, 0x0015);
486 bcm43xx_ilt_write16(bcm, 0x0005, 0x0015); 487 bcm43xx_ilt_write(bcm, 0x0005, 0x0015);
487 bcm43xx_ilt_write16(bcm, 0x0006, 0x0019); 488 bcm43xx_ilt_write(bcm, 0x0006, 0x0019);
488 489
489 bcm43xx_ilt_write16(bcm, 0x0404, 0x0003); 490 bcm43xx_ilt_write(bcm, 0x0404, 0x0003);
490 bcm43xx_ilt_write16(bcm, 0x0405, 0x0003); 491 bcm43xx_ilt_write(bcm, 0x0405, 0x0003);
491 bcm43xx_ilt_write16(bcm, 0x0406, 0x0007); 492 bcm43xx_ilt_write(bcm, 0x0406, 0x0007);
492 493
493 for (i = 0; i < 16; i++) 494 for (i = 0; i < 16; i++)
494 bcm43xx_ilt_write16(bcm, 0x4000 + i, (0x8 + i) & 0x000F); 495 bcm43xx_ilt_write(bcm, 0x4000 + i, (0x8 + i) & 0x000F);
495 496
496 bcm43xx_ilt_write16(bcm, 0x3003, 0x1044); 497 bcm43xx_ilt_write(bcm, 0x3003, 0x1044);
497 bcm43xx_ilt_write16(bcm, 0x3004, 0x7201); 498 bcm43xx_ilt_write(bcm, 0x3004, 0x7201);
498 bcm43xx_ilt_write16(bcm, 0x3006, 0x0040); 499 bcm43xx_ilt_write(bcm, 0x3006, 0x0040);
499 bcm43xx_ilt_write16(bcm, 0x3001, (bcm43xx_ilt_read16(bcm, 0x3001) & 0x0010) | 0x0008); 500 bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008);
500 501
501 for (i = 0; i < BCM43xx_ILT_FINEFREQA_SIZE; i++) 502 for (i = 0; i < BCM43xx_ILT_FINEFREQA_SIZE; i++)
502 bcm43xx_ilt_write16(bcm, 0x5800 + i, bcm43xx_ilt_finefreqa[i]); 503 bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqa[i]);
503 for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++) 504 for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++)
504 bcm43xx_ilt_write16(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]); 505 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]);
505 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) 506 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
506 bcm43xx_ilt_write16(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); 507 bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
507 bcm43xx_phy_init_noisescaletbl(bcm); 508 bcm43xx_phy_init_noisescaletbl(bcm);
508 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) 509 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
509 bcm43xx_ilt_write16(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); 510 bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
510 break; 511 break;
511 case 3: 512 case 3:
512 for (i = 0; i < 64; i++) 513 for (i = 0; i < 64; i++)
513 bcm43xx_ilt_write16(bcm, 0x4000 + i, i); 514 bcm43xx_ilt_write(bcm, 0x4000 + i, i);
514 515
515 bcm43xx_ilt_write16(bcm, 0x3807, 0x0051); 516 bcm43xx_ilt_write(bcm, 0x3807, 0x0051);
516 517
517 bcm43xx_phy_write(bcm, 0x001C, 0x0FF9); 518 bcm43xx_phy_write(bcm, 0x001C, 0x0FF9);
518 bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F); 519 bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F);
@@ -524,35 +525,35 @@ static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm)
524 bcm43xx_phy_write(bcm, 0x001F, 0x1C00); 525 bcm43xx_phy_write(bcm, 0x001F, 0x1C00);
525 bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400); 526 bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400);
526 527
527 bcm43xx_ilt_write16(bcm, 0x3001, (bcm43xx_ilt_read16(bcm, 0x3001) & 0x0010) | 0x0008); 528 bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008);
528 for (i = 0; i < BCM43xx_ILT_NOISEA3_SIZE; i++) 529 for (i = 0; i < BCM43xx_ILT_NOISEA3_SIZE; i++)
529 bcm43xx_ilt_write16(bcm, 0x1800 + i, bcm43xx_ilt_noisea3[i]); 530 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea3[i]);
530 bcm43xx_phy_init_noisescaletbl(bcm); 531 bcm43xx_phy_init_noisescaletbl(bcm);
531 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) 532 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
532 bcm43xx_ilt_write16(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); 533 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
533 534
534 bcm43xx_phy_write(bcm, 0x0003, 0x1808); 535 bcm43xx_phy_write(bcm, 0x0003, 0x1808);
535 536
536 bcm43xx_ilt_write16(bcm, 0x0803, 0x000F); 537 bcm43xx_ilt_write(bcm, 0x0803, 0x000F);
537 bcm43xx_ilt_write16(bcm, 0x0804, 0x001F); 538 bcm43xx_ilt_write(bcm, 0x0804, 0x001F);
538 bcm43xx_ilt_write16(bcm, 0x0805, 0x002A); 539 bcm43xx_ilt_write(bcm, 0x0805, 0x002A);
539 bcm43xx_ilt_write16(bcm, 0x0805, 0x0030); 540 bcm43xx_ilt_write(bcm, 0x0805, 0x0030);
540 bcm43xx_ilt_write16(bcm, 0x0807, 0x003A); 541 bcm43xx_ilt_write(bcm, 0x0807, 0x003A);
541 542
542 bcm43xx_ilt_write16(bcm, 0x0000, 0x0013); 543 bcm43xx_ilt_write(bcm, 0x0000, 0x0013);
543 bcm43xx_ilt_write16(bcm, 0x0001, 0x0013); 544 bcm43xx_ilt_write(bcm, 0x0001, 0x0013);
544 bcm43xx_ilt_write16(bcm, 0x0002, 0x0013); 545 bcm43xx_ilt_write(bcm, 0x0002, 0x0013);
545 bcm43xx_ilt_write16(bcm, 0x0003, 0x0013); 546 bcm43xx_ilt_write(bcm, 0x0003, 0x0013);
546 bcm43xx_ilt_write16(bcm, 0x0004, 0x0015); 547 bcm43xx_ilt_write(bcm, 0x0004, 0x0015);
547 bcm43xx_ilt_write16(bcm, 0x0005, 0x0015); 548 bcm43xx_ilt_write(bcm, 0x0005, 0x0015);
548 bcm43xx_ilt_write16(bcm, 0x0006, 0x0019); 549 bcm43xx_ilt_write(bcm, 0x0006, 0x0019);
549 550
550 bcm43xx_ilt_write16(bcm, 0x0404, 0x0003); 551 bcm43xx_ilt_write(bcm, 0x0404, 0x0003);
551 bcm43xx_ilt_write16(bcm, 0x0405, 0x0003); 552 bcm43xx_ilt_write(bcm, 0x0405, 0x0003);
552 bcm43xx_ilt_write16(bcm, 0x0406, 0x0007); 553 bcm43xx_ilt_write(bcm, 0x0406, 0x0007);
553 554
554 bcm43xx_ilt_write16(bcm, 0x3C02, 0x000F); 555 bcm43xx_ilt_write(bcm, 0x3C02, 0x000F);
555 bcm43xx_ilt_write16(bcm, 0x3C03, 0x0014); 556 bcm43xx_ilt_write(bcm, 0x3C03, 0x0014);
556 break; 557 break;
557 default: 558 default:
558 assert(0); 559 assert(0);
@@ -598,19 +599,19 @@ static void bcm43xx_phy_inita(struct bcm43xx_private *bcm)
598 bcm43xx_radio_write16(bcm, 0x0019, 0x0000); 599 bcm43xx_radio_write16(bcm, 0x0019, 0x0000);
599 bcm43xx_radio_write16(bcm, 0x0017, 0x0020); 600 bcm43xx_radio_write16(bcm, 0x0017, 0x0020);
600 601
601 tval = bcm43xx_ilt_read16(bcm, 0x3001); 602 tval = bcm43xx_ilt_read(bcm, 0x3001);
602 if (phy->rev == 1) { 603 if (phy->rev == 1) {
603 bcm43xx_ilt_write16(bcm, 0x3001, 604 bcm43xx_ilt_write(bcm, 0x3001,
604 (bcm43xx_ilt_read16(bcm, 0x3001) & 0xFF87) 605 (bcm43xx_ilt_read(bcm, 0x3001) & 0xFF87)
605 | 0x0058); 606 | 0x0058);
606 } else { 607 } else {
607 bcm43xx_ilt_write16(bcm, 0x3001, 608 bcm43xx_ilt_write(bcm, 0x3001,
608 (bcm43xx_ilt_read16(bcm, 0x3001) & 0xFFC3) 609 (bcm43xx_ilt_read(bcm, 0x3001) & 0xFFC3)
609 | 0x002C); 610 | 0x002C);
610 } 611 }
611 bcm43xx_dummy_transmission(bcm); 612 bcm43xx_dummy_transmission(bcm);
612 phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_A_PCTL); 613 phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_A_PCTL);
613 bcm43xx_ilt_write16(bcm, 0x3001, tval); 614 bcm43xx_ilt_write(bcm, 0x3001, tval);
614 615
615 bcm43xx_radio_set_txpower_a(bcm, 0x0018); 616 bcm43xx_radio_set_txpower_a(bcm, 0x0018);
616 } 617 }
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index 3901aa994666..4d3b0e85876c 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -97,6 +97,7 @@ void bcm43xx_radio_lock(struct bcm43xx_private *bcm)
97 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); 97 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
98 status |= BCM43xx_SBF_RADIOREG_LOCK; 98 status |= BCM43xx_SBF_RADIOREG_LOCK;
99 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); 99 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
100 mmiowb();
100 udelay(10); 101 udelay(10);
101} 102}
102 103
@@ -108,6 +109,7 @@ void bcm43xx_radio_unlock(struct bcm43xx_private *bcm)
108 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); 109 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
109 status &= ~BCM43xx_SBF_RADIOREG_LOCK; 110 status &= ~BCM43xx_SBF_RADIOREG_LOCK;
110 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); 111 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
112 mmiowb();
111} 113}
112 114
113u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset) 115u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset)
@@ -142,6 +144,7 @@ u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset)
142void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val) 144void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val)
143{ 145{
144 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset); 146 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset);
147 mmiowb();
145 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val); 148 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val);
146} 149}
147 150
@@ -161,10 +164,10 @@ static void bcm43xx_set_all_gains(struct bcm43xx_private *bcm,
161 } 164 }
162 165
163 for (i = 0; i < 4; i++) 166 for (i = 0; i < 4; i++)
164 bcm43xx_ilt_write16(bcm, offset + i, first); 167 bcm43xx_ilt_write(bcm, offset + i, first);
165 168
166 for (i = start; i < end; i++) 169 for (i = start; i < end; i++)
167 bcm43xx_ilt_write16(bcm, offset + i, second); 170 bcm43xx_ilt_write(bcm, offset + i, second);
168 171
169 if (third != -1) { 172 if (third != -1) {
170 tmp = ((u16)third << 14) | ((u16)third << 6); 173 tmp = ((u16)third << 14) | ((u16)third << 6);
@@ -196,11 +199,11 @@ static void bcm43xx_set_original_gains(struct bcm43xx_private *bcm)
196 tmp |= (i & 0x0001) << 1; 199 tmp |= (i & 0x0001) << 1;
197 tmp |= (i & 0x0002) >> 1; 200 tmp |= (i & 0x0002) >> 1;
198 201
199 bcm43xx_ilt_write16(bcm, offset + i, tmp); 202 bcm43xx_ilt_write(bcm, offset + i, tmp);
200 } 203 }
201 204
202 for (i = start; i < end; i++) 205 for (i = start; i < end; i++)
203 bcm43xx_ilt_write16(bcm, offset + i, i - start); 206 bcm43xx_ilt_write(bcm, offset + i, i - start);
204 207
205 bcm43xx_phy_write(bcm, 0x04A0, 208 bcm43xx_phy_write(bcm, 0x04A0,
206 (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040); 209 (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040);
@@ -316,6 +319,7 @@ u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm)
316void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val) 319void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val)
317{ 320{
318 bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset); 321 bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset);
322 mmiowb();
319 bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val); 323 bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val);
320} 324}
321 325
@@ -612,10 +616,6 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
612 } 616 }
613 break; 617 break;
614 case BCM43xx_PHYTYPE_G: 618 case BCM43xx_PHYTYPE_G:
615//FIXME: Something is broken here. This is called when enabling WLAN interfmode.
616// If this is done at runtime, I get an XMIT ERROR and transmission is
617// broken. I guess some important register is overwritten by accident.
618// The XMIT ERROR comes from the dummy_transmissions in set_gains.
619 if (radio->revision >= 9) 619 if (radio->revision >= 9)
620 return; 620 return;
621 if (radio->revision == 8) 621 if (radio->revision == 8)
@@ -1641,14 +1641,14 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower)
1641 base &= 0x000F; 1641 base &= 0x000F;
1642 bcm43xx_phy_write(bcm, 0x0017, base | 0x0020); 1642 bcm43xx_phy_write(bcm, 0x0017, base | 0x0020);
1643 1643
1644 ilt = bcm43xx_ilt_read16(bcm, 0x3001); 1644 ilt = bcm43xx_ilt_read(bcm, 0x3001);
1645 ilt &= 0x0007; 1645 ilt &= 0x0007;
1646 1646
1647 dac = bcm43xx_get_txgain_dac(txpower); 1647 dac = bcm43xx_get_txgain_dac(txpower);
1648 dac <<= 3; 1648 dac <<= 3;
1649 dac |= ilt; 1649 dac |= ilt;
1650 1650
1651 bcm43xx_ilt_write16(bcm, 0x3001, dac); 1651 bcm43xx_ilt_write(bcm, 0x3001, dac);
1652 1652
1653 bcm->current_core->radio->txpower[0] = txpower; 1653 bcm->current_core->radio->txpower[0] = txpower;
1654 1654