dev->dev->write16(dev->dev, offset, value);
}
+/* To optimize this check for flush_writes on BCM47XX_BCMA only. */
+static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
+{
+ b43_write16(dev, offset, value);
+#if defined(CONFIG_BCM47XX_BCMA)
+ if (dev->dev->flush_writes)
+ b43_read16(dev, offset);
+#endif
+}
+
static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
u16 set)
{
*/
+#ifdef CONFIG_BCM47XX_BCMA
+#include <asm/mach-bcm47xx/bcm47xx.h>
+#endif
+
#include "b43.h"
#include "bus.h"
dev->write32 = b43_bus_bcma_write32;
dev->block_read = b43_bus_bcma_block_read;
dev->block_write = b43_bus_bcma_block_write;
+#ifdef CONFIG_BCM47XX_BCMA
+ if (b43_bus_host_is_pci(dev) &&
+ bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA &&
+ bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4716)
+ dev->flush_writes = true;
+#endif
dev->dev = &core->dev;
dev->dma_dev = core->dma_dev;
size_t count, u16 offset, u8 reg_width);
void (*block_write)(struct b43_bus_dev *dev, const void *buffer,
size_t count, u16 offset, u8 reg_width);
+ bool flush_writes;
struct device *dev;
struct device *dma_dev;
if (core_rev == 40 || core_rev == 42) {
radio_manuf = 0x17F;
- b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
+ b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0);
radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
- b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
+ b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1);
radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
radio_ver = 0; /* Is there version somewhere? */
u16 radio24[3];
for (tmp = 0; tmp < 3; tmp++) {
- b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
+ b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp);
radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
}
else
tmp = 0x5205017F;
} else {
- b43_write16(dev, B43_MMIO_RADIO_CONTROL,
- B43_RADIOCTL_ID);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+ B43_RADIOCTL_ID);
tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
- b43_write16(dev, B43_MMIO_RADIO_CONTROL,
- B43_RADIOCTL_ID);
- tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
- << 16;
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+ B43_RADIOCTL_ID);
+ tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
}
radio_manuf = (tmp & 0x00000FFF);
radio_id = (tmp & 0x0FFFF000) >> 12;
static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
{
reg = adjust_phyreg(dev, reg);
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
return b43_read16(dev, B43_MMIO_PHY_DATA);
}
static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
{
reg = adjust_phyreg(dev, reg);
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_write16(dev, B43_MMIO_PHY_DATA, value);
}
if (dev->phy.ops->phy_read)
return dev->phy.ops->phy_read(dev, reg);
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
return b43_read16(dev, B43_MMIO_PHY_DATA);
}
if (dev->phy.ops->phy_write)
return dev->phy.ops->phy_write(dev, reg, value);
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_write16(dev, B43_MMIO_PHY_DATA, value);
}
static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
{
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
return b43_read16(dev, B43_MMIO_PHY_DATA);
}
static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
{
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_write16(dev, B43_MMIO_PHY_DATA, value);
}
/* G-PHY needs 0x80 for read access. */
reg |= 0x80;
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
}
/* Register 1 is a 32-bit register. */
B43_WARN_ON(reg == 1);
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
}
static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
u16 set)
{
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_write16(dev, B43_MMIO_PHY_DATA,
(b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
}
/* HT-PHY needs 0x200 for read access */
reg |= 0x200;
- b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO24_DATA);
}
static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
u16 value)
{
- b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
}
static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
u16 set)
{
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_write16(dev, B43_MMIO_PHY_DATA,
(b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
}
/* LCN-PHY needs 0x200 for read access */
reg |= 0x200;
- b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO24_DATA);
}
static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
u16 value)
{
- b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
}
static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
u16 set)
{
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_write16(dev, B43_MMIO_PHY_DATA,
(b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
}
} else
reg |= 0x200;
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
}
/* Register 1 is a 32-bit register. */
B43_WARN_ON(reg == 1);
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
}
u16 set)
{
check_phyreg(dev, reg);
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
dev->phy.writes_counter = 1;
}
else
reg |= 0x100;
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
}
/* Register 1 is a 32-bit register. */
B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
}