Commit 1e0b8120 authored by Edward Cree's avatar Edward Cree Committed by Ben Hutchings

sfc: Log all unexpected MCDI errors

Split each of efx_mcdi_rpc, efx_mcdi_rpc_finish, and efx_mcdi_rpc_async into
a normal and a _quiet version; made the former log MCDI errors with
netif_err (and include the raw MCDI error code), and the latter never log
them at all.  Changed various callers; any where some errors are expected
(but others are not) call the _quiet version and then if necessary log the
MCDI error themselves.  Said logging is done by new efx_mcdi_display_error.

Callers of efx_mcdi_rpc*_quiet functions which may want to log the error
need to ensure that their outbuf is big enough to hold an MCDI error; to
this end, they now use MCDI_DECLARE_BUF_OUT_OR_ERR, which always allocates
at least 8 bytes.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 8d13a377
...@@ -278,11 +278,17 @@ static int efx_ef10_probe(struct efx_nic *efx) ...@@ -278,11 +278,17 @@ static int efx_ef10_probe(struct efx_nic *efx)
static int efx_ef10_free_vis(struct efx_nic *efx) static int efx_ef10_free_vis(struct efx_nic *efx)
{ {
int rc = efx_mcdi_rpc(efx, MC_CMD_FREE_VIS, NULL, 0, NULL, 0, NULL); MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0);
size_t outlen;
int rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FREE_VIS, NULL, 0,
outbuf, sizeof(outbuf), &outlen);
/* -EALREADY means nothing to free, so ignore */ /* -EALREADY means nothing to free, so ignore */
if (rc == -EALREADY) if (rc == -EALREADY)
rc = 0; rc = 0;
if (rc)
efx_mcdi_display_error(efx, MC_CMD_FREE_VIS, 0, outbuf, outlen,
rc);
return rc; return rc;
} }
...@@ -1244,7 +1250,6 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue) ...@@ -1244,7 +1250,6 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
fail: fail:
WARN_ON(true); WARN_ON(true);
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
} }
static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
...@@ -1258,7 +1263,7 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) ...@@ -1258,7 +1263,7 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE, MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE,
tx_queue->queue); tx_queue->queue);
rc = efx_mcdi_rpc(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc && rc != -EALREADY) if (rc && rc != -EALREADY)
...@@ -1267,7 +1272,8 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue) ...@@ -1267,7 +1272,8 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
return; return;
fail: fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); efx_mcdi_display_error(efx, MC_CMD_FINI_TXQ, MC_CMD_FINI_TXQ_IN_LEN,
outbuf, outlen, rc);
} }
static void efx_ef10_tx_remove(struct efx_tx_queue *tx_queue) static void efx_ef10_tx_remove(struct efx_tx_queue *tx_queue)
...@@ -1482,14 +1488,9 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue) ...@@ -1482,14 +1488,9 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue)
rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen, rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen,
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc) WARN_ON(rc);
goto fail;
return; return;
fail:
WARN_ON(true);
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
} }
static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
...@@ -1503,7 +1504,7 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) ...@@ -1503,7 +1504,7 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE, MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE,
efx_rx_queue_index(rx_queue)); efx_rx_queue_index(rx_queue));
rc = efx_mcdi_rpc(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc && rc != -EALREADY) if (rc && rc != -EALREADY)
...@@ -1512,7 +1513,8 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue) ...@@ -1512,7 +1513,8 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
return; return;
fail: fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); efx_mcdi_display_error(efx, MC_CMD_FINI_RXQ, MC_CMD_FINI_RXQ_IN_LEN,
outbuf, outlen, rc);
} }
static void efx_ef10_rx_remove(struct efx_rx_queue *rx_queue) static void efx_ef10_rx_remove(struct efx_rx_queue *rx_queue)
...@@ -1649,15 +1651,7 @@ static int efx_ef10_ev_init(struct efx_channel *channel) ...@@ -1649,15 +1651,7 @@ static int efx_ef10_ev_init(struct efx_channel *channel)
rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen, rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen,
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc)
goto fail;
/* IRQ return is ignored */ /* IRQ return is ignored */
return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc; return rc;
} }
...@@ -1671,7 +1665,7 @@ static void efx_ef10_ev_fini(struct efx_channel *channel) ...@@ -1671,7 +1665,7 @@ static void efx_ef10_ev_fini(struct efx_channel *channel)
MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel); MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel);
rc = efx_mcdi_rpc(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc && rc != -EALREADY) if (rc && rc != -EALREADY)
...@@ -1680,7 +1674,8 @@ static void efx_ef10_ev_fini(struct efx_channel *channel) ...@@ -1680,7 +1674,8 @@ static void efx_ef10_ev_fini(struct efx_channel *channel)
return; return;
fail: fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); efx_mcdi_display_error(efx, MC_CMD_FINI_EVQ, MC_CMD_FINI_EVQ_IN_LEN,
outbuf, outlen, rc);
} }
static void efx_ef10_ev_remove(struct efx_channel *channel) static void efx_ef10_ev_remove(struct efx_channel *channel)
......
This diff is collapsed.
...@@ -116,12 +116,19 @@ void efx_mcdi_fini(struct efx_nic *efx); ...@@ -116,12 +116,19 @@ void efx_mcdi_fini(struct efx_nic *efx);
int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const efx_dword_t *inbuf, int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const efx_dword_t *inbuf,
size_t inlen, efx_dword_t *outbuf, size_t outlen, size_t inlen, efx_dword_t *outbuf, size_t outlen,
size_t *outlen_actual); size_t *outlen_actual);
int efx_mcdi_rpc_quiet(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen,
efx_dword_t *outbuf, size_t outlen,
size_t *outlen_actual);
int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen); const efx_dword_t *inbuf, size_t inlen);
int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
efx_dword_t *outbuf, size_t outlen, efx_dword_t *outbuf, size_t outlen,
size_t *outlen_actual); size_t *outlen_actual);
int efx_mcdi_rpc_finish_quiet(struct efx_nic *efx, unsigned cmd,
size_t inlen, efx_dword_t *outbuf,
size_t outlen, size_t *outlen_actual);
typedef void efx_mcdi_async_completer(struct efx_nic *efx, typedef void efx_mcdi_async_completer(struct efx_nic *efx,
unsigned long cookie, int rc, unsigned long cookie, int rc,
...@@ -131,6 +138,15 @@ int efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, ...@@ -131,6 +138,15 @@ int efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd,
const efx_dword_t *inbuf, size_t inlen, size_t outlen, const efx_dword_t *inbuf, size_t inlen, size_t outlen,
efx_mcdi_async_completer *complete, efx_mcdi_async_completer *complete,
unsigned long cookie); unsigned long cookie);
int efx_mcdi_rpc_async_quiet(struct efx_nic *efx, unsigned int cmd,
const efx_dword_t *inbuf, size_t inlen,
size_t outlen,
efx_mcdi_async_completer *complete,
unsigned long cookie);
void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd,
size_t inlen, efx_dword_t *outbuf,
size_t outlen, int rc);
int efx_mcdi_poll_reboot(struct efx_nic *efx); int efx_mcdi_poll_reboot(struct efx_nic *efx);
void efx_mcdi_mode_poll(struct efx_nic *efx); void efx_mcdi_mode_poll(struct efx_nic *efx);
...@@ -147,6 +163,8 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); ...@@ -147,6 +163,8 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
*/ */
#define MCDI_DECLARE_BUF(_name, _len) \ #define MCDI_DECLARE_BUF(_name, _len) \
efx_dword_t _name[DIV_ROUND_UP(_len, 4)] efx_dword_t _name[DIV_ROUND_UP(_len, 4)]
#define MCDI_DECLARE_BUF_OUT_OR_ERR(_name, _len) \
MCDI_DECLARE_BUF(_name, max_t(size_t, _len, 8))
#define _MCDI_PTR(_buf, _offset) \ #define _MCDI_PTR(_buf, _offset) \
((u8 *)(_buf) + (_offset)) ((u8 *)(_buf) + (_offset))
#define MCDI_PTR(_buf, _field) \ #define MCDI_PTR(_buf, _field) \
......
...@@ -90,13 +90,6 @@ static int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities, ...@@ -90,13 +90,6 @@ static int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
NULL, 0, NULL); NULL, 0, NULL);
if (rc)
goto fail;
return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc; return rc;
} }
...@@ -143,17 +136,13 @@ static int efx_mcdi_mdio_read(struct net_device *net_dev, ...@@ -143,17 +136,13 @@ static int efx_mcdi_mdio_read(struct net_device *net_dev,
rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc) if (rc)
goto fail; return rc;
if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) != if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) !=
MC_CMD_MDIO_STATUS_GOOD) MC_CMD_MDIO_STATUS_GOOD)
return -EIO; return -EIO;
return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE); return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE);
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc;
} }
static int efx_mcdi_mdio_write(struct net_device *net_dev, static int efx_mcdi_mdio_write(struct net_device *net_dev,
...@@ -174,17 +163,13 @@ static int efx_mcdi_mdio_write(struct net_device *net_dev, ...@@ -174,17 +163,13 @@ static int efx_mcdi_mdio_write(struct net_device *net_dev,
rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc) if (rc)
goto fail; return rc;
if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) != if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) !=
MC_CMD_MDIO_STATUS_GOOD) MC_CMD_MDIO_STATUS_GOOD)
return -EIO; return -EIO;
return 0; return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc;
} }
static u32 mcdi_to_ethtool_cap(u32 media, u32 cap) static u32 mcdi_to_ethtool_cap(u32 media, u32 cap)
...@@ -487,17 +472,14 @@ static bool efx_mcdi_phy_poll(struct efx_nic *efx) ...@@ -487,17 +472,14 @@ static bool efx_mcdi_phy_poll(struct efx_nic *efx)
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), NULL); outbuf, sizeof(outbuf), NULL);
if (rc) { if (rc)
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
__func__, rc);
efx->link_state.up = false; efx->link_state.up = false;
} else { else
efx_mcdi_phy_decode_link( efx_mcdi_phy_decode_link(
efx, &efx->link_state, efx, &efx->link_state,
MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED), MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS), MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL)); MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
}
return !efx_link_state_equal(&efx->link_state, &old_state); return !efx_link_state_equal(&efx->link_state, &old_state);
} }
...@@ -531,11 +513,8 @@ static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *e ...@@ -531,11 +513,8 @@ static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *e
BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), NULL); outbuf, sizeof(outbuf), NULL);
if (rc) { if (rc)
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
__func__, rc);
return; return;
}
ecmd->lp_advertising = ecmd->lp_advertising =
mcdi_to_ethtool_cap(phy_cfg->media, mcdi_to_ethtool_cap(phy_cfg->media,
MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP)); MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP));
...@@ -918,11 +897,8 @@ bool efx_mcdi_mac_check_fault(struct efx_nic *efx) ...@@ -918,11 +897,8 @@ bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), &outlength); outbuf, sizeof(outbuf), &outlength);
if (rc) { if (rc)
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
__func__, rc);
return true; return true;
}
return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0; return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
} }
...@@ -960,14 +936,6 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, ...@@ -960,14 +936,6 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx,
rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
NULL, 0, NULL); NULL, 0, NULL);
if (rc)
goto fail;
return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: action %d failed rc=%d\n",
__func__, action, rc);
return rc; return rc;
} }
......
...@@ -313,6 +313,8 @@ static int efx_phc_enable(struct ptp_clock_info *ptp, ...@@ -313,6 +313,8 @@ static int efx_phc_enable(struct ptp_clock_info *ptp,
static int efx_ptp_enable(struct efx_nic *efx) static int efx_ptp_enable(struct efx_nic *efx)
{ {
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ENABLE_LEN); MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ENABLE_LEN);
MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0);
int rc;
MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE); MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE);
MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
...@@ -320,8 +322,14 @@ static int efx_ptp_enable(struct efx_nic *efx) ...@@ -320,8 +322,14 @@ static int efx_ptp_enable(struct efx_nic *efx)
efx->ptp_data->channel->channel); efx->ptp_data->channel->channel);
MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode); MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode);
return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
NULL, 0, NULL); outbuf, sizeof(outbuf), NULL);
rc = (rc == -EALREADY) ? 0 : rc;
if (rc)
efx_mcdi_display_error(efx, MC_CMD_PTP,
MC_CMD_PTP_IN_ENABLE_LEN,
outbuf, sizeof(outbuf), rc);
return rc;
} }
/* Disable MCDI PTP support. /* Disable MCDI PTP support.
...@@ -332,11 +340,19 @@ static int efx_ptp_enable(struct efx_nic *efx) ...@@ -332,11 +340,19 @@ static int efx_ptp_enable(struct efx_nic *efx)
static int efx_ptp_disable(struct efx_nic *efx) static int efx_ptp_disable(struct efx_nic *efx)
{ {
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_DISABLE_LEN); MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_DISABLE_LEN);
MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0);
int rc;
MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_DISABLE); MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_DISABLE);
MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
NULL, 0, NULL); outbuf, sizeof(outbuf), NULL);
rc = (rc == -EALREADY) ? 0 : rc;
if (rc)
efx_mcdi_display_error(efx, MC_CMD_PTP,
MC_CMD_PTP_IN_DISABLE_LEN,
outbuf, sizeof(outbuf), rc);
return rc;
} }
static void efx_ptp_deliver_rx_queue(struct sk_buff_head *q) static void efx_ptp_deliver_rx_queue(struct sk_buff_head *q)
......
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