aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/mcdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/mcdi.c')
-rw-r--r--drivers/net/sfc/mcdi.c32
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
107static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) 108static 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
605int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build) 606void 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
639fail: 631fail:
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
644int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, 636int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,