Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Print nvm version of ixl(4) when attaching



details:   https://anonhg.NetBSD.org/src/rev/013454d7987a
branches:  trunk
changeset: 1006480:013454d7987a
user:      yamaguchi <yamaguchi%NetBSD.org@localhost>
date:      Fri Jan 17 09:42:05 2020 +0000

description:
Print nvm version of ixl(4) when attaching

reviewed by msaitoh

diffstat:

 sys/dev/pci/if_ixl.c    |  264 +++++++++++++++++++++++++++++++++++++++++++++++-
 sys/dev/pci/if_ixlvar.h |   52 +++++++++-
 2 files changed, 311 insertions(+), 5 deletions(-)

diffs (truncated from 450 to 300 lines):

diff -r 2af63ae0705d -r 013454d7987a sys/dev/pci/if_ixl.c
--- a/sys/dev/pci/if_ixl.c      Fri Jan 17 09:37:42 2020 +0000
+++ b/sys/dev/pci/if_ixl.c      Fri Jan 17 09:42:05 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ixl.c,v 1.25 2020/01/17 09:37:42 yamaguchi Exp $    */
+/*     $NetBSD: if_ixl.c,v 1.26 2020/01/17 09:42:05 yamaguchi Exp $    */
 
 /*
  * Copyright (c) 2013-2015, Intel Corporation
@@ -198,6 +198,8 @@
 
 #define IXL_ATQ_EXEC_TIMEOUT           (10 * hz)
 
+#define IXL_SRRD_SRCTL_ATTEMPTS                100000
+
 struct ixl_aq_regs {
        bus_size_t              atq_tail;
        bus_size_t              atq_head;
@@ -653,11 +655,14 @@
        unsigned int             sc_msix_vector_queue;
 
        struct ixl_dmamem        sc_scratch;
+       struct ixl_dmamem        sc_aqbuf;
 
        const struct ixl_aq_regs *
                                 sc_aq_regs;
        uint32_t                 sc_aq_flags;
 #define IXL_SC_AQ_FLAG_RXCTL   __BIT(0)
+#define IXL_SC_AQ_FLAG_NVMLOCK __BIT(1)
+#define IXL_SC_AQ_FLAG_NVMREAD __BIT(2)
 
        kmutex_t                 sc_atq_lock;
        kcondvar_t               sc_atq_cv;
@@ -753,6 +758,7 @@
 static void    ixl_atq_done(struct ixl_softc *);
 static int     ixl_atq_exec(struct ixl_softc *, struct ixl_atq *);
 static int     ixl_get_version(struct ixl_softc *);
+static int     ixl_get_nvm_version(struct ixl_softc *);
 static int     ixl_get_hw_capabilities(struct ixl_softc *);
 static int     ixl_pxe_clear(struct ixl_softc *);
 static int     ixl_lldp_shut(struct ixl_softc *);
@@ -780,6 +786,7 @@
                    const struct ixl_hmc_pack *, unsigned int);
 static uint32_t        ixl_rd_rx_csr(struct ixl_softc *, uint32_t);
 static void    ixl_wr_rx_csr(struct ixl_softc *, uint32_t, uint32_t);
+static int     ixl_rd16_nvm(struct ixl_softc *, uint16_t, uint16_t *);
 
 static int     ixl_match(device_t, cfdata_t, void *);
 static void    ixl_attach(device_t, device_t, void *);
@@ -1176,6 +1183,13 @@
 
        ixl_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod);
 
+       if (ixl_dmamem_alloc(sc, &sc->sc_aqbuf, IXL_AQ_BUFLEN, 0) != 0) {
+               aprint_error_dev(self, ", unable to allocate nvm buffer\n");
+               goto shutdown;
+       }
+
+       ixl_get_nvm_version(sc);
+
        if (sc->sc_mac_type == I40E_MAC_X722)
                sc->sc_nqueue_pairs_device = 128;
        else
@@ -1185,7 +1199,7 @@
        if (rv != 0) {
                aprint_error(", GET HW CAPABILITIES %s\n",
                    rv == ETIMEDOUT ? "timeout" : "error");
-               goto shutdown;
+               goto free_aqbuf;
        }
 
        sc->sc_nqueue_pairs_max = MIN((int)sc->sc_nqueue_pairs_device, ncpu);
@@ -1203,7 +1217,7 @@
 
        if (ixl_get_mac(sc) != 0) {
                /* error printed by ixl_get_mac */
-               goto shutdown;
+               goto free_aqbuf;
        }
 
        aprint_normal("\n");
