summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2016-08-26 15:25:46 (GMT)
committerDavid S. Miller <davem@davemloft.net>2016-08-29 04:29:46 (GMT)
commitf9dc70744dc74bc9e128d579f2bc85eb7c0ad8ce (patch)
tree383547a7ec0f4c697b560821a2e4c23fbb0e409b
parent5711a98221443aec54c4c81ee98c6ae46acccb65 (diff)
downloadlinux-f9dc70744dc74bc9e128d579f2bc85eb7c0ad8ce.tar.xz
net/xgene: fix error handling during reset
The newly added reset logic uses helper functions for the MMIO that may fail. However, when the read operation fails, we end up writing back uninitialized data to the register, as gcc warns: drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c: In function 'xgene_enet_link_state': drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c:213:2: error: 'data' may be used uninitialized in this function [-Werror=maybe-uninitialized] drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c:209:6: note: 'data' was declared here u32 data; We already print a warning to the console log if that happens, the best alternative that I can see is skip the rest of the reset sequence if the register value cannot be read: Most likely the write would fail as well, and if it succeeded, worse things could happen. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Fixes: 3eb7cb9dc946 ("drivers: net: xgene: XFI PCS reset when link is down") Cc: Fushen Chen <fchen@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
index d672e71..279ee27 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -155,19 +155,23 @@ static void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
rd_addr);
}
-static void xgene_enet_rd_pcs(struct xgene_enet_pdata *pdata,
+static bool xgene_enet_rd_pcs(struct xgene_enet_pdata *pdata,
u32 rd_addr, u32 *rd_data)
{
void __iomem *addr, *rd, *cmd, *cmd_done;
+ bool success;
addr = pdata->pcs_addr + PCS_ADDR_REG_OFFSET;
rd = pdata->pcs_addr + PCS_READ_REG_OFFSET;
cmd = pdata->pcs_addr + PCS_COMMAND_REG_OFFSET;
cmd_done = pdata->pcs_addr + PCS_COMMAND_DONE_REG_OFFSET;
- if (!xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data))
+ success = xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data);
+ if (!success)
netdev_err(pdata->ndev, "PCS read failed, addr: %04x\n",
rd_addr);
+
+ return success;
}
static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
@@ -208,7 +212,9 @@ static void xgene_pcs_reset(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_pcs(pdata, PCS_CONTROL_1, &data);
+ if (!xgene_enet_rd_pcs(pdata, PCS_CONTROL_1, &data))
+ return;
+
xgene_enet_wr_pcs(pdata, PCS_CONTROL_1, data | PCS_CTRL_PCS_RST);
xgene_enet_wr_pcs(pdata, PCS_CONTROL_1, data & ~PCS_CTRL_PCS_RST);
}