Date: Thu, 21 Dec 2017 15:19:43 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r327062 - in head/sys/dev/cxgbe: . common Message-ID: <201712211519.vBLFJh2c092926@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Thu Dec 21 15:19:43 2017 New Revision: 327062 URL: https://svnweb.freebsd.org/changeset/base/327062 Log: cxgbe(4): Read the MFG diags version from the VPD and make it available in the sysctl MIB. MFC after: 1 week Sponsored by: Chelsio Communications Modified: head/sys/dev/cxgbe/common/common.h head/sys/dev/cxgbe/common/t4_hw.c head/sys/dev/cxgbe/t4_main.c Modified: head/sys/dev/cxgbe/common/common.h ============================================================================== --- head/sys/dev/cxgbe/common/common.h Thu Dec 21 14:09:06 2017 (r327061) +++ head/sys/dev/cxgbe/common/common.h Thu Dec 21 15:19:43 2017 (r327062) @@ -44,6 +44,7 @@ enum { EC_LEN = 16, /* E/C length */ ID_LEN = 16, /* ID length */ PN_LEN = 16, /* Part Number length */ + MD_LEN = 16, /* MFG diags version length */ MACADDR_LEN = 12, /* MAC Address length */ }; @@ -258,6 +259,7 @@ struct vpd_params { u8 id[ID_LEN + 1]; u8 pn[PN_LEN + 1]; u8 na[MACADDR_LEN + 1]; + u8 md[MD_LEN + 1]; }; struct pci_params { @@ -590,7 +592,7 @@ int t4_get_vpd_version(struct adapter *adapter, u32 *v int t4_get_version_info(struct adapter *adapter); int t4_init_hw(struct adapter *adapter, u32 fw_params); const struct chip_params *t4_get_chip_params(int chipid); -int t4_prep_adapter(struct adapter *adapter, u8 *buf); +int t4_prep_adapter(struct adapter *adapter, u32 *buf); int t4_shutdown_adapter(struct adapter *adapter); int t4_init_devlog_params(struct adapter *adapter, int fw_attach); int t4_init_sge_params(struct adapter *adapter); Modified: head/sys/dev/cxgbe/common/t4_hw.c ============================================================================== --- head/sys/dev/cxgbe/common/t4_hw.c Thu Dec 21 14:09:06 2017 (r327061) +++ head/sys/dev/cxgbe/common/t4_hw.c Thu Dec 21 15:19:43 2017 (r327062) @@ -2664,13 +2664,16 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t } /* - * Partial EEPROM Vital Product Data structure. Includes only the ID and - * VPD-R sections. + * Partial EEPROM Vital Product Data structure. The VPD starts with one ID + * header followed by one or more VPD-R sections, each with its own header. */ struct t4_vpd_hdr { u8 id_tag; u8 id_len[2]; u8 id_data[ID_LEN]; +}; + +struct t4_vpdr_hdr { u8 vpdr_tag; u8 vpdr_len[2]; }; @@ -2905,32 +2908,43 @@ int t4_seeprom_wp(struct adapter *adapter, int enable) /** * get_vpd_keyword_val - Locates an information field keyword in the VPD - * @v: Pointer to buffered vpd data structure + * @vpd: Pointer to buffered vpd data structure * @kw: The keyword to search for + * @region: VPD region to search (starting from 0) * * Returns the value of the information field keyword or * -ENOENT otherwise. */ -static int get_vpd_keyword_val(const struct t4_vpd_hdr *v, const char *kw) +static int get_vpd_keyword_val(const u8 *vpd, const char *kw, int region) { - int i; - unsigned int offset , len; - const u8 *buf = (const u8 *)v; - const u8 *vpdr_len = &v->vpdr_len[0]; + int i, tag; + unsigned int offset, len; + const struct t4_vpdr_hdr *vpdr; + offset = sizeof(struct t4_vpd_hdr); - len = (u16)vpdr_len[0] + ((u16)vpdr_len[1] << 8); + vpdr = (const void *)(vpd + offset); + tag = vpdr->vpdr_tag; + len = (u16)vpdr->vpdr_len[0] + ((u16)vpdr->vpdr_len[1] << 8); + while (region--) { + offset += sizeof(struct t4_vpdr_hdr) + len; + vpdr = (const void *)(vpd + offset); + if (++tag != vpdr->vpdr_tag) + return -ENOENT; + len = (u16)vpdr->vpdr_len[0] + ((u16)vpdr->vpdr_len[1] << 8); + } + offset += sizeof(struct t4_vpdr_hdr); - if (len + sizeof(struct t4_vpd_hdr) > VPD_LEN) { + if (offset + len > VPD_LEN) { return -ENOENT; } for (i = offset; i + VPD_INFO_FLD_HDR_SIZE <= offset + len;) { - if(memcmp(buf + i , kw , 2) == 0){ + if (memcmp(vpd + i , kw , 2) == 0){ i += VPD_INFO_FLD_HDR_SIZE; return i; } - i += VPD_INFO_FLD_HDR_SIZE + buf[i+2]; + i += VPD_INFO_FLD_HDR_SIZE + vpd[i+2]; } return -ENOENT; @@ -2946,18 +2960,18 @@ static int get_vpd_keyword_val(const struct t4_vpd_hdr * Reads card parameters stored in VPD EEPROM. */ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p, - u8 *vpd) + u32 *buf) { int i, ret, addr; - int ec, sn, pn, na; + int ec, sn, pn, na, md; u8 csum; - const struct t4_vpd_hdr *v; + const u8 *vpd = (const u8 *)buf; /* * Card information normally starts at VPD_BASE but early cards had * it at 0. */ - ret = t4_seeprom_read(adapter, VPD_BASE, (u32 *)(vpd)); + ret = t4_seeprom_read(adapter, VPD_BASE, buf); if (ret) return (ret); @@ -2971,14 +2985,13 @@ static int get_vpd_params(struct adapter *adapter, str addr = *vpd == CHELSIO_VPD_UNIQUE_ID ? VPD_BASE : VPD_BASE_OLD; for (i = 0; i < VPD_LEN; i += 4) { - ret = t4_seeprom_read(adapter, addr + i, (u32 *)(vpd + i)); + ret = t4_seeprom_read(adapter, addr + i, buf++); if (ret) return ret; } - v = (const struct t4_vpd_hdr *)vpd; #define FIND_VPD_KW(var,name) do { \ - var = get_vpd_keyword_val(v , name); \ + var = get_vpd_keyword_val(vpd, name, 0); \ if (var < 0) { \ CH_ERR(adapter, "missing VPD keyword " name "\n"); \ return -EINVAL; \ @@ -3001,7 +3014,7 @@ static int get_vpd_params(struct adapter *adapter, str FIND_VPD_KW(na, "NA"); #undef FIND_VPD_KW - memcpy(p->id, v->id_data, ID_LEN); + memcpy(p->id, vpd + offsetof(struct t4_vpd_hdr, id_data), ID_LEN); strstrip(p->id); memcpy(p->ec, vpd + ec, EC_LEN); strstrip(p->ec); @@ -3015,6 +3028,14 @@ static int get_vpd_params(struct adapter *adapter, str memcpy(p->na, vpd + na, min(i, MACADDR_LEN)); strstrip((char *)p->na); + md = get_vpd_keyword_val(vpd, "VF", 1); + if (md < 0) { + snprintf(p->md, sizeof(p->md), "unknown"); + } else { + i = vpd[md - VPD_INFO_FLD_HDR_SIZE + 2]; + memcpy(p->md, vpd + md, min(i, MD_LEN)); + } + return 0; } @@ -7997,7 +8018,7 @@ const struct chip_params *t4_get_chip_params(int chipi * values for some adapter tunables, take PHYs out of reset, and * initialize the MDIO interface. */ -int t4_prep_adapter(struct adapter *adapter, u8 *buf) +int t4_prep_adapter(struct adapter *adapter, u32 *buf) { int ret; uint16_t device_id; Modified: head/sys/dev/cxgbe/t4_main.c ============================================================================== --- head/sys/dev/cxgbe/t4_main.c Thu Dec 21 14:09:06 2017 (r327061) +++ head/sys/dev/cxgbe/t4_main.c Thu Dec 21 15:19:43 2017 (r327062) @@ -836,7 +836,7 @@ t4_attach(device_t dev) struct make_dev_args mda; struct intrs_and_queues iaq; struct sge *s; - uint8_t *buf; + uint32_t *buf; #ifdef TCP_OFFLOAD int ofld_rqidx, ofld_tqidx; #endif @@ -5126,6 +5126,9 @@ t4_sysctls(struct adapter *sc) SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "ec", CTLFLAG_RD, sc->params.vpd.ec, 0, "engineering change"); + + SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "md_version", + CTLFLAG_RD, sc->params.vpd.md, 0, "manufacturing diags version"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "na", CTLFLAG_RD, sc->params.vpd.na, 0, "network address");
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712211519.vBLFJh2c092926>