Commit 73733847 authored by Michael Buesch's avatar Michael Buesch Committed by John W. Linville

[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: default avatarMichael Buesch <mbuesch@freenet.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7ce942d0
...@@ -9,27 +9,10 @@ ...@@ -9,27 +9,10 @@
/* DMA-Interrupt reasons. */ /* DMA-Interrupt reasons. */
/*TODO: add the missing ones. */ #define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
#define BCM43xx_DMAIRQ_ERR0 (1 << 10) | (1 << 14) | (1 << 15))
#define BCM43xx_DMAIRQ_ERR1 (1 << 11) #define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
#define BCM43xx_DMAIRQ_ERR2 (1 << 12)
#define BCM43xx_DMAIRQ_ERR3 (1 << 13)
#define BCM43xx_DMAIRQ_ERR4 (1 << 14)
#define BCM43xx_DMAIRQ_ERR5 (1 << 15)
#define BCM43xx_DMAIRQ_RX_DONE (1 << 16) #define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
/* helpers */
#define BCM43xx_DMAIRQ_ANYERR (BCM43xx_DMAIRQ_ERR0 | \
BCM43xx_DMAIRQ_ERR1 | \
BCM43xx_DMAIRQ_ERR2 | \
BCM43xx_DMAIRQ_ERR3 | \
BCM43xx_DMAIRQ_ERR4 | \
BCM43xx_DMAIRQ_ERR5)
#define BCM43xx_DMAIRQ_FATALERR (BCM43xx_DMAIRQ_ERR0 | \
BCM43xx_DMAIRQ_ERR1 | \
BCM43xx_DMAIRQ_ERR2 | \
BCM43xx_DMAIRQ_ERR4 | \
BCM43xx_DMAIRQ_ERR5)
#define BCM43xx_DMAIRQ_NONFATALERR BCM43xx_DMAIRQ_ERR3
/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */ /* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
#define BCM43xx_DMA_TX_CONTROL 0x00 #define BCM43xx_DMA_TX_CONTROL 0x00
......
...@@ -312,20 +312,22 @@ const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = { ...@@ -312,20 +312,22 @@ const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = {
/**** Helper functions to access the device Internal Lookup Tables ****/ /**** Helper functions to access the device Internal Lookup Tables ****/
void bcm43xx_ilt_write16(struct bcm43xx_private *bcm, u16 offset, u16 val) void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
{ {
if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) { if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
mmiowb();
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val); bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val);
} else { } else {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset); bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
mmiowb();
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val); bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val);
} }
} }
u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset) u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
{ {
if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) { if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1); return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
} else { } else {
...@@ -333,35 +335,3 @@ u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset) ...@@ -333,35 +335,3 @@ u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset)
return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1); return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
} }
} }
void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val)
{
if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA2, (u16)(val >> 16));
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, (u16)(val & 0x0000FFFF));
} else {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA2, (u16)(val >> 16));
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, (u16)(val & 0x0000FFFF));
}
}
u32 bcm43xx_ilt_read32(struct bcm43xx_private *bcm, u16 offset)
{
u32 ret;
if ( bcm->current_core->phy->type == BCM43xx_PHYTYPE_A ) {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
ret = bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA2);
ret <<= 16;
ret |= bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
} else {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
ret = bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA2);
ret <<= 16;
ret |= bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
}
return ret;
}
...@@ -26,9 +26,7 @@ extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE]; ...@@ -26,9 +26,7 @@ extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE];
extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE]; extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
void bcm43xx_ilt_write16(struct bcm43xx_private *bcm, u16 offset, u16 val); void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset); u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val);
u32 bcm43xx_ilt_read32(struct bcm43xx_private *bcm, u16 offset);
#endif /* BCM43xx_ILT_H_ */ #endif /* BCM43xx_ILT_H_ */
...@@ -155,6 +155,7 @@ static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val) ...@@ -155,6 +155,7 @@ static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
val = swab32(val); val = swab32(val);
bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset); bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
mmiowb();
bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val); bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
} }
...@@ -225,9 +226,12 @@ void bcm43xx_shm_write32(struct bcm43xx_private *bcm, ...@@ -225,9 +226,12 @@ void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
if (offset & 0x0003) { if (offset & 0x0003) {
/* Unaligned access */ /* Unaligned access */
bcm43xx_shm_control_word(bcm, routing, offset >> 2); bcm43xx_shm_control_word(bcm, routing, offset >> 2);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
(value >> 16) & 0xffff); (value >> 16) & 0xffff);
mmiowb();
bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1); bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA,
value & 0xffff); value & 0xffff);
return; return;
...@@ -235,6 +239,7 @@ void bcm43xx_shm_write32(struct bcm43xx_private *bcm, ...@@ -235,6 +239,7 @@ void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
offset >>= 2; offset >>= 2;
} }
bcm43xx_shm_control_word(bcm, routing, offset); bcm43xx_shm_control_word(bcm, routing, offset);
mmiowb();
bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value); bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value);
} }
...@@ -246,6 +251,7 @@ void bcm43xx_shm_write16(struct bcm43xx_private *bcm, ...@@ -246,6 +251,7 @@ void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
if (offset & 0x0003) { if (offset & 0x0003) {
/* Unaligned access */ /* Unaligned access */
bcm43xx_shm_control_word(bcm, routing, offset >> 2); bcm43xx_shm_control_word(bcm, routing, offset >> 2);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
value); value);
return; return;
...@@ -253,6 +259,7 @@ void bcm43xx_shm_write16(struct bcm43xx_private *bcm, ...@@ -253,6 +259,7 @@ void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
offset >>= 2; offset >>= 2;
} }
bcm43xx_shm_control_word(bcm, routing, offset); bcm43xx_shm_control_word(bcm, routing, offset);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value); bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value);
} }
...@@ -311,6 +318,7 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf) ...@@ -311,6 +318,7 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
status |= BCM43xx_SBF_TIME_UPDATE; status |= BCM43xx_SBF_TIME_UPDATE;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
mmiowb();
/* Be careful with the in-progress timer. /* Be careful with the in-progress timer.
* First zero out the low register, so we have a full * 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,9 +328,10 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
u32 lo = (tsf & 0x00000000FFFFFFFFULL); u32 lo = (tsf & 0x00000000FFFFFFFFULL);
u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32; u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
barrier();
bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0); bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0);
mmiowb();
bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi); bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi);
mmiowb();
bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo); bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo);
} else { } else {
u16 v0 = (tsf & 0x000000000000FFFFULL); u16 v0 = (tsf & 0x000000000000FFFFULL);
...@@ -330,11 +339,14 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf) ...@@ -330,11 +339,14 @@ void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32; u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48; u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
barrier();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0); bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3); bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2); bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1); bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0); bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
} }
...@@ -974,6 +986,7 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm) ...@@ -974,6 +986,7 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm) void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
{ {
struct bcm43xx_phyinfo *phy = bcm->current_core->phy; struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
unsigned int i, max_loop; unsigned int i, max_loop;
u16 value = 0; u16 value = 0;
u32 buffer[5] = { u32 buffer[5] = {
...@@ -984,6 +997,13 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm) ...@@ -984,6 +997,13 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
0x00000000, 0x00000000,
}; };
/* FIXME: It seems like a dummy_transmission corrupts the DMA engines,
* once they are initialized. So avoid doing a dummy_transmission,
* if the DMA engines are running.
*/
if (bcm->initialized)
return;
switch (phy->type) { switch (phy->type) {
case BCM43xx_PHYTYPE_A: case BCM43xx_PHYTYPE_A:
max_loop = 0x1E; max_loop = 0x1E;
...@@ -1015,24 +1035,28 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm) ...@@ -1015,24 +1035,28 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
bcm43xx_write16(bcm, 0x0500, 0x0000); bcm43xx_write16(bcm, 0x0500, 0x0000);
bcm43xx_write16(bcm, 0x0502, 0x0030); bcm43xx_write16(bcm, 0x0502, 0x0030);
if (radio->version == 0x2050 && radio->revision <= 0x5)
bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
for (i = 0x00; i < max_loop; i++) { for (i = 0x00; i < max_loop; i++) {
value = bcm43xx_read16(bcm, 0x050E); value = bcm43xx_read16(bcm, 0x050E);
if ((value & 0x0080) != 0) if (value & 0x0080)
break; break;
udelay(10); udelay(10);
} }
for (i = 0x00; i < 0x0A; i++) { for (i = 0x00; i < 0x0A; i++) {
value = bcm43xx_read16(bcm, 0x050E); value = bcm43xx_read16(bcm, 0x050E);
if ((value & 0x0400) != 0) if (value & 0x0400)
break; break;
udelay(10); udelay(10);
} }
for (i = 0x00; i < 0x0A; i++) { for (i = 0x00; i < 0x0A; i++) {
value = bcm43xx_read16(bcm, 0x0690); value = bcm43xx_read16(bcm, 0x0690);
if ((value & 0x0100) == 0) if (!(value & 0x0100))
break; break;
udelay(10); udelay(10);
} }
if (radio->version == 0x2050 && radio->revision <= 0x5)
bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
} }
static void key_write(struct bcm43xx_private *bcm, static void key_write(struct bcm43xx_private *bcm,
...@@ -1646,22 +1670,6 @@ static void handle_irq_beacon(struct bcm43xx_private *bcm) ...@@ -1646,22 +1670,6 @@ static void handle_irq_beacon(struct bcm43xx_private *bcm)
} }
} }
/* Debug helper for irq bottom-half to print all reason registers. */
#define bcmirq_print_reasons(description) \
do { \
dprintkl(KERN_ERR PFX description "\n" \
KERN_ERR PFX " Generic Reason: 0x%08x\n" \
KERN_ERR PFX " DMA reasons: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n" \
KERN_ERR PFX " DMA TX status: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", \
reason, \
dma_reason[0], dma_reason[1], \
dma_reason[2], dma_reason[3], \
bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_BASE + BCM43xx_DMA_TX_STATUS), \
bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_BASE + BCM43xx_DMA_TX_STATUS), \
bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_BASE + BCM43xx_DMA_TX_STATUS), \
bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_BASE + BCM43xx_DMA_TX_STATUS)); \
} while (0)
/* Interrupt handler bottom-half */ /* Interrupt handler bottom-half */
static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
{ {
...@@ -1690,9 +1698,30 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) ...@@ -1690,9 +1698,30 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
* on DMA or PIO queues. * on DMA or PIO queues.
* Maybe we get this in other error conditions, too. * Maybe we get this in other error conditions, too.
*/ */
bcmirq_print_reasons("XMIT ERROR"); printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR); bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
} }
if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
(dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
(dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
(dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
"0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
dma_reason[0], dma_reason[1],
dma_reason[2], dma_reason[3]);
bcm43xx_controller_restart(bcm, "DMA error");
bcm43xx_unlock_mmio(bcm, flags);
return;
}
if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
(dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
(dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
(dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
printkl(KERN_ERR PFX "DMA error: "
"0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
dma_reason[0], dma_reason[1],
dma_reason[2], dma_reason[3]);
}
if (reason & BCM43xx_IRQ_PS) { if (reason & BCM43xx_IRQ_PS) {
handle_irq_ps(bcm); handle_irq_ps(bcm);
...@@ -1780,8 +1809,6 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) ...@@ -1780,8 +1809,6 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
bcm43xx_unlock_mmio(bcm, flags); bcm43xx_unlock_mmio(bcm, flags);
} }
#undef bcmirq_print_reasons
static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm,
u32 reason, u32 mask) u32 reason, u32 mask)
{ {
...@@ -3875,6 +3902,7 @@ static void bcm43xx_chip_reset(void *_bcm) ...@@ -3875,6 +3902,7 @@ static void bcm43xx_chip_reset(void *_bcm)
void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
{ {
bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
schedule_work(&bcm->restart_work); schedule_work(&bcm->restart_work);
......
This diff is collapsed.
...@@ -97,6 +97,7 @@ void bcm43xx_radio_lock(struct bcm43xx_private *bcm) ...@@ -97,6 +97,7 @@ void bcm43xx_radio_lock(struct bcm43xx_private *bcm)
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
status |= BCM43xx_SBF_RADIOREG_LOCK; status |= BCM43xx_SBF_RADIOREG_LOCK;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
mmiowb();
udelay(10); udelay(10);
} }
...@@ -108,6 +109,7 @@ void bcm43xx_radio_unlock(struct bcm43xx_private *bcm) ...@@ -108,6 +109,7 @@ void bcm43xx_radio_unlock(struct bcm43xx_private *bcm)
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
status &= ~BCM43xx_SBF_RADIOREG_LOCK; status &= ~BCM43xx_SBF_RADIOREG_LOCK;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
mmiowb();
} }
u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset) u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset)
...@@ -142,6 +144,7 @@ u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset) ...@@ -142,6 +144,7 @@ u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset)
void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val) void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val)
{ {
bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset); bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset);
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val); bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val);
} }
...@@ -161,10 +164,10 @@ static void bcm43xx_set_all_gains(struct bcm43xx_private *bcm, ...@@ -161,10 +164,10 @@ static void bcm43xx_set_all_gains(struct bcm43xx_private *bcm,
} }
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
bcm43xx_ilt_write16(bcm, offset + i, first); bcm43xx_ilt_write(bcm, offset + i, first);
for (i = start; i < end; i++) for (i = start; i < end; i++)
bcm43xx_ilt_write16(bcm, offset + i, second); bcm43xx_ilt_write(bcm, offset + i, second);
if (third != -1) { if (third != -1) {
tmp = ((u16)third << 14) | ((u16)third << 6); tmp = ((u16)third << 14) | ((u16)third << 6);
...@@ -196,11 +199,11 @@ static void bcm43xx_set_original_gains(struct bcm43xx_private *bcm) ...@@ -196,11 +199,11 @@ static void bcm43xx_set_original_gains(struct bcm43xx_private *bcm)
tmp |= (i & 0x0001) << 1; tmp |= (i & 0x0001) << 1;
tmp |= (i & 0x0002) >> 1; tmp |= (i & 0x0002) >> 1;
bcm43xx_ilt_write16(bcm, offset + i, tmp); bcm43xx_ilt_write(bcm, offset + i, tmp);
} }
for (i = start; i < end; i++) for (i = start; i < end; i++)
bcm43xx_ilt_write16(bcm, offset + i, i - start); bcm43xx_ilt_write(bcm, offset + i, i - start);
bcm43xx_phy_write(bcm, 0x04A0, bcm43xx_phy_write(bcm, 0x04A0,
(bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040); (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040);
...@@ -316,6 +319,7 @@ u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm) ...@@ -316,6 +319,7 @@ u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm)
void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val) void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val)
{ {
bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset); bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset);
mmiowb();
bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val); bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val);
} }
...@@ -612,10 +616,6 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm) ...@@ -612,10 +616,6 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
} }
break; break;
case BCM43xx_PHYTYPE_G: case BCM43xx_PHYTYPE_G:
//FIXME: Something is broken here. This is called when enabling WLAN interfmode.
// If this is done at runtime, I get an XMIT ERROR and transmission is
// broken. I guess some important register is overwritten by accident.
// The XMIT ERROR comes from the dummy_transmissions in set_gains.
if (radio->revision >= 9) if (radio->revision >= 9)
return; return;
if (radio->revision == 8) if (radio->revision == 8)
...@@ -1641,14 +1641,14 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower) ...@@ -1641,14 +1641,14 @@ void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower)
base &= 0x000F; base &= 0x000F;
bcm43xx_phy_write(bcm, 0x0017, base | 0x0020); bcm43xx_phy_write(bcm, 0x0017, base | 0x0020);
ilt = bcm43xx_ilt_read16(bcm, 0x3001); ilt = bcm43xx_ilt_read(bcm, 0x3001);
ilt &= 0x0007; ilt &= 0x0007;
dac = bcm43xx_get_txgain_dac(txpower); dac = bcm43xx_get_txgain_dac(txpower);
dac <<= 3; dac <<= 3;
dac |= ilt; dac |= ilt;
bcm43xx_ilt_write16(bcm, 0x3001, dac); bcm43xx_ilt_write(bcm, 0x3001, dac);
bcm->current_core->radio->txpower[0] = txpower; bcm->current_core->radio->txpower[0] = txpower;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment