diff options
Diffstat (limited to 'drivers/net/sfc/mcdi.c')
-rw-r--r-- | drivers/net/sfc/mcdi.c | 32 |
1 files changed, 12 insertions, 20 deletions
diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index b716e827b291..5e118f0d2479 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2008-2009 Solarflare Communications Inc. | 3 | * Copyright 2008-2011 Solarflare Communications Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 as published | 6 | * under the terms of the GNU General Public License version 2 as published |
@@ -94,14 +94,15 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, | |||
94 | 94 | ||
95 | efx_writed(efx, &hdr, pdu); | 95 | efx_writed(efx, &hdr, pdu); |
96 | 96 | ||
97 | for (i = 0; i < inlen; i += 4) | 97 | for (i = 0; i < inlen; i += 4) { |
98 | _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i); | 98 | _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i); |
99 | 99 | /* use wmb() within loop to inhibit write combining */ | |
100 | /* Ensure the payload is written out before the header */ | 100 | wmb(); |
101 | wmb(); | 101 | } |
102 | 102 | ||
103 | /* ring the doorbell with a distinctive value */ | 103 | /* ring the doorbell with a distinctive value */ |
104 | _efx_writed(efx, (__force __le32) 0x45789abc, doorbell); | 104 | _efx_writed(efx, (__force __le32) 0x45789abc, doorbell); |
105 | wmb(); | ||
105 | } | 106 | } |
106 | 107 | ||
107 | static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) | 108 | static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) |
@@ -602,7 +603,7 @@ void efx_mcdi_process_event(struct efx_channel *channel, | |||
602 | ************************************************************************** | 603 | ************************************************************************** |
603 | */ | 604 | */ |
604 | 605 | ||
605 | int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build) | 606 | void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) |
606 | { | 607 | { |
607 | u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)]; | 608 | u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)]; |
608 | size_t outlength; | 609 | size_t outlength; |
@@ -616,29 +617,20 @@ int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build) | |||
616 | if (rc) | 617 | if (rc) |
617 | goto fail; | 618 | goto fail; |
618 | 619 | ||
619 | if (outlength == MC_CMD_GET_VERSION_V0_OUT_LEN) { | ||
620 | *version = 0; | ||
621 | *build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE); | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) { | 620 | if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) { |
626 | rc = -EIO; | 621 | rc = -EIO; |
627 | goto fail; | 622 | goto fail; |
628 | } | 623 | } |
629 | 624 | ||
630 | ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION); | 625 | ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION); |
631 | *version = (((u64)le16_to_cpu(ver_words[0]) << 48) | | 626 | snprintf(buf, len, "%u.%u.%u.%u", |
632 | ((u64)le16_to_cpu(ver_words[1]) << 32) | | 627 | le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]), |
633 | ((u64)le16_to_cpu(ver_words[2]) << 16) | | 628 | le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3])); |
634 | le16_to_cpu(ver_words[3])); | 629 | return; |
635 | *build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE); | ||
636 | |||
637 | return 0; | ||
638 | 630 | ||
639 | fail: | 631 | fail: |
640 | netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); | 632 | netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); |
641 | return rc; | 633 | buf[0] = 0; |
642 | } | 634 | } |
643 | 635 | ||
644 | int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, | 636 | int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, |