Files
linux/drivers/bcma/driver_pci.c
Colin Ian King 420c20be08 bcma: fix incorrect update of BCMA_CORE_PCI_MDIO_DATA
An earlier commit re-worked the setting of the bitmask and is now
assigning v with some bit flags rather than bitwise or-ing them
into v, consequently the earlier bit-settings of v are being lost.
Fix this by replacing an assignment with the bitwise or instead.

Addresses-Coverity: ("Unused value")
Fixes: 2be25cac8402 ("bcma: add constants for PCI and use them")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2019-09-03 16:44:02 +03:00

307 lines
8.2 KiB
C

/*
* Broadcom specific AMBA
* PCI Core
*
* Copyright 2005, 2011, Broadcom Corporation
* Copyright 2006, 2007, Michael Buesch <m@bues.ch>
* Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/export.h>
#include <linux/bcma/bcma.h>
/**************************************************
* R/W ops.
**************************************************/
u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
{
pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
}
static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
{
pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
}
static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u16 phy)
{
u32 v;
int i;
v = BCMA_CORE_PCI_MDIODATA_START;
v |= BCMA_CORE_PCI_MDIODATA_WRITE;
v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
v |= BCMA_CORE_PCI_MDIODATA_TA;
v |= (phy << 4);
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
udelay(10);
for (i = 0; i < 200; i++) {
v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
break;
usleep_range(1000, 2000);
}
}
static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u16 device, u8 address)
{
int max_retries = 10;
u16 ret = 0;
u32 v;
int i;
/* enable mdio access to SERDES */
v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
if (pc->core->id.rev >= 10) {
max_retries = 200;
bcma_pcie_mdio_set_phy(pc, device);
v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
} else {
v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
}
v |= BCMA_CORE_PCI_MDIODATA_START;
v |= BCMA_CORE_PCI_MDIODATA_READ;
v |= BCMA_CORE_PCI_MDIODATA_TA;
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
/* Wait for the device to complete the transaction */
udelay(10);
for (i = 0; i < max_retries; i++) {
v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
udelay(10);
ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
break;
}
usleep_range(1000, 2000);
}
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
return ret;
}
static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u16 device,
u8 address, u16 data)
{
int max_retries = 10;
u32 v;
int i;
/* enable mdio access to SERDES */
v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
if (pc->core->id.rev >= 10) {
max_retries = 200;
bcma_pcie_mdio_set_phy(pc, device);
v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
} else {
v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
}
v |= BCMA_CORE_PCI_MDIODATA_START;
v |= BCMA_CORE_PCI_MDIODATA_WRITE;
v |= BCMA_CORE_PCI_MDIODATA_TA;
v |= data;
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);