@@ -1222,7 +1236,7 @@
 
        if (ixl_hmc(sc) != 0) {
                /* error printed by ixl_hmc */
-               goto shutdown;
+               goto free_aqbuf;
        }
 
        if (ixl_lldp_shut(sc) != 0) {
@@ -1408,6 +1422,8 @@
        ixl_dmamem_free(sc, &sc->sc_scratch);
 free_hmc:
        ixl_hmc_free(sc);
+free_aqbuf:
+       ixl_dmamem_free(sc, &sc->sc_aqbuf);
 shutdown:
        ixl_wr(sc, sc->sc_aq_regs->atq_head, 0);
        ixl_wr(sc, sc->sc_aq_regs->arq_head, 0);
@@ -1514,6 +1530,7 @@
 
        ixl_dmamem_free(sc, &sc->sc_arq);
        ixl_dmamem_free(sc, &sc->sc_atq);
+       ixl_dmamem_free(sc, &sc->sc_aqbuf);
 
        cv_destroy(&sc->sc_atq_cv);
        mutex_destroy(&sc->sc_atq_lock);
@@ -3789,11 +3806,17 @@
        aprint_normal(", FW %hu.%hu.%05u API %hu.%hu", (uint16_t)fwver,
            (uint16_t)(fwver >> 16), fwbuild, api_maj_ver, api_min_ver);
 
+       if (sc->sc_mac_type == I40E_MAC_X722) {
+               SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK |
+                   IXL_SC_AQ_FLAG_NVMREAD);
+       }
+
 #define IXL_API_VER(maj, min)  (((uint32_t)(maj) << 16) | (min))
        if (IXL_API_VER(api_maj_ver, api_min_ver) >= IXL_API_VER(1, 5)) {
                if (sc->sc_mac_type == I40E_MAC_X722) {
                        SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL);
                }
+               SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK);
        }
 #undef IXL_API_VER
 
@@ -3801,6 +3824,37 @@
 }
 
 static int
