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