diff options
Diffstat (limited to 'drivers/net/ethernet/meta/fbnic/fbnic_mac.c')
-rw-r--r-- | drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 62 |
1 files changed, 56 insertions, 6 deletions
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c index 80b82ff12c4d..14291401f463 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c @@ -686,25 +686,75 @@ fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset, MAC_STAT_TX_BROADCAST); } -static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id, long *val) +static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id, + long *val) { - struct fbnic_fw_completion fw_cmpl; + struct fbnic_fw_completion *fw_cmpl; + int err = 0, retries = 5; s32 *sensor; + fw_cmpl = kzalloc(sizeof(*fw_cmpl), GFP_KERNEL); + if (!fw_cmpl) + return -ENOMEM; + + /* Initialize completion and queue it for FW to process */ + fbnic_fw_init_cmpl(fw_cmpl, FBNIC_TLV_MSG_ID_TSENE_READ_RESP); + switch (id) { case FBNIC_SENSOR_TEMP: - sensor = &fw_cmpl.tsene.millidegrees; + sensor = &fw_cmpl->u.tsene.millidegrees; break; case FBNIC_SENSOR_VOLTAGE: - sensor = &fw_cmpl.tsene.millivolts; + sensor = &fw_cmpl->u.tsene.millivolts; break; default: - return -EINVAL; + err = -EINVAL; + goto exit_free; + } + + err = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl); + if (err) { + dev_err(fbd->dev, + "Failed to transmit TSENE read msg, err %d\n", + err); + goto exit_free; + } + + /* Allow 2 seconds for reply, resend and try up to 5 times */ + while (!wait_for_completion_timeout(&fw_cmpl->done, 2 * HZ)) { + retries--; + + if (retries == 0) { + dev_err(fbd->dev, + "Timed out waiting for TSENE read\n"); + err = -ETIMEDOUT; + goto exit_cleanup; + } + + err = fbnic_fw_xmit_tsene_read_msg(fbd, NULL); + if (err) { + dev_err(fbd->dev, + "Failed to transmit TSENE read msg, err %d\n", + err); + goto exit_cleanup; + } + } + + /* Handle error returned by firmware */ + if (fw_cmpl->result) { + err = fw_cmpl->result; + dev_err(fbd->dev, "%s: Firmware returned error %d\n", + __func__, err); + goto exit_cleanup; } *val = *sensor; +exit_cleanup: + fbnic_fw_clear_compl(fbd); +exit_free: + fbnic_fw_put_cmpl(fw_cmpl); - return 0; + return err; } static const struct fbnic_mac fbnic_mac_asic = { |