+ixl_get_nvm_version(struct ixl_softc *sc)
+{
+       uint16_t nvmver, cfg_ptr, eetrack_hi, eetrack_lo, oem_hi, oem_lo;
+       uint32_t eetrack, oem;
+       uint16_t nvm_maj_ver, nvm_min_ver, oem_build;
+       uint8_t oem_ver, oem_patch;
+
+       nvmver = cfg_ptr = eetrack_hi = eetrack_lo = oem_hi = oem_lo = 0;
+       ixl_rd16_nvm(sc, I40E_SR_NVM_DEV_STARTER_VERSION, &nvmver);
+       ixl_rd16_nvm(sc, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
+       ixl_rd16_nvm(sc, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
+       ixl_rd16_nvm(sc, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr);
+       ixl_rd16_nvm(sc, cfg_ptr + I40E_NVM_OEM_VER_OFF, &oem_hi);
+       ixl_rd16_nvm(sc, cfg_ptr + I40E_NVM_OEM_VER_OFF + 1, &oem_lo);
+
+       nvm_maj_ver = (uint16_t)__SHIFTOUT(nvmver, IXL_NVM_VERSION_HI_MASK);
+       nvm_min_ver = (uint16_t)__SHIFTOUT(nvmver, IXL_NVM_VERSION_LO_MASK);
+       eetrack = ((uint32_t)eetrack_hi << 16) | eetrack_lo;
+       oem = ((uint32_t)oem_hi << 16) | oem_lo;
+       oem_ver = __SHIFTOUT(oem, IXL_NVM_OEMVERSION_MASK);
+       oem_build = __SHIFTOUT(oem, IXL_NVM_OEMBUILD_MASK);
+       oem_patch = __SHIFTOUT(oem, IXL_NVM_OEMPATCH_MASK);
+
+       aprint_normal(" nvm %x.%02x etid %08x oem %d.%d.%d",
+           nvm_maj_ver, nvm_min_ver, eetrack,
+           oem_ver, oem_build, oem_patch);
+
+       return 0;
+}
+
+static int
 ixl_pxe_clear(struct ixl_softc *sc)
 {
        struct ixl_aq_desc iaq;
@@ -6344,6 +6398,208 @@
        ixl_wr(sc, reg, value);
 }
 
+static int
+ixl_nvm_lock(struct ixl_softc *sc, char rw)
+{
+       struct ixl_aq_desc iaq;
+       struct ixl_aq_req_resource_param *param;
+       int rv;
+
+       if (!ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK))
+               return 0;
+
+       memset(&iaq, 0, sizeof(iaq));
+       iaq.iaq_opcode = htole16(IXL_AQ_OP_REQUEST_RESOURCE);
+
+       param = (struct ixl_aq_req_resource_param *)&iaq.iaq_param;
+       param->resource_id = htole16(IXL_AQ_RESOURCE_ID_NVM);
+       if (rw == 'R') {
+               param->access_type = htole16(IXL_AQ_RESOURCE_ACCES_READ);
+       } else {
+               param->access_type = htole16(IXL_AQ_RESOURCE_ACCES_WRITE);
+       }
+
+       rv = ixl_atq_poll(sc, &iaq, 250);
+
+       if (rv != 0)
+               return ETIMEDOUT;
+
+       switch (le16toh(iaq.iaq_retval)) {
+       case IXL_AQ_RC_OK:
+               break;
+       case IXL_AQ_RC_EACCES:
+               return EACCES;
+       case IXL_AQ_RC_EBUSY:
+               return EBUSY;
+       case IXL_AQ_RC_EPERM:
+               return EPERM;
+       }
+
+       return 0;
+}
+
+static int
+ixl_nvm_unlock(struct ixl_softc *sc)
+{
+       struct ixl_aq_desc iaq;
+       struct ixl_aq_rel_resource_param *param;
+       int rv;
+
+       if (!ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK))
+               return 0;
+
+       memset(&iaq, 0, sizeof(iaq));
+       iaq.iaq_opcode = htole16(IXL_AQ_OP_RELEASE_RESOURCE);
+
+       param = (struct ixl_aq_rel_resource_param *)&iaq.iaq_param;
+       param->resource_id = htole16(IXL_AQ_RESOURCE_ID_NVM);
+
+       rv = ixl_atq_poll(sc, &iaq, 250);
+
+       if (rv != 0)
+               return ETIMEDOUT;
+
+       switch (le16toh(iaq.iaq_retval)) {
+       case IXL_AQ_RC_OK:
+               break;
+       default:
+               return EIO;
+       }
+       return 0;
+}
+
+static int
+ixl_srdone_poll(struct ixl_softc *sc)
+{
+       int wait_count;
+       uint32_t reg;
+
+       for (wait_count = 0; wait_count < IXL_SRRD_SRCTL_ATTEMPTS;
+           wait_count++) {
+               reg = ixl_rd(sc, I40E_GLNVM_SRCTL);
+               if (ISSET(reg, I40E_GLNVM_SRCTL_DONE_MASK))
+                       break;
+
+               delaymsec(5);
+       }
+
+       if (wait_count == IXL_SRRD_SRCTL_ATTEMPTS)
+               return -1;
+
+       return 0;
+}
+
+static int
+ixl_nvm_read_srctl(struct ixl_softc *sc, uint16_t offset, uint16_t *data)
+{
+       uint32_t reg;
+
+       if (ixl_srdone_poll(sc) != 0)
+               return ETIMEDOUT;
+
+       reg = ((uint32_t)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
+           __BIT(I40E_GLNVM_SRCTL_START_SHIFT);
+       ixl_wr(sc, I40E_GLNVM_SRCTL, reg);
+
+       if (ixl_srdone_poll(sc) != 0) {
+               aprint_debug("NVM read error: couldn't access "
+                   "Shadow RAM address: 0x%x\n", offset);
+               return ETIMEDOUT;
+       }
+
+       reg = ixl_rd(sc, I40E_GLNVM_SRDATA);
+       *data = (uint16_t)__SHIFTOUT(reg, I40E_GLNVM_SRDATA_RDDATA_MASK);
+
+       return 0;
+}
+
+static int
+ixl_nvm_read_aq(struct ixl_softc *sc, uint16_t offset_word,
+    void *data, size_t len)
+{
+       struct ixl_dmamem *idm;
+       struct ixl_aq_desc iaq;
+       struct ixl_aq_nvm_param *param;
+       uint32_t offset_bytes;
+       int rv;
+
+       idm = &sc->sc_aqbuf;
+       if (len > IXL_DMA_LEN(idm))
+               return ENOMEM;
+
+       memset(IXL_DMA_KVA(idm), 0, IXL_DMA_LEN(idm));
+       memset(&iaq, 0, sizeof(iaq));
+       iaq.iaq_opcode = htole16(IXL_AQ_OP_NVM_READ);
+       iaq.iaq_flags = htole16(IXL_AQ_BUF |



Home | Main Index | Thread Index | Old Index