Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Jul 2016 21:52:08 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r303204 - head/sys/dev/cxgbe
Message-ID:  <201607222152.u6MLq8UN002916@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Jul 22 21:52:07 2016
New Revision: 303204
URL: https://svnweb.freebsd.org/changeset/base/303204

Log:
  Install a handler for firmware work request error messages.
  
  If a driver sends an malformed or disallowed work request, the firmware
  responds with a work request error.  Previously the driver treated this is
  as an unexpected message and panicked.  Now it decodes the error message
  to aid in debugging.
  
  Reviewed by:	np (older version)
  MFC after:	1 month
  Sponsored by:	Chelsio Communications
  Differential Revision:	https://reviews.freebsd.org/D6950

Modified:
  head/sys/dev/cxgbe/t4_sge.c

Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c	Fri Jul 22 21:49:41 2016	(r303203)
+++ head/sys/dev/cxgbe/t4_sge.c	Fri Jul 22 21:52:07 2016	(r303204)
@@ -244,6 +244,7 @@ static int handle_sge_egr_update(struct 
     struct mbuf *);
 static int handle_fw_msg(struct sge_iq *, const struct rss_header *,
     struct mbuf *);
+static int t4_handle_wrerr_rpl(struct adapter *, const __be64 *);
 static void wrq_tx_drain(void *, int);
 static void drain_wrq_wr_list(struct adapter *, struct sge_wrq *);
 
@@ -402,6 +403,7 @@ t4_sge_modload(void)
 	t4_register_cpl_handler(CPL_SGE_EGR_UPDATE, handle_sge_egr_update);
 	t4_register_cpl_handler(CPL_RX_PKT, t4_eth_rx);
 	t4_register_fw_msg_handler(FW6_TYPE_CMD_RPL, t4_handle_fw_rpl);
+	t4_register_fw_msg_handler(FW6_TYPE_WRERR_RPL, t4_handle_wrerr_rpl);
 }
 
 void
@@ -4782,6 +4784,71 @@ handle_fw_msg(struct sge_iq *iq, const s
 	return (t4_fw_msg_handler[cpl->type](sc, &cpl->data[0]));
 }
 
+/**
+ *	t4_handle_wrerr_rpl - process a FW work request error message
+ *	@adap: the adapter
+ *	@rpl: start of the FW message
+ */
+static int
+t4_handle_wrerr_rpl(struct adapter *adap, const __be64 *rpl)
+{
+	u8 opcode = *(const u8 *)rpl;
+	const struct fw_error_cmd *e = (const void *)rpl;
+	unsigned int i;
+
+	if (opcode != FW_ERROR_CMD) {
+		log(LOG_ERR,
+		    "%s: Received WRERR_RPL message with opcode %#x\n",
+		    device_get_nameunit(adap->dev), opcode);
+		return (EINVAL);
+	}
+	log(LOG_ERR, "%s: FW_ERROR (%s) ", device_get_nameunit(adap->dev),
+	    G_FW_ERROR_CMD_FATAL(be32toh(e->op_to_type)) ? "fatal" :
+	    "non-fatal");
+	switch (G_FW_ERROR_CMD_TYPE(be32toh(e->op_to_type))) {
+	case FW_ERROR_TYPE_EXCEPTION:
+		log(LOG_ERR, "exception info:\n");
+		for (i = 0; i < nitems(e->u.exception.info); i++)
+			log(LOG_ERR, "%s%08x", i == 0 ? "\t" : " ",
+			    be32toh(e->u.exception.info[i]));
+		log(LOG_ERR, "\n");
+		break;
+	case FW_ERROR_TYPE_HWMODULE:
+		log(LOG_ERR, "HW module regaddr %08x regval %08x\n",
+		    be32toh(e->u.hwmodule.regaddr),
+		    be32toh(e->u.hwmodule.regval));
+		break;
+	case FW_ERROR_TYPE_WR:
+		log(LOG_ERR, "WR cidx %d PF %d VF %d eqid %d hdr:\n",
+		    be16toh(e->u.wr.cidx),
+		    G_FW_ERROR_CMD_PFN(be16toh(e->u.wr.pfn_vfn)),
+		    G_FW_ERROR_CMD_VFN(be16toh(e->u.wr.pfn_vfn)),
+		    be32toh(e->u.wr.eqid));
+		for (i = 0; i < nitems(e->u.wr.wrhdr); i++)
+			log(LOG_ERR, "%s%02x", i == 0 ? "\t" : " ",
+			    e->u.wr.wrhdr[i]);
+		log(LOG_ERR, "\n");
+		break;
+	case FW_ERROR_TYPE_ACL:
+		log(LOG_ERR, "ACL cidx %d PF %d VF %d eqid %d %s",
+		    be16toh(e->u.acl.cidx),
+		    G_FW_ERROR_CMD_PFN(be16toh(e->u.acl.pfn_vfn)),
+		    G_FW_ERROR_CMD_VFN(be16toh(e->u.acl.pfn_vfn)),
+		    be32toh(e->u.acl.eqid),
+		    G_FW_ERROR_CMD_MV(be16toh(e->u.acl.mv_pkd)) ? "vlanid" :
+		    "MAC");
+		for (i = 0; i < nitems(e->u.acl.val); i++)
+			log(LOG_ERR, " %02x", e->u.acl.val[i]);
+		log(LOG_ERR, "\n");
+		break;
+	default:
+		log(LOG_ERR, "type %#x\n",
+		    G_FW_ERROR_CMD_TYPE(be32toh(e->op_to_type)));
+		return (EINVAL);
+	}
+	return (0);
+}
+
 static int
 sysctl_uint16(SYSCTL_HANDLER_ARGS)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607222152.u6MLq8UN002916>