aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
diff options
context:
space:
mode:
authorIyappan Subramanian <isubramanian@apm.com>2017-05-10 13:44:59 -0700
committerDavid S. Miller <davem@davemloft.net>2017-05-16 11:41:08 -0400
commitae1aed95d0255aafdffc48c3a077c7980adc1168 (patch)
treec9d3948e16fae4a42c6299048e33e75c558a1b61 /drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (diff)
downloadlinux-dev-ae1aed95d0255aafdffc48c3a077c7980adc1168.tar.xz
linux-dev-ae1aed95d0255aafdffc48c3a077c7980adc1168.zip
drivers: net: xgene: Protect indirect MAC access
This patch, - refactors mac read/write functions - adds lock to protect indirect mac access Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> Signed-off-by: Quan Nguyen <qnguyen@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_hw.c119
1 files changed, 50 insertions, 69 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index 2a835e07adfb..2050c58eddfd 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -270,42 +270,32 @@ static void xgene_enet_wr_mcx_csr(struct xgene_enet_pdata *pdata,
iowrite32(val, addr);
}
-static bool xgene_enet_wr_indirect(void __iomem *addr, void __iomem *wr,
- void __iomem *cmd, void __iomem *cmd_done,
- u32 wr_addr, u32 wr_data)
+void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata, u32 wr_addr, u32 wr_data)
{
- u32 done;
+ void __iomem *addr, *wr, *cmd, *cmd_done;
+ struct net_device *ndev = pdata->ndev;
u8 wait = 10;
+ u32 done;
+ addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
+ wr = pdata->mcx_mac_addr + MAC_WRITE_REG_OFFSET;
+ cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
+ cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+
+ spin_lock(&pdata->mac_lock);
iowrite32(wr_addr, addr);
iowrite32(wr_data, wr);
iowrite32(XGENE_ENET_WR_CMD, cmd);
- /* wait for write command to complete */
while (!(done = ioread32(cmd_done)) && wait--)
udelay(1);
if (!done)
- return false;
+ netdev_err(ndev, "mac write failed, addr: %04x data: %08x\n",
+ wr_addr, wr_data);
iowrite32(0, cmd);
-
- return true;
-}
-
-static void xgene_enet_wr_mcx_mac(struct xgene_enet_pdata *pdata,
- u32 wr_addr, u32 wr_data)
-{
- void __iomem *addr, *wr, *cmd, *cmd_done;
-
- addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
- wr = pdata->mcx_mac_addr + MAC_WRITE_REG_OFFSET;
- cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
- cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
-
- if (!xgene_enet_wr_indirect(addr, wr, cmd, cmd_done, wr_addr, wr_data))
- netdev_err(pdata->ndev, "MCX mac write failed, addr: %04x\n",
- wr_addr);
+ spin_unlock(&pdata->mac_lock);
}
static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,
@@ -332,42 +322,33 @@ static void xgene_enet_rd_mcx_csr(struct xgene_enet_pdata *pdata,
*val = ioread32(addr);
}
-static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd,
- void __iomem *cmd, void __iomem *cmd_done,
- u32 rd_addr, u32 *rd_data)
+u32 xgene_enet_rd_mac(struct xgene_enet_pdata *pdata, u32 rd_addr)
{
- u32 done;
+ void __iomem *addr, *rd, *cmd, *cmd_done;
+ u32 done, rd_data;
u8 wait = 10;
+ addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
+ rd = pdata->mcx_mac_addr + MAC_READ_REG_OFFSET;
+ cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
+ cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+
+ spin_lock(&pdata->mac_lock);
iowrite32(rd_addr, addr);
iowrite32(XGENE_ENET_RD_CMD, cmd);
- /* wait for read command to complete */
while (!(done = ioread32(cmd_done)) && wait--)
udelay(1);
if (!done)
- return false;
+ netdev_err(pdata->ndev, "mac read failed, addr: %04x\n",
+ rd_addr);
- *rd_data = ioread32(rd);
+ rd_data = ioread32(rd);
iowrite32(0, cmd);
+ spin_unlock(&pdata->mac_lock);
- return true;
-}
-
-static void xgene_enet_rd_mcx_mac(struct xgene_enet_pdata *pdata,
- u32 rd_addr, u32 *rd_data)
-{
- void __iomem *addr, *rd, *cmd, *cmd_done;
-
- addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
- rd = pdata->mcx_mac_addr + MAC_READ_REG_OFFSET;
- cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
- cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
-
- if (!xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data))
- netdev_err(pdata->ndev, "MCX mac read failed, addr: %04x\n",
- rd_addr);
+ return rd_data;
}
static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
@@ -379,8 +360,8 @@ static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
(dev_addr[1] << 8) | dev_addr[0];
addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16);
- xgene_enet_wr_mcx_mac(pdata, STATION_ADDR0_ADDR, addr0);
- xgene_enet_wr_mcx_mac(pdata, STATION_ADDR1_ADDR, addr1);
+ xgene_enet_wr_mac(pdata, STATION_ADDR0_ADDR, addr0);
+ xgene_enet_wr_mac(pdata, STATION_ADDR1_ADDR, addr1);
}
static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
@@ -405,8 +386,8 @@ static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
{
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, 0);
}
static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
@@ -456,8 +437,8 @@ static void xgene_gmac_set_speed(struct xgene_enet_pdata *pdata)
xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, &icm0);
xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, &icm2);
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_2_ADDR, &mc2);
- xgene_enet_rd_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, &intf_ctl);
+ mc2 = xgene_enet_rd_mac(pdata, MAC_CONFIG_2_ADDR);
+ intf_ctl = xgene_enet_rd_mac(pdata, INTERFACE_CONTROL_ADDR);
xgene_enet_rd_csr(pdata, RGMII_REG_0_ADDR, &rgmii);
switch (pdata->phy_speed) {
@@ -495,8 +476,8 @@ static void xgene_gmac_set_speed(struct xgene_enet_pdata *pdata)
}
mc2 |= FULL_DUPLEX2 | PAD_CRC | LENGTH_CHK;
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
- xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
+ xgene_enet_wr_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii);
xgene_enet_configure_clock(pdata);
@@ -506,7 +487,7 @@ static void xgene_gmac_set_speed(struct xgene_enet_pdata *pdata)
static void xgene_enet_set_frame_size(struct xgene_enet_pdata *pdata, int size)
{
- xgene_enet_wr_mcx_mac(pdata, MAX_FRAME_LEN_ADDR, size);
+ xgene_enet_wr_mac(pdata, MAX_FRAME_LEN_ADDR, size);
}
static void xgene_gmac_enable_tx_pause(struct xgene_enet_pdata *pdata,
@@ -528,14 +509,14 @@ static void xgene_gmac_flowctl_tx(struct xgene_enet_pdata *pdata, bool enable)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);
if (enable)
data |= TX_FLOW_EN;
else
data &= ~TX_FLOW_EN;
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data);
pdata->mac_ops->enable_tx_pause(pdata, enable);
}
@@ -544,14 +525,14 @@ static void xgene_gmac_flowctl_rx(struct xgene_enet_pdata *pdata, bool enable)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);
if (enable)
data |= RX_FLOW_EN;
else
data &= ~RX_FLOW_EN;
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data);
}
static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
@@ -565,9 +546,9 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
xgene_gmac_set_mac_addr(pdata);
/* Adjust MDC clock frequency */
- xgene_enet_rd_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, &value);
+ value = xgene_enet_rd_mac(pdata, MII_MGMT_CONFIG_ADDR);
MGMT_CLOCK_SEL_SET(&value, 7);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, value);
+ xgene_enet_wr_mac(pdata, MII_MGMT_CONFIG_ADDR, value);
/* Enable drop if bufpool not available */
xgene_enet_rd_csr(pdata, RSIF_CONFIG_REG_ADDR, &value);
@@ -637,32 +618,32 @@ static void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);
+ data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);
}
static void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);
+ data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);
}
static void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);
+ data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);
}
static void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
+ data = xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
}
bool xgene_ring_mgr_init(struct xgene_enet_pdata *p)