svn commit: r247670 - in stable/8: share/man/man4 sys/conf sys/dev/cxgbe sys/dev/cxgbe/common sys/dev/cxgbe/firmware sys/modules/cxgbe/firmware sys/modules/cxgbe/if_cxgbe tools/tools/cxgbetool

Navdeep Parhar np at FreeBSD.org
Sat Mar 2 21:59:09 UTC 2013


Author: np
Date: Sat Mar  2 21:59:07 2013
New Revision: 247670
URL: http://svnweb.freebsd.org/changeset/base/247670

Log:
  MFC r234831, r234833, r237263**, r237436*, r237439, r237463, r237512,
  r237587, r237799, r237819, r237831, r238028, r238054, r238313, r239102,
  r239258, r239259, r239264*, r239266, r239336, r239338*, r239339,
  r239341, r239344, r240443, r240451, r240452*, r240453, r241397, r241398,
  r241399, r241401, r241409, r241416, r241493, r244551, r244580, r245243,
  r245274*, r245276*, r245434*, r245517, r245518, r245520, r245567,
  r245933, r245935, r245936, r246093, r246385, r246575, r247062, r247122,
  r247289, r247291, r247347, r247355.
  
  This brings stable/8's cxgbe(4) up to date with what's in head right
  now.  One major difference is the missing t4_tom (TCP Offload Module);
  there are no plans to backport it to 8.
  
  Build tested with make universe (with -DMAKE_JUST_KERNELS)
  
  *  partial
  ** partial manual backport, not really an MFC

Added:
  stable/8/sys/dev/cxgbe/firmware/t4fw-1.8.4.0.bin.uu
     - copied unchanged from r247289, head/sys/dev/cxgbe/firmware/t4fw-1.8.4.0.bin.uu
Deleted:
  stable/8/sys/dev/cxgbe/common/jhash.h
Modified:
  stable/8/share/man/man4/cxgbe.4
  stable/8/sys/conf/files
  stable/8/sys/conf/kern.pre.mk
  stable/8/sys/dev/cxgbe/adapter.h
  stable/8/sys/dev/cxgbe/common/common.h
  stable/8/sys/dev/cxgbe/common/t4_hw.c
  stable/8/sys/dev/cxgbe/common/t4_hw.h
  stable/8/sys/dev/cxgbe/common/t4_msg.h
  stable/8/sys/dev/cxgbe/firmware/t4fw_cfg.txt
  stable/8/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt
  stable/8/sys/dev/cxgbe/firmware/t4fw_interface.h
  stable/8/sys/dev/cxgbe/offload.h
  stable/8/sys/dev/cxgbe/osdep.h
  stable/8/sys/dev/cxgbe/t4_ioctl.h
  stable/8/sys/dev/cxgbe/t4_l2t.c
  stable/8/sys/dev/cxgbe/t4_l2t.h
  stable/8/sys/dev/cxgbe/t4_main.c
  stable/8/sys/dev/cxgbe/t4_sge.c
  stable/8/sys/modules/cxgbe/firmware/Makefile
  stable/8/sys/modules/cxgbe/if_cxgbe/Makefile
  stable/8/tools/tools/cxgbetool/cxgbetool.c
Directory Properties:
  stable/8/share/man/man4/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/conf/   (props changed)
  stable/8/sys/dev/   (props changed)
  stable/8/sys/dev/cxgbe/   (props changed)
  stable/8/sys/modules/   (props changed)
  stable/8/tools/tools/cxgbetool/   (props changed)

Modified: stable/8/share/man/man4/cxgbe.4
==============================================================================
--- stable/8/share/man/man4/cxgbe.4	Sat Mar  2 21:16:40 2013	(r247669)
+++ stable/8/share/man/man4/cxgbe.4	Sat Mar  2 21:59:07 2013	(r247670)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2011, Chelsio Inc
+.\" Copyright (c) 2011-2012, Chelsio Inc
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -145,10 +145,9 @@ dev.cxgbe.X.holdoff_tmr_idx sysctl.
 The packet-count index value to use to delay interrupts.
 The packet-count list has the values 1, 8, 16, and 32 by default
 and the index selects a value from this list.
