From owner-svn-src-stable@FreeBSD.ORG Sat Mar 2 21:59:09 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 24705308; Sat, 2 Mar 2013 21:59:09 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 081243DC; Sat, 2 Mar 2013 21:59:09 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r22Lx9Dq058603; Sat, 2 Mar 2013 21:59:09 GMT (envelope-from np@svn.freebsd.org) Received: (from np@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r22Lx7QD058594; Sat, 2 Mar 2013 21:59:07 GMT (envelope-from np@svn.freebsd.org) Message-Id: <201303022159.r22Lx7QD058594@svn.freebsd.org> From: Navdeep Parhar Date: Sat, 2 Mar 2013 21:59:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: 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 X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Mar 2013 21:59:09 -0000 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 #include #include +#include #include #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 __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 ***