Skip site navigation (1)Skip section navigation (2)
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>