-The default value is 2 for both 10Gb and 1Gb ports, which means 16
-packets (or the holdoff timer going off) before an interrupt is
-generated.
--1 disables packet counting.
+The default value is -1 for both 10Gb and 1Gb ports, which means packet
+counting is disabled and interrupts are generated based solely on the
+holdoff timer value.
 Different cxgbe interfaces can be assigned different values via the
 dev.cxgbe.X.holdoff_pktc_idx sysctl.
 This sysctl works only when the interface has never been marked up (as done by
@@ -179,6 +178,15 @@ Bit 0 represents INTx (line interrupts),
 The default is 7 (all allowed).
 The driver will select the best possible type out of the allowed types by
 itself.
+.It Va hw.cxgbe.fw_install
+0 prohibits the driver from installing a firmware on the card.
+1 allows the driver to install a new firmware if internal driver
+heuristics indicate that the new firmware is preferable to the one
+already on the card.
+2 instructs the driver to always install the new firmware on the card as
+long as it is compatible with the driver and is a different version than
+the one already on the card.
+The default is 1.
 .It Va hw.cxgbe.config_file
 Select a pre-packaged device configuration file.
 A configuration file contains a recipe for partitioning and configuring the

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files	Sat Mar  2 21:16:40 2013	(r247669)
+++ stable/8/sys/conf/files	Sat Mar  2 21:59:07 2013	(r247670)
@@ -815,6 +815,40 @@ dev/cxgbe/t4_l2t.c		optional cxgbe pci \
 	compile-with "${NORMAL_C} -I$S/dev/cxgbe"
 dev/cxgbe/common/t4_hw.c	optional cxgbe pci \
 	compile-with "${NORMAL_C} -I$S/dev/cxgbe"
+t4fw_cfg.c		optional cxgbe					\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk t4fw_cfg.fw:t4fw_cfg t4fw_cfg_uwire.fw:t4fw_cfg_uwire t4fw.fw:t4fw -mt4fw_cfg -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"t4fw_cfg.c"
+t4fw_cfg.fwo		optional cxgbe					\
+	dependency	"t4fw_cfg.fw"					\
+	compile-with	"${NORMAL_FWO}"					\
+	no-implicit-rule						\
+	clean		"t4fw_cfg.fwo"
+t4fw_cfg.fw		optional cxgbe					\
+	dependency	"$S/dev/cxgbe/firmware/t4fw_cfg.txt"		\
+	compile-with	"${CP} ${.ALLSRC} ${.TARGET}"			\
+	no-obj no-implicit-rule						\
+	clean		"t4fw_cfg.fw"
+t4fw_cfg_uwire.fwo	optional cxgbe					\
+	dependency	"t4fw_cfg_uwire.fw"				\
+	compile-with	"${NORMAL_FWO}"					\
+	no-implicit-rule						\
+	clean		"t4fw_cfg_uwire.fwo"
+t4fw_cfg_uwire.fw	optional cxgbe					\
+	dependency	"$S/dev/cxgbe/firmware/t4fw_cfg_uwire.txt"	\
+	compile-with	"${CP} ${.ALLSRC} ${.TARGET}"			\
+	no-obj no-implicit-rule						\
+	clean		"t4fw_cfg_uwire.fw"
+t4fw.fwo		optional cxgbe					\
+	dependency	"t4fw.fw"					\
+	compile-with	"${NORMAL_FWO}"					\
+	no-implicit-rule						\
+	clean		"t4fw.fwo"
+t4fw.fw			optional cxgbe					\
+	dependency	"$S/dev/cxgbe/firmware/t4fw-1.8.4.0.bin.uu"	\
+	compile-with	"${NORMAL_FW}"					\
+	no-obj no-implicit-rule						\
+	clean		"t4fw.fw"
 dev/cy/cy.c			optional cy
 dev/cy/cy_isa.c			optional cy isa
 dev/cy/cy_pci.c			optional cy pci

Modified: stable/8/sys/conf/kern.pre.mk
==============================================================================
--- stable/8/sys/conf/kern.pre.mk	Sat Mar  2 21:16:40 2013	(r247669)
+++ stable/8/sys/conf/kern.pre.mk	Sat Mar  2 21:59:07 2013	(r247670)
@@ -15,6 +15,7 @@ LDSCRIPT?=	$S/conf/${LDSCRIPT_NAME}
 M=	${MACHINE_ARCH}
 
 AWK?=		awk
+CP?=		cp
 LINT?=		lint
 NM?=		nm
 OBJCOPY?=	objcopy

Modified: stable/8/sys/dev/cxgbe/adapter.h
==============================================================================
--- stable/8/sys/dev/cxgbe/adapter.h	Sat Mar  2 21:16:40 2013	(r247669)
+++ stable/8/sys/dev/cxgbe/adapter.h	Sat Mar  2 21:59:07 2013	(r247670)
@@ -44,6 +44,7 @@
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_media.h>
+#include <netinet/in.h>
 #include <netinet/tcp_lro.h>
 
 #include "offload.h"
@@ -77,6 +78,15 @@ prefetch(void *x)
 #define SBUF_DRAIN 1
 #endif
 
+#if (__FreeBSD_version < 900000)
+#define IFCAP_RXCSUM_IPV6 0
+#define IFCAP_TXCSUM_IPV6 0
+#define CSUM_DATA_VALID_IPV6 0
+#define IFCAP_HWCSUM_IPV6 0
+#define CSUM_UDP_IPV6 0
+#define CSUM_TCP_IPV6 0
+#endif
+
 #ifdef __amd64__
 /* XXX: need systemwide bus_space_read_8/bus_space_write_8 */
 static __inline uint64_t
@@ -134,6 +144,7 @@ enum {
 #else
 	FL_BUF_SIZES = 3,	/* cluster, jumbo9k, jumbo16k */
 #endif
+	OFLD_BUF_SIZE = MJUM16BYTES,	/* size of fl buffer for TOE rxq */
 
 	CTRL_EQ_QSIZE = 128,
 
@@ -142,6 +153,12 @@ enum {
 	TX_WR_FLITS = SGE_MAX_WR_LEN / 8
 };
 
+#ifdef T4_PKT_TIMESTAMP
+#define RX_COPY_THRESHOLD (MINCLSIZE - 8)
+#else
+#define RX_COPY_THRESHOLD MINCLSIZE
+#endif
+
 enum {
 	/* adapter intr_type */
 	INTR_INTX	= (1 << 0),
@@ -150,12 +167,23 @@ enum {
 };
 
 enum {
+	/* flags understood by begin_synchronized_op */
+	HOLD_LOCK	= (1 << 0),
+	SLEEP_OK	= (1 << 1),
+	INTR_OK		= (1 << 2),
+
+	/* flags understood by end_synchronized_op */
+	LOCK_HELD	= HOLD_LOCK,
+};
+
+enum {
 	/* adapter flags */
 	FULL_INIT_DONE	= (1 << 0),
 	FW_OK		= (1 << 1),
 	INTR_DIRECT	= (1 << 2),	/* direct interrupts for everything */
 	MASTER_PF	= (1 << 3),
 	ADAP_SYSCTL_CTX	= (1 << 4),
+	TOM_INIT_DONE	= (1 << 5),
 
 	CXGBE_BUSY	= (1 << 9),
 
@@ -165,11 +193,11 @@ enum {
 	PORT_SYSCTL_CTX	= (1 << 2),
 };
 
-#define IS_DOOMED(pi)	(pi->flags & DOOMED)
-#define SET_DOOMED(pi)	do {pi->flags |= DOOMED;} while (0)
-#define IS_BUSY(sc)	(sc->flags & CXGBE_BUSY)
-#define SET_BUSY(sc)	do {sc->flags |= CXGBE_BUSY;} while (0)
-#define CLR_BUSY(sc)	do {sc->flags &= ~CXGBE_BUSY;} while (0)
+#define IS_DOOMED(pi)	((pi)->flags & DOOMED)
+#define SET_DOOMED(pi)	do {(pi)->flags |= DOOMED;} while (0)
+#define IS_BUSY(sc)	((sc)->flags & CXGBE_BUSY)
+#define SET_BUSY(sc)	do {(sc)->flags |= CXGBE_BUSY;} while (0)
+#define CLR_BUSY(sc)	do {(sc)->flags &= ~CXGBE_BUSY;} while (0)
 
 struct port_info {
 	device_t dev;
@@ -198,7 +226,7 @@ struct port_info {
 	int first_txq;	/* index of first tx queue */
 	int nrxq;	/* # of rx queues */
 	int first_rxq;	/* index of first rx queue */
-#ifndef TCP_OFFLOAD_DISABLE
+#ifdef TCP_OFFLOAD
 	int nofldtxq;		/* # of offload tx queues */
 	int first_ofld_txq;	/* index of first offload tx queue */
 	int nofldrxq;		/* # of offload rx queues */
@@ -271,7 +299,6 @@ struct sge_iq {
 	bus_dma_tag_t desc_tag;
 	bus_dmamap_t desc_map;
 	bus_addr_t ba;		/* bus address of descriptor ring */
-	char lockname[16];
 	uint32_t flags;
 	uint16_t abs_id;	/* absolute SGE id for the iq */
 	int8_t   intr_pktc_idx;	/* packet count threshold index */
@@ -295,7 +322,7 @@ struct sge_iq {
 enum {
 	EQ_CTRL		= 1,
 	EQ_ETH		= 2,
-#ifndef TCP_OFFLOAD_DISABLE
+#ifdef TCP_OFFLOAD
 	EQ_OFLD		= 3,
 #endif
 
@@ -388,7 +415,7 @@ struct sge_txq {
 	/* stats for common events first */
 
 	uint64_t txcsum;	/* # of times hardware assisted with checksum */
-	uint64_t tso_wrs;	/* # of IPv4 TSO work requests */
+	uint64_t tso_wrs;	/* # of TSO work requests */
 	uint64_t vlan_insertion;/* # of times VLAN tag was inserted */
 	uint64_t imm_wrs;	/* # of work requests with immediate data */
 	uint64_t sgl_wrs;	/* # of work requests with direct SGL */
@@ -408,7 +435,7 @@ struct sge_rxq {
 	struct sge_fl fl;	/* MUST follow iq */
 
 	struct ifnet *ifp;	/* the interface this rxq belongs to */
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	struct lro_ctrl lro;	/* LRO state */
 #endif
 
@@ -421,14 +448,36 @@ struct sge_rxq {
 
 } __aligned(CACHE_LINE_SIZE);
 
-#ifndef TCP_OFFLOAD_DISABLE
+static inline struct sge_rxq *
+iq_to_rxq(struct sge_iq *iq)
+{
+
+	return (member2struct(sge_rxq, iq, iq));
+}
+
+
+#ifdef TCP_OFFLOAD
 /* ofld_rxq: SGE ingress queue + SGE free list + miscellaneous items */
 struct sge_ofld_rxq {
 	struct sge_iq iq;	/* MUST be first */
 	struct sge_fl fl;	/* MUST follow iq */
 } __aligned(CACHE_LINE_SIZE);
+
+static inline struct sge_ofld_rxq *
+iq_to_ofld_rxq(struct sge_iq *iq)
+{
+
+	return (member2struct(sge_ofld_rxq, iq, iq));
+}
 #endif
 
+struct wrqe {
+	STAILQ_ENTRY(wrqe) link;
+	struct sge_wrq *wrq;
+	int wr_len;
+	uint64_t wr[] __aligned(16);
+};
+
 /*
  * wrq: SGE egress queue that is given prebuilt work requests.  Both the control
  * and offload tx queues are of this type.
@@ -437,8 +486,9 @@ struct sge_wrq {
 	struct sge_eq eq;	/* MUST be first */
 
 	struct adapter *adapter;
-	struct mbuf *head;	/* held up due to lack of descriptors */
-	struct mbuf *tail;	/* valid only if head is valid */
+
+	/* List of WRs held up due to lack of tx descriptors */
+	STAILQ_HEAD(, wrqe) wr_list;
 
 	/* stats for common events first */
 
@@ -456,7 +506,7 @@ struct sge {
 
 	int nrxq;	/* total # of Ethernet rx queues */
 	int ntxq;	/* total # of Ethernet tx tx queues */
-#ifndef TCP_OFFLOAD_DISABLE
+#ifdef TCP_OFFLOAD
 	int nofldrxq;	/* total # of TOE rx queues */
 	int nofldtxq;	/* total # of TOE tx queues */
 #endif
@@ -468,7 +518,7 @@ struct sge {
 	struct sge_wrq *ctrlq;	/* Control queues */
 	struct sge_txq *txq;	/* NIC tx queues */
 	struct sge_rxq *rxq;	/* NIC rx queues */
-#ifndef TCP_OFFLOAD_DISABLE
+#ifdef TCP_OFFLOAD
 	struct sge_wrq *ofld_txq;	/* TOE tx queues */
 	struct sge_ofld_rxq *ofld_rxq;	/* TOE rx queues */
 #endif
@@ -482,6 +532,8 @@ struct sge {
 struct rss_header;
 typedef int (*cpl_handler_t)(struct sge_iq *, const struct rss_header *,
     struct mbuf *);
+typedef int (*an_handler_t)(struct sge_iq *, const struct rsp_ctrl *);
+typedef int (*fw_msg_handler_t)(struct adapter *, const __be64 *);
 
 struct adapter {
 	SLIST_ENTRY(adapter) link;
@@ -518,21 +570,22 @@ struct adapter {
 	uint8_t chan_map[NCHAN];
 	uint32_t filter_mode;
 
-#ifndef TCP_OFFLOAD_DISABLE
-	struct uld_softc tom;
+#ifdef TCP_OFFLOAD
+	void *tom_softc;	/* (struct tom_data *) */
 	struct tom_tunables tt;
 #endif
 	struct l2t_data *l2t;	/* L2 table */
 	struct tid_info tids;
 
 	int open_device_map;
-#ifndef TCP_OFFLOAD_DISABLE
+#ifdef TCP_OFFLOAD
 	int offload_map;
 #endif
 	int flags;
 
 	char fw_version[32];
-	unsigned int cfcsum;
+	char cfg_file[32];
+	u_int cfcsum;
 	struct adapter_params params;
 	struct t4_virt_res vres;
 
@@ -553,7 +606,14 @@ struct adapter {
 	TAILQ_HEAD(, sge_fl) sfl;
 	struct callout sfl_callout;
 
-	cpl_handler_t cpl_handler[256] __aligned(CACHE_LINE_SIZE);
+	an_handler_t an_handler __aligned(CACHE_LINE_SIZE);
+	fw_msg_handler_t fw_msg_handler[5];	/* NUM_FW6_TYPES */
+	cpl_handler_t cpl_handler[0xef];	/* NUM_CPL_CMDS */
+
+#ifdef INVARIANTS
+	const char *last_op;
+	const void *last_op_thr;
+#endif
 };
 
 #define ADAPTER_LOCK(sc)		mtx_lock(&(sc)->sc_lock)
@@ -561,6 +621,12 @@ struct adapter {
 #define ADAPTER_LOCK_ASSERT_OWNED(sc)	mtx_assert(&(sc)->sc_lock, MA_OWNED)
 #define ADAPTER_LOCK_ASSERT_NOTOWNED(sc) mtx_assert(&(sc)->sc_lock, MA_NOTOWNED)
 
+/* XXX: not bulletproof, but much better than nothing */
+#define ASSERT_SYNCHRONIZED_OP(sc)	\
+    KASSERT(IS_BUSY(sc) && \
+	(mtx_owned(&(sc)->sc_lock) || sc->last_op_thr == curthread), \
+	("%s: operation not synchronized.", __func__))
+
 #define PORT_LOCK(pi)			mtx_lock(&(pi)->pi_lock)
 #define PORT_UNLOCK(pi)			mtx_unlock(&(pi)->pi_lock)
 #define PORT_LOCK_ASSERT_OWNED(pi)	mtx_assert(&(pi)->pi_lock, MA_OWNED)
@@ -589,18 +655,18 @@ struct adapter {
 #define TXQ_LOCK_ASSERT_OWNED(txq)	EQ_LOCK_ASSERT_OWNED(&(txq)->eq)
 #define TXQ_LOCK_ASSERT_NOTOWNED(txq)	EQ_LOCK_ASSERT_NOTOWNED(&(txq)->eq)
 
-#define for_each_txq(pi, iter, txq) \
-	txq = &pi->adapter->sge.txq[pi->first_txq]; \
-	for (iter = 0; iter < pi->ntxq; ++iter, ++txq)
-#define for_each_rxq(pi, iter, rxq) \
-	rxq = &pi->adapter->sge.rxq[pi->first_rxq]; \
-	for (iter = 0; iter < pi->nrxq; ++iter, ++rxq)
-#define for_each_ofld_txq(pi, iter, ofld_txq) \
-	ofld_txq = &pi->adapter->sge.ofld_txq[pi->first_ofld_txq]; \
-	for (iter = 0; iter < pi->nofldtxq; ++iter, ++ofld_txq)
-#define for_each_ofld_rxq(pi, iter, ofld_rxq) \
-	ofld_rxq = &pi->adapter->sge.ofld_rxq[pi->first_ofld_rxq]; \
-	for (iter = 0; iter < pi->nofldrxq; ++iter, ++ofld_rxq)
+#define for_each_txq(pi, iter, q) \
+	for (q = &pi->adapter->sge.txq[pi->first_txq], iter = 0; \
+	    iter < pi->ntxq; ++iter, ++q)
+#define for_each_rxq(pi, iter, q) \
+	for (q = &pi->adapter->sge.rxq[pi->first_rxq], iter = 0; \
+	    iter < pi->nrxq; ++iter, ++q)
+#define for_each_ofld_txq(pi, iter, q) \
+	for (q = &pi->adapter->sge.ofld_txq[pi->first_ofld_txq], iter = 0; \
+	    iter < pi->nofldtxq; ++iter, ++q)
+#define for_each_ofld_rxq(pi, iter, q) \
+	for (q = &pi->adapter->sge.ofld_rxq[pi->first_ofld_rxq], iter = 0; \
+	    iter < pi->nofldrxq; ++iter, ++q)
 
 /* One for errors, one for firmware events */
 #define T4_EXTRA_INTR 2
@@ -608,82 +674,96 @@ struct adapter {
 static inline uint32_t
 t4_read_reg(struct adapter *sc, uint32_t reg)
 {
+
 	return bus_space_read_4(sc->bt, sc->bh, reg);
 }
 
 static inline void
 t4_write_reg(struct adapter *sc, uint32_t reg, uint32_t val)
 {
+
 	bus_space_write_4(sc->bt, sc->bh, reg, val);
 }
 
 static inline uint64_t
 t4_read_reg64(struct adapter *sc, uint32_t reg)
 {
+
 	return t4_bus_space_read_8(sc->bt, sc->bh, reg);
 }
 
 static inline void
 t4_write_reg64(struct adapter *sc, uint32_t reg, uint64_t val)
 {
+
 	t4_bus_space_write_8(sc->bt, sc->bh, reg, val);
 }
 
 static inline void
 t4_os_pci_read_cfg1(struct adapter *sc, int reg, uint8_t *val)
 {
+
 	*val = pci_read_config(sc->dev, reg, 1);
 }
 
 static inline void
 t4_os_pci_write_cfg1(struct adapter *sc, int reg, uint8_t val)
 {
+
 	pci_write_config(sc->dev, reg, val, 1);
 }
 
 static inline void
 t4_os_pci_read_cfg2(struct adapter *sc, int reg, uint16_t *val)
 {
+
 	*val = pci_read_config(sc->dev, reg, 2);
 }
 
 static inline void
 t4_os_pci_write_cfg2(struct adapter *sc, int reg, uint16_t val)
 {
+
 	pci_write_config(sc->dev, reg, val, 2);
 }
 
 static inline void
 t4_os_pci_read_cfg4(struct adapter *sc, int reg, uint32_t *val)
 {
+
 	*val = pci_read_config(sc->dev, reg, 4);
 }
 
 static inline void
 t4_os_pci_write_cfg4(struct adapter *sc, int reg, uint32_t val)
 {
+
 	pci_write_config(sc->dev, reg, val, 4);
 }
 
 static inline struct port_info *
 adap2pinfo(struct adapter *sc, int idx)
 {
+
 	return (sc->port[idx]);
 }
 
 static inline void
 t4_os_set_hw_addr(struct adapter *sc, int idx, uint8_t hw_addr[])
 {
+
 	bcopy(hw_addr, sc->port[idx]->hw_addr, ETHER_ADDR_LEN);
 }
 
 static inline bool is_10G_port(const struct port_info *pi)
 {
+
 	return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) != 0);
 }
 
 static inline int tx_resume_threshold(struct sge_eq *eq)
 {
+
 	return (eq->qsize / 4);
 }
 
@@ -697,6 +777,11 @@ void t4_os_portmod_changed(const struct 
 void t4_os_link_changed(struct adapter *, int, int);
 void t4_iterate(void (*)(struct adapter *, void *), void *);
 int t4_register_cpl_handler(struct adapter *, int, cpl_handler_t);
+int t4_register_an_handler(struct adapter *, an_handler_t);
+int t4_register_fw_msg_handler(struct adapter *, int, fw_msg_handler_t);
+int t4_filter_rpl(struct sge_iq *, const struct rss_header *, struct mbuf *);
+int begin_synchronized_op(struct adapter *, struct port_info *, int, char *);
+void end_synchronized_op(struct adapter *, int);
 
 /* t4_sge.c */
 void t4_sge_modload(void);
@@ -713,21 +798,45 @@ void t4_intr_all(void *);
 void t4_intr(void *);
 void t4_intr_err(void *);
 void t4_intr_evt(void *);
-int t4_mgmt_tx(struct adapter *, struct mbuf *);
-int t4_wrq_tx_locked(struct adapter *, struct sge_wrq *, struct mbuf *);
+void t4_wrq_tx_locked(struct adapter *, struct sge_wrq *, struct wrqe *);
 int t4_eth_tx(struct ifnet *, struct sge_txq *, struct mbuf *);
 void t4_update_fl_bufsize(struct ifnet *);
 int can_resume_tx(struct sge_eq *);
 
-static inline int t4_wrq_tx(struct adapter *sc, struct sge_wrq *wrq, struct mbuf *m)
+static inline struct wrqe *
+alloc_wrqe(int wr_len, struct sge_wrq *wrq)
 {
-	int rc;
+	int len = offsetof(struct wrqe, wr) + wr_len;
+	struct wrqe *wr;
+
+	wr = malloc(len, M_CXGBE, M_NOWAIT);
+	if (__predict_false(wr == NULL))
+		return (NULL);
+	wr->wr_len = wr_len;
+	wr->wrq = wrq;
+	return (wr);
+}
+
+static inline void *
+wrtod(struct wrqe *wr)
+{
+	return (&wr->wr[0]);
+}
+
+static inline void
+free_wrqe(struct wrqe *wr)
+{
+	free(wr, M_CXGBE);
+}
+
+static inline void
+t4_wrq_tx(struct adapter *sc, struct wrqe *wr)
+{
+	struct sge_wrq *wrq = wr->wrq;
 
 	TXQ_LOCK(wrq);
-	rc = t4_wrq_tx_locked(sc, wrq, m);
+	t4_wrq_tx_locked(sc, wrq, wr);
 	TXQ_UNLOCK(wrq);
-	return (rc);
 }
 
-
 #endif

Modified: stable/8/sys/dev/cxgbe/common/common.h
==============================================================================
--- stable/8/sys/dev/cxgbe/common/common.h	Sat Mar  2 21:16:40 2013	(r247669)
+++ stable/8/sys/dev/cxgbe/common/common.h	Sat Mar  2 21:59:07 2013	(r247670)
@@ -38,6 +38,8 @@ enum {
 	SERNUM_LEN     = 24,    /* Serial # length */
 	EC_LEN         = 16,    /* E/C length */
 	ID_LEN         = 16,    /* ID length */
+	PN_LEN         = 16,    /* Part Number length */
+	MACADDR_LEN    = 12,    /* MAC Address length */
 };
 
 enum { MEM_EDC0, MEM_EDC1, MEM_MC };
@@ -62,8 +64,14 @@ enum {
 };
 
 #define FW_VERSION_MAJOR 1
-#define FW_VERSION_MINOR 4
-#define FW_VERSION_MICRO 16
+#define FW_VERSION_MINOR 8
+#define FW_VERSION_MICRO 4
+#define FW_VERSION_BUILD 0
+
+#define FW_VERSION (V_FW_HDR_FW_VER_MAJOR(FW_VERSION_MAJOR) | \
+    V_FW_HDR_FW_VER_MINOR(FW_VERSION_MINOR) | \
+    V_FW_HDR_FW_VER_MICRO(FW_VERSION_MICRO) | \
+    V_FW_HDR_FW_VER_BUILD(FW_VERSION_BUILD))
 
 struct port_stats {
 	u64 tx_octets;            /* total # of octets in good frames */
@@ -219,6 +227,8 @@ struct vpd_params {
 	u8 ec[EC_LEN + 1];
 	u8 sn[SERNUM_LEN + 1];
 	u8 id[ID_LEN + 1];
+	u8 pn[PN_LEN + 1];
+	u8 na[MACADDR_LEN + 1];
 };
 
 struct pci_params {
@@ -356,6 +366,8 @@ void t4_write_indirect(struct adapter *a
 		       unsigned int data_reg, const u32 *vals,
 		       unsigned int nregs, unsigned int start_idx);
 
+u32 t4_hw_pci_read_cfg4(adapter_t *adapter, int reg);
+
 struct fw_filter_wr;
 
 void t4_intr_enable(struct adapter *adapter);
@@ -374,7 +386,7 @@ int t4_seeprom_wp(struct adapter *adapte
 int t4_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords,
 		  u32 *data, int byte_oriented);
 int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
-int t4_load_boot(struct adapter *adap, const u8 *boot_data,
+int t4_load_boot(struct adapter *adap, u8 *boot_data,
                  unsigned int boot_addr, unsigned int size);
 unsigned int t4_flash_cfg_addr(struct adapter *adapter);
 int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size);
@@ -431,6 +443,9 @@ int t4_mem_read(struct adapter *adap, in
 		__be32 *data);
 
 void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
+void t4_get_port_stats_offset(struct adapter *adap, int idx,
+		struct port_stats *stats,
+		struct port_stats *offset);
 void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p);
 void t4_clr_port_stats(struct adapter *adap, int idx);
 
@@ -472,6 +487,10 @@ int t4_fw_hello(struct adapter *adap, un
 		enum dev_master master, enum dev_state *state);
 int t4_fw_bye(struct adapter *adap, unsigned int mbox);
 int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset);
+int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force);
+int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset);
+int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
+		  const u8 *fw_data, unsigned int size, int force);
 int t4_fw_initialize(struct adapter *adap, unsigned int mbox);
 int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
 		    unsigned int vf, unsigned int nparams, const u32 *params,
@@ -484,6 +503,10 @@ int t4_cfg_pfvf(struct adapter *adap, un
 		unsigned int rxqi, unsigned int rxq, unsigned int tc,
 		unsigned int vi, unsigned int cmask, unsigned int pmask,
 		unsigned int exactf, unsigned int rcaps, unsigned int wxcaps);
+int t4_alloc_vi_func(struct adapter *adap, unsigned int mbox,
+		     unsigned int port, unsigned int pf, unsigned int vf,
+		     unsigned int nmac, u8 *mac, unsigned int *rss_size,
+		     unsigned int portfunc, unsigned int idstype);
 int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
 		unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
 		unsigned int *rss_size);
@@ -504,6 +527,8 @@ int t4_enable_vi(struct adapter *adap, u
 		 bool rx_en, bool tx_en);
 int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
 		     unsigned int nblinks);
+int t4_i2c_rd(struct adapter *adap, unsigned int mbox, unsigned int port_id,
+	      u8 dev_addr, u8 offset, u8 *valp);
 int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
 	       unsigned int mmd, unsigned int reg, unsigned int *valp);
 int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
@@ -524,5 +549,7 @@ int t4_sge_ctxt_rd(struct adapter *adap,
 		   enum ctxt_type ctype, u32 *data);
 int t4_sge_ctxt_rd_bd(struct adapter *adap, unsigned int cid, enum ctxt_type ctype,
 		      u32 *data);
+int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox);
 int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
+int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, u32 addr, u32 val);
 #endif /* __CHELSIO_COMMON_H */

Modified: stable/8/sys/dev/cxgbe/common/t4_hw.c
==============================================================================
--- stable/8/sys/dev/cxgbe/common/t4_hw.c	Sat Mar  2 21:16:40 2013	(r247669)
+++ stable/8/sys/dev/cxgbe/common/t4_hw.c	Sat Mar  2 21:59:07 2013	(r247670)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2011 Chelsio Communications, Inc.
+ * Copyright (c) 2012 Chelsio Communications, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,13 +27,20 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_inet.h"
+
 #include "common.h"
 #include "t4_regs.h"
 #include "t4_regs_values.h"
 #include "firmware/t4fw_interface.h"
 
 #undef msleep
-#define msleep(x) pause("t4hw", (x) * hz / 1000)
+#define msleep(x) do { \
+	if (cold) \
+		DELAY((x) * 1000); \
+	else \
+		pause("t4hw", (x) * hz / 1000); \
+} while (0)
 
 /**
  *	t4_wait_op_done_val - wait until an operation is completed
@@ -133,6 +140,50 @@ void t4_write_indirect(struct adapter *a
 }
 
 /*
+ * Read a 32-bit PCI Configuration Space register via the PCI-E backdoor
+ * mechanism.  This guarantees that we get the real value even if we're
+ * operating within a Virtual Machine and the Hypervisor is trapping our
+ * Configuration Space accesses.
+ */
+u32 t4_hw_pci_read_cfg4(adapter_t *adap, int reg)
+{
+	t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ,
+		     F_ENABLE | F_LOCALCFG | V_FUNCTION(adap->pf) |
+		     V_REGISTER(reg));
+	return t4_read_reg(adap, A_PCIE_CFG_SPACE_DATA);
+}
+
+/*
+ *	t4_report_fw_error - report firmware error
+ *	@adap: the adapter
+ *
+ *	The adapter firmware can indicate error conditions to the host.
+ *	This routine prints out the reason for the firmware error (as
+ *	reported by the firmware).
+ */
+static void t4_report_fw_error(struct adapter *adap)
+{
+	static const char *reason[] = {
+		"Crash",			/* PCIE_FW_EVAL_CRASH */
+		"During Device Preparation",	/* PCIE_FW_EVAL_PREP */
+		"During Device Configuration",	/* PCIE_FW_EVAL_CONF */
+		"During Device Initialization",	/* PCIE_FW_EVAL_INIT */
+		"Unexpected Event",		/* PCIE_FW_EVAL_UNEXPECTEDEVENT */
+		"Insufficient Airflow",		/* PCIE_FW_EVAL_OVERHEAT */
+		"Device Shutdown",		/* PCIE_FW_EVAL_DEVICESHUTDOWN */
+		"Reserved",			/* reserved */
+	};
+	u32 pcie_fw;
+
+	pcie_fw = t4_read_reg(adap, A_PCIE_FW);
+	if (!(pcie_fw & F_PCIE_FW_ERR))
+		CH_ERR(adap, "Firmware error report called with no error\n");
+	else
+		CH_ERR(adap, "Firmware reports adapter error: %s\n",
+		       reason[G_PCIE_FW_EVAL(pcie_fw)]);
+}
+
+/*
  * Get the reply to a mailbox command and store it in @rpl in big-endian order.
  */
 static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
@@ -194,7 +245,6 @@ int t4_wr_mbox_meat(struct adapter *adap
 	u64 res;
 	int i, ms, delay_idx;
 	const __be64 *p = cmd;
-
 	u32 data_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_DATA);
 	u32 ctl_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_CTRL);
 
@@ -247,8 +297,15 @@ int t4_wr_mbox_meat(struct adapter *adap
 		}
 	}
 
+	/*
+	 * We timed out waiting for a reply to our mailbox command.  Report
+	 * the error and also check to see if the firmware reported any
+	 * errors ...
+	 */
 	CH_ERR(adap, "command %#x in mailbox %d timed out\n",
 	       *(const u8 *)cmd, mbox);
+	if (t4_read_reg(adap, A_PCIE_FW) & F_PCIE_FW_ERR)
+		t4_report_fw_error(adap);
 	return -ETIMEDOUT;
 }
 
@@ -281,7 +338,7 @@ int t4_mc_read(struct adapter *adap, u32
 #define MC_DATA(i) MC_BIST_STATUS_REG(A_MC_BIST_STATUS_RDATA, i)
 
 	for (i = 15; i >= 0; i--)
-		*data++ = htonl(t4_read_reg(adap, MC_DATA(i)));
+		*data++ = ntohl(t4_read_reg(adap, MC_DATA(i)));
 	if (ecc)
 		*ecc = t4_read_reg64(adap, MC_DATA(16));
 #undef MC_DATA
@@ -319,7 +376,7 @@ int t4_edc_read(struct adapter *adap, in
 #define EDC_DATA(i) (EDC_BIST_STATUS_REG(A_EDC_BIST_STATUS_RDATA, i) + idx)
 
 	for (i = 15; i >= 0; i--)
-		*data++ = htonl(t4_read_reg(adap, EDC_DATA(i)));
+		*data++ = ntohl(t4_read_reg(adap, EDC_DATA(i)));
 	if (ecc)
 		*ecc = t4_read_reg64(adap, EDC_DATA(16));
 #undef EDC_DATA
@@ -564,7 +621,7 @@ static int get_vpd_keyword_val(const str
 static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
 {
 	int i, ret, addr;
-	int ec, sn;
+	int ec, sn, pn, na;
 	u8 vpd[VPD_LEN], csum;
 	const struct t4_vpd_hdr *v;
 
@@ -600,6 +657,8 @@ static int get_vpd_params(struct adapter
 	}
 	FIND_VPD_KW(ec, "EC");
 	FIND_VPD_KW(sn, "SN");
+	FIND_VPD_KW(pn, "PN");
+	FIND_VPD_KW(na, "NA");
 #undef FIND_VPD_KW
 
 	memcpy(p->id, v->id_data, ID_LEN);
@@ -609,6 +668,10 @@ static int get_vpd_params(struct adapter
 	i = vpd[sn - VPD_INFO_FLD_HDR_SIZE + 2];
 	memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN));
 	strstrip(p->sn);
+	memcpy(p->pn, vpd + pn, min(i, PN_LEN));
+	strstrip((char *)p->pn);
+	memcpy(p->na, vpd + na, min(i, MACADDR_LEN));
+	strstrip((char *)p->na);
 
 	return 0;
 }
@@ -952,7 +1015,7 @@ int t4_load_cfg(struct adapter *adap, co
 	if (ret || size == 0)
 		goto out;
 
-        /* this will write to the flash up to SF_PAGE_SIZE at a time */
+	/* this will write to the flash up to SF_PAGE_SIZE at a time */
 	for (i = 0; i< size; i+= SF_PAGE_SIZE) {
 		if ( (size - i) <  SF_PAGE_SIZE) 
 			n = size - i;
@@ -1054,42 +1117,209 @@ out:
 	return ret;
 }
 
-/* BIOS boot header */
-typedef struct boot_header_s {
-	u8	signature[2];	/* signature */
-	u8	length;		/* image length (include header) */
-	u8	offset[4];	/* initialization vector */
-	u8	reserved[19];	/* reserved */
-	u8	exheader[2];	/* offset to expansion header */
-} boot_header_t;
+/* BIOS boot headers */
+typedef struct pci_expansion_rom_header {
+	u8	signature[2]; /* ROM Signature. Should be 0xaa55 */
+	u8	reserved[22]; /* Reserved per processor Architecture data */
+	u8	pcir_offset[2]; /* Offset to PCI Data Structure */
+} pci_exp_rom_header_t; /* PCI_EXPANSION_ROM_HEADER */
+
+/* Legacy PCI Expansion ROM Header */
+typedef struct legacy_pci_expansion_rom_header {
+	u8	signature[2]; /* ROM Signature. Should be 0xaa55 */
+	u8	size512; /* Current Image Size in units of 512 bytes */
+	u8	initentry_point[4];
+	u8	cksum; /* Checksum computed on the entire Image */
+	u8	reserved[16]; /* Reserved */
+	u8	pcir_offset[2]; /* Offset to PCI Data Struture */
+} legacy_pci_exp_rom_header_t; /* LEGACY_PCI_EXPANSION_ROM_HEADER */
+
+/* EFI PCI Expansion ROM Header */
+typedef struct efi_pci_expansion_rom_header {
+	u8	signature[2]; // ROM signature. The value 0xaa55
+	u8	initialization_size[2]; /* Units 512. Includes this header */
+	u8	efi_signature[4]; /* Signature from EFI image header. 0x0EF1 */
+	u8	efi_subsystem[2]; /* Subsystem value for EFI image header */
+	u8	efi_machine_type[2]; /* Machine type from EFI image header */
+	u8	compression_type[2]; /* Compression type. */
+		/* 
+		 * Compression type definition
+		 * 0x0: uncompressed
+		 * 0x1: Compressed
+		 * 0x2-0xFFFF: Reserved
+		 */
+	u8	reserved[8]; /* Reserved */
+	u8	efi_image_header_offset[2]; /* Offset to EFI Image */
+	u8	pcir_offset[2]; /* Offset to PCI Data Structure */
+} efi_pci_exp_rom_header_t; /* EFI PCI Expansion ROM Header */
+
+/* PCI Data Structure Format */
+typedef struct pcir_data_structure { /* PCI Data Structure */
+	u8	signature[4]; /* Signature. The string "PCIR" */
+	u8	vendor_id[2]; /* Vendor Identification */
+	u8	device_id[2]; /* Device Identification */
+	u8	vital_product[2]; /* Pointer to Vital Product Data */
+	u8	length[2]; /* PCIR Data Structure Length */
+	u8	revision; /* PCIR Data Structure Revision */
+	u8	class_code[3]; /* Class Code */
+	u8	image_length[2]; /* Image Length. Multiple of 512B */
+	u8	code_revision[2]; /* Revision Level of Code/Data */
+	u8	code_type; /* Code Type. */
+		/*
+		 * PCI Expansion ROM Code Types
+		 * 0x00: Intel IA-32, PC-AT compatible. Legacy
+		 * 0x01: Open Firmware standard for PCI. FCODE
+		 * 0x02: Hewlett-Packard PA RISC. HP reserved
+		 * 0x03: EFI Image. EFI
+		 * 0x04-0xFF: Reserved.
+		 */
+	u8	indicator; /* Indicator. Identifies the last image in the ROM */
+	u8	reserved[2]; /* Reserved */
+} pcir_data_t; /* PCI__DATA_STRUCTURE */
 
+/* BOOT constants */
 enum {
 	BOOT_FLASH_BOOT_ADDR = 0x0,/* start address of boot image in flash */
 	BOOT_SIGNATURE = 0xaa55,   /* signature of BIOS boot ROM */
 	BOOT_SIZE_INC = 512,       /* image size measured in 512B chunks */
-	BOOT_MIN_SIZE = sizeof(boot_header_t), /* at least basic header */
-	BOOT_MAX_SIZE = 1024*BOOT_SIZE_INC /* 1 byte * length increment  */
+	BOOT_MIN_SIZE = sizeof(pci_exp_rom_header_t), /* basic header */
+	BOOT_MAX_SIZE = 1024*BOOT_SIZE_INC, /* 1 byte * length increment  */
+	VENDOR_ID = 0x1425, /* Vendor ID */
+	PCIR_SIGNATURE = 0x52494350 /* PCIR signature */
 };
 
 /*
+ *	modify_device_id - Modifies the device ID of the Boot BIOS image 
+ *	@adatper: the device ID to write.
+ *	@boot_data: the boot image to modify.
+ *
+ *	Write the supplied device ID to the boot BIOS image.
+ */
+static void modify_device_id(int device_id, u8 *boot_data)
+{
+	legacy_pci_exp_rom_header_t *header;
+	pcir_data_t *pcir_header;
+	u32 cur_header = 0;
+
+	/*
+	 * Loop through all chained images and change the device ID's
+	 */
+	while (1) {
+		header = (legacy_pci_exp_rom_header_t *) &boot_data[cur_header];
+		pcir_header = (pcir_data_t *) &boot_data[cur_header +
+		    le16_to_cpu(*(u16*)header->pcir_offset)];
+
+		/*
+		 * Only modify the Device ID if code type is Legacy or HP.
+		 * 0x00: Okay to modify
+		 * 0x01: FCODE. Do not be modify
+		 * 0x03: Okay to modify
+		 * 0x04-0xFF: Do not modify
+		 */
+		if (pcir_header->code_type == 0x00) {
+			u8 csum = 0;
+			int i;
+
+			/*
+			 * Modify Device ID to match current adatper
+			 */
+			*(u16*) pcir_header->device_id = device_id;
+
+			/*
+			 * Set checksum temporarily to 0.
+			 * We will recalculate it later.
+			 */
+			header->cksum = 0x0;
+
+			/*
+			 * Calculate and update checksum
+			 */
+			for (i = 0; i < (header->size512 * 512); i++)
+				csum += (u8)boot_data[cur_header + i];
+
+			/*
+			 * Invert summed value to create the checksum
+			 * Writing new checksum value directly to the boot data
+			 */
+			boot_data[cur_header + 7] = -csum;
+
+		} else if (pcir_header->code_type == 0x03) {
+
+			/*
+			 * Modify Device ID to match current adatper
+			 */
+			*(u16*) pcir_header->device_id = device_id;
+
+		}
+
+
+		/*
+		 * Check indicator element to identify if this is the last
+		 * image in the ROM.
+		 */
+		if (pcir_header->indicator & 0x80)
+			break;
+
+		/*
+		 * Move header pointer up to the next image in the ROM.
+		 */
+		cur_header += header->size512 * 512;
+	}
+}
+
+/*
  *	t4_load_boot - download boot flash
  *	@adapter: the adapter
  *	@boot_data: the boot image to write
+ *	@boot_addr: offset in flash to write boot_data
  *	@size: image size
  *
  *	Write the supplied boot image to the card's serial flash.
  *	The boot image has the following sections: a 28-byte header and the
  *	boot image.
  */
-int t4_load_boot(struct adapter *adap, const u8 *boot_data, 
+int t4_load_boot(struct adapter *adap, u8 *boot_data, 
 		 unsigned int boot_addr, unsigned int size)
 {
+	pci_exp_rom_header_t *header;
+	int pcir_offset ;
+	pcir_data_t *pcir_header;
 	int ret, addr;
+	uint16_t device_id;
 	unsigned int i;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list