svn commit: r271555 - in stable/8: share/man/man4 sys/conf sys/dev/cxgbe sys/dev/cxgbe/common sys/dev/cxgbe/firmware sys/modules/cxgbe sys/modules/cxgbe/firmware sys/modules/cxgbe/t4_firmware sys/m...

Navdeep Parhar np at FreeBSD.org
Sat Sep 13 22:30:06 UTC 2014


Author: np
Date: Sat Sep 13 22:30:04 2014
New Revision: 271555
URL: http://svnweb.freebsd.org/changeset/base/271555

Log:
  cxgbe(4): backport Chelsio T5 support from the 9-STABLE branch.
  
  This is a direct commit to get the base 40GbE/10GbE T5 driver to
  8-STABLE.  There were too many changes between 8 and 9 (t4_tom,
  iw_cxgbe, etc.) and MFC'ing everything and then ripping out stuff
  selectively would have been too much trouble.
  
  Tested with "make -DMAKE_JUST_KERNELS universe".

Added:
  stable/8/sys/dev/cxgbe/firmware/t4fw-1.11.27.0.bin.uu   (contents, props changed)
  stable/8/sys/dev/cxgbe/firmware/t5fw-1.11.27.0.bin.uu   (contents, props changed)
  stable/8/sys/dev/cxgbe/firmware/t5fw_cfg.txt   (contents, props changed)
  stable/8/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt   (contents, props changed)
  stable/8/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt   (contents, props changed)
  stable/8/sys/modules/cxgbe/t4_firmware/
  stable/8/sys/modules/cxgbe/t4_firmware/Makefile   (contents, props changed)
  stable/8/sys/modules/cxgbe/t5_firmware/
  stable/8/sys/modules/cxgbe/t5_firmware/Makefile   (contents, props changed)
Deleted:
  stable/8/sys/dev/cxgbe/firmware/t4fw-1.8.4.0.bin.uu
  stable/8/sys/modules/cxgbe/firmware/
Modified:
  stable/8/share/man/man4/cxgbe.4
  stable/8/sys/conf/files
  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/common/t4_regs.h
  stable/8/sys/dev/cxgbe/common/t4_regs_values.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_main.c
  stable/8/sys/dev/cxgbe/t4_sge.c
  stable/8/sys/modules/cxgbe/Makefile

Modified: stable/8/share/man/man4/cxgbe.4
==============================================================================
--- stable/8/share/man/man4/cxgbe.4	Sat Sep 13 22:16:40 2014	(r271554)
+++ stable/8/share/man/man4/cxgbe.4	Sat Sep 13 22:30:04 2014	(r271555)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2011-2012, Chelsio Inc
+.\" Copyright (c) 2011-2014, Chelsio Inc
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 25, 2012
+.Dd March 20, 2014
 .Dt CXGBE 4
 .Os
 .Sh NAME
 .Nm cxgbe
-.Nd "Chelsio T4 10Gb and 1Gb Ethernet adapter driver"
+.Nd "Chelsio T4 and T5 based 40Gb, 10Gb, and 1Gb Ethernet adapter driver"
 .Sh SYNOPSIS
 To compile this driver into the kernel,
 place the following lines in your
@@ -46,16 +46,18 @@ kernel configuration file:
 .Ed
 .Pp
 To load the driver as a
-module at boot time, place the following line in
+module at boot time, place the following lines in
 .Xr loader.conf 5 :
 .Bd -literal -offset indent
+t4fw_cfg_load="YES"
+t5fw_cfg_load="YES"
 if_cxgbe_load="YES"
 .Ed
 .Sh DESCRIPTION
 The
 .Nm
 driver provides support for PCI Express Ethernet adapters based on
-the Chelsio Terminator 4 (T4) ASIC.
+the Chelsio Terminator 4 and Terminator 5 ASICs (T4 and T5).
 The driver supports Jumbo Frames, Transmit/Receive checksum offload,
 TCP segmentation offload (TSO), Large Receive Offload (LRO), VLAN
 tag insertion/extraction, VLAN checksum offload, VLAN TSO, and
@@ -64,11 +66,49 @@ For further hardware information and que
 requirements, see
 .Pa http://www.chelsio.com/ .
 .Pp
+Note that ports of T5 cards are named cxl and attach to a t5nex parent device
+(in contrast to ports named cxgbe that attach to a t4nex parent for a T4 card).
+Loader tunables with the hw.cxgbe prefix apply to both T4 and T5 cards.
+The sysctl MIBs are at dev.t5nex and dev.cxl for T5 cards and at dev.t4nex and
+dev.cxgbe for T4 cards.
+.Pp
 For more information on configuring this device, see
 .Xr ifconfig 8 .
 .Sh HARDWARE
 The
 .Nm
+driver supports 40Gb, 10Gb and 1Gb Ethernet adapters based on the T5 ASIC
+(ports will be named cxl):
+.Pp
+.Bl -bullet -compact
+.It
+Chelsio T580-CR
+.It
+Chelsio T580-LP-CR
+.It
+Chelsio T580-LP-SO-CR
+.It
+Chelsio T560-CR
+.It
+Chelsio T540-CR
+.It
+Chelsio T540-LP-CR
+.It
+Chelsio T522-CR
+.It
+Chelsio T520-LL-CR
+.It
+Chelsio T520-CR
+.It
+Chelsio T520-SO
+.It
+Chelsio T520-BT
+.It
+Chelsio T504-BT
+.El
+.Pp
+The
+.Nm
 driver supports 10Gb and 1Gb Ethernet adapters based on the T4 ASIC:
 .Pp
 .Bl -bullet -compact
@@ -100,11 +140,11 @@ prompt before booting the kernel or stor
 .Xr loader.conf 5 .
 .Bl -tag -width indent
 .It Va hw.cxgbe.ntxq10g
-The number of tx queues to use for a 10Gb port.
+The number of tx queues to use for a 10Gb or 40Gb port.
 The default is 16 or the number
 of CPU cores in the system, whichever is less.
 .It Va hw.cxgbe.nrxq10g
-The number of rx queues to use for a 10Gb port.
+The number of rx queues to use for a 10Gb or 40Gb port.
 The default is 8 or the number
 of CPU cores in the system, whichever is less.
 .It Va hw.cxgbe.ntxq1g
@@ -116,11 +156,11 @@ The number of rx queues to use for a 1Gb
 The default is 2 or the number
 of CPU cores in the system, whichever is less.
 .It Va hw.cxgbe.nofldtxq10g
-The number of TOE tx queues to use for a 10Gb port.
+The number of TOE tx queues to use for a 10Gb or 40Gb port.
 The default is 8 or the
 number of CPU cores in the system, whichever is less.
 .It Va hw.cxgbe.nofldrxq10g
-The number of TOE rx queues to use for a 10Gb port.
+The number of TOE rx queues to use for a 10Gb or 40Gb port.
 The default is 2 or the
 number of CPU cores in the system, whichever is less.
 .It Va hw.cxgbe.nofldtxq1g
@@ -136,20 +176,18 @@ The timer index value to use to delay in
 The holdoff timer list has the values 1, 5, 10, 50, 100, and 200
 by default (all values are in microseconds) and the index selects a
 value from this list.
-The default value is 1 for both 10Gb and 1Gb ports, which means the
-timer value is 5us.
-Different cxgbe interfaces can be assigned different values at any time via the
-dev.cxgbe.X.holdoff_tmr_idx sysctl.
+The default value is 1 which means the timer value is 5us.
+Different interfaces can be assigned different values at any time via the
+dev.cxgbe.X.holdoff_tmr_idx or dev.cxl.X.holdoff_tmr_idx sysctl.
 .It Va hw.cxgbe.holdoff_pktc_idx_10G
 .It Va hw.cxgbe.holdoff_pktc_idx_1G
 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 -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.
+The default value is -1 which means packet counting is disabled and interrupts
+are generated based solely on the holdoff timer value.
+Different interfaces can be assigned different values via the
+dev.cxgbe.X.holdoff_pktc_idx or dev.cxl.X.holdoff_pktc_idx sysctl.
 This sysctl works only when the interface has never been marked up (as done by
 ifconfig up).
 .It Va hw.cxgbe.qsize_txq
@@ -160,16 +198,16 @@ software queuing.
 See
 .Xr ifnet 9 .
 The default value is 1024.
-Different cxgbe interfaces can be assigned different values via the
-dev.cxgbe.X.qsize_txq sysctl.
+Different interfaces can be assigned different values via the
+dev.cxgbe.X.qsize_txq sysctl or dev.cxl.X.qsize_txq sysctl.
 This sysctl works only when the interface has never been marked up (as done by
 ifconfig up).
 .It Va hw.cxgbe.qsize_rxq
 The size, in number of entries, of the descriptor ring used for an
 rx queue.
 The default value is 1024.
-Different cxgbe interfaces can be assigned different values via the
-dev.cxgbe.X.qsize_rxq sysctl.
+Different interfaces can be assigned different values via the
+dev.cxgbe.X.qsize_rxq or dev.cxl.X.qsize_rxq sysctl.
 This sysctl works only when the interface has never been marked up (as done by
 ifconfig up).
 .It Va hw.cxgbe.interrupt_types
@@ -187,6 +225,43 @@ already on the card.
 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.fl_pktshift
+The number of bytes of padding inserted before the begining of an Ethernet
+frame in the receive buffer.
+The default value of 2 ensures that the Ethernet payload (usually the IP header)
+is at a 4 byte aligned address.
+0-7 are all valid values.
+.It Va hw.cxgbe.fl_pad
+A non-zero value ensures that writes from the hardware to a receive buffer are
+padded up to the specified boundary.
+The default is -1 which lets the driver pick a pad boundary.
+0 disables trailer padding completely.
+.It Va hw.cxgbe.cong_drop
+Controls the hardware response to congestion.
+-1 disables congestion feedback and is not recommended.
+0 instructs the hardware to backpressure its pipeline on congestion.
+This usually results in the port emitting pause frames.
+1 instructs the hardware to drop frames destined for congested queues.
+.It Va hw.cxgbe.buffer_packing
+Allow the hardware to deliver multiple frames in the same receive buffer
+opportunistically.
+The default is -1 which lets the driver decide.
+0 or 1 explicitly disable or enable this feature.
+.It Va hw.cxgbe.allow_mbufs_in_cluster
+1 allows the driver to lay down one or more mbufs within the receive buffer
+opportunistically.  This is the default.
+0 prohibits the driver from doing so.
+.It Va hw.cxgbe.largest_rx_cluster
+.It Va hw.cxgbe.safest_rx_cluster
+Sizes of rx clusters.  Each of these must be set to one of the sizes available
+(usually 2048, 4096, 9216, and 16384) and largest_rx_cluster must be greater
+than or equal to safest_rx_cluster.
+The defaults are 16384 and 4096 respectively.
+The driver will never attempt to allocate a receive buffer larger than
+largest_rx_cluster and will fall back to allocating buffers of
+safest_rx_cluster size if an allocation larger than safest_rx_cluster fails.
+Note that largest_rx_cluster merely establishes a ceiling -- the driver is
+allowed to allocate buffers of smaller sizes.
 .It Va hw.cxgbe.config_file
 Select a pre-packaged device configuration file.
 A configuration file contains a recipe for partitioning and configuring the
@@ -194,7 +269,7 @@ hardware resources on the card.
 This tunable is for specialized applications only and should not be used in
 normal operation.
 The configuration profile currently in use is available in the dev.t4nex.X.cf
-and dev.t4nex.X.cfcsum sysctls.
+and dev.t4nex.X.cfcsum (dev.t5nex for T5 cards) sysctls.
 .It Va hw.cxgbe.linkcaps_allowed
 .It Va hw.cxgbe.niccaps_allowed
 .It Va hw.cxgbe.toecaps_allowed
@@ -208,7 +283,7 @@ capability.
 This tunable is for specialized applications only and should not be used in
 normal operation.
 The capabilities for which hardware resources have been reserved are listed in
-dev.t4nex.X.*caps sysctls.
+dev.t4nex.X.*caps or dev.t5nex.X.*caps sysctls.
 .El
 .Sh SUPPORT
 For general information and support,
@@ -230,6 +305,10 @@ The
 .Nm
 device driver first appeared in
 .Fx 9.0 .
+Support for T5 cards first appeared in
+.Fx 9.2
+and
+.Fx 10.0 .
 .Sh AUTHORS
 .An -nosplit
 The

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files	Sat Sep 13 22:16:40 2014	(r271554)
+++ stable/8/sys/conf/files	Sat Sep 13 22:30:04 2014	(r271555)
@@ -850,10 +850,34 @@ t4fw.fwo		optional cxgbe					\
 	no-implicit-rule						\
 	clean		"t4fw.fwo"
 t4fw.fw			optional cxgbe					\
-	dependency	"$S/dev/cxgbe/firmware/t4fw-1.8.4.0.bin.uu"	\
+	dependency	"$S/dev/cxgbe/firmware/t4fw-1.11.27.0.bin.uu"	\
 	compile-with	"${NORMAL_FW}"					\
 	no-obj no-implicit-rule						\
 	clean		"t4fw.fw"
+t5fw_cfg.c		optional cxgbe					\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk t5fw_cfg.fw:t5fw_cfg t5fw.fw:t5fw -mt5fw_cfg -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"t5fw_cfg.c"
+t5fw_cfg.fwo		optional cxgbe					\
+	dependency	"t5fw_cfg.fw"					\
+	compile-with	"${NORMAL_FWO}"					\
+	no-implicit-rule						\
+	clean		"t5fw_cfg.fwo"
+t5fw_cfg.fw		optional cxgbe					\
+	dependency	"$S/dev/cxgbe/firmware/t5fw_cfg.txt"		\
+	compile-with	"${CP} ${.ALLSRC} ${.TARGET}"			\
+	no-obj no-implicit-rule						\
+	clean		"t5fw_cfg.fw"
+t5fw.fwo		optional cxgbe					\
+	dependency	"t5fw.fw"					\
+	compile-with	"${NORMAL_FWO}"					\
+	no-implicit-rule						\
+	clean		"t5fw.fwo"
+t5fw.fw			optional cxgbe					\
+	dependency	"$S/dev/cxgbe/firmware/t5fw-1.11.27.0.bin.uu"	\
+	compile-with	"${NORMAL_FW}"					\
+	no-obj no-implicit-rule						\
+	clean		"t5fw.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/dev/cxgbe/adapter.h
==============================================================================
--- stable/8/sys/dev/cxgbe/adapter.h	Sat Sep 13 22:16:40 2014	(r271554)
+++ stable/8/sys/dev/cxgbe/adapter.h	Sat Sep 13 22:30:04 2014	(r271555)
@@ -50,9 +50,6 @@
 #include "offload.h"
 #include "firmware/t4fw_interface.h"
 
-#define T4_CFGNAME "t4fw_cfg"
-#define T4_FWNAME "t4fw"
-
 MALLOC_DECLARE(M_CXGBE);
 #define CXGBE_UNIMPLEMENTED(s) \
     panic("%s (%s, line %d) not implemented yet.", s, __FILE__, __LINE__)
@@ -140,11 +137,11 @@ enum {
 
 	RX_FL_ESIZE = EQ_ESIZE,	/* 8 64bit addresses */
 #if MJUMPAGESIZE != MCLBYTES
-	FL_BUF_SIZES = 4,	/* cluster, jumbop, jumbo9k, jumbo16k */
+	SW_ZONE_SIZES = 4,	/* cluster, jumbop, jumbo9k, jumbo16k */
 #else
-	FL_BUF_SIZES = 3,	/* cluster, jumbo9k, jumbo16k */
+	SW_ZONE_SIZES = 3,	/* cluster, jumbo9k, jumbo16k */
 #endif
-	OFLD_BUF_SIZE = MJUM16BYTES,	/* size of fl buffer for TOE rxq */
+	CL_METADATA_SIZE = CACHE_LINE_SIZE,
 
 	CTRL_EQ_QSIZE = 128,
 
@@ -153,12 +150,6 @@ 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),
@@ -184,6 +175,7 @@ enum {
 	MASTER_PF	= (1 << 3),
 	ADAP_SYSCTL_CTX	= (1 << 4),
 	TOM_INIT_DONE	= (1 << 5),
+	BUF_PACKING_OK	= (1 << 6),
 
 	CXGBE_BUSY	= (1 << 9),
 
@@ -211,6 +203,7 @@ struct port_info {
 	unsigned long flags;
 	int if_flags;
 
+	uint16_t *rss;
 	uint16_t viid;
 	int16_t  xact_addr_filt;/* index of exact MAC address filter */
 	uint16_t rss_size;	/* size of VI's RSS table slice */
@@ -220,10 +213,12 @@ struct port_info {
 	uint8_t  mod_type;
 	uint8_t  port_id;
 	uint8_t  tx_chan;
+	uint8_t  rx_chan_map;	/* rx MPS channel bitmap */
 
 	/* These need to be int as they are used in sysctl */
 	int ntxq;	/* # of tx queues */
 	int first_txq;	/* index of first tx queue */
+	int rsrv_noflowq; /* Reserve queue 0 for non-flowid packets */
 	int nrxq;	/* # of rx queues */
 	int first_rxq;	/* index of first rx queue */
 #ifdef TCP_OFFLOAD
@@ -237,6 +232,7 @@ struct port_info {
 	int qsize_rxq;
 	int qsize_txq;
 
+	int linkdnrc;
 	struct link_config link_cfg;
 	struct port_stats stats;
 
@@ -246,16 +242,28 @@ struct port_info {
 	uint8_t hw_addr[ETHER_ADDR_LEN]; /* factory MAC address, won't change */
 };
 
-struct fl_sdesc {
-	struct mbuf *m;
-	bus_dmamap_t map;
-	caddr_t cl;
-	uint8_t tag_idx;	/* the sc->fl_tag this map comes from */
+/* Where the cluster came from, how it has been carved up. */
+struct cluster_layout {
+	int8_t zidx;
+	int8_t hwidx;
+	uint16_t region1;	/* mbufs laid out within this region */
+				/* region2 is the DMA region */
+	uint16_t region3;	/* cluster_metadata within this region */
+};
+
+struct cluster_metadata {
+	u_int refcount;
 #ifdef INVARIANTS
-	__be64 ba_tag;
+	struct fl_sdesc *sd;	/* For debug only.  Could easily be stale */
 #endif
 };
 
+struct fl_sdesc {
+	caddr_t cl;
+	uint16_t nmbuf;	/* # of driver originated mbufs with ref on cluster */
+	struct cluster_layout cll;
+};
+
 struct tx_desc {
 	__be64 flit[8];
 };
@@ -334,6 +342,9 @@ enum {
 	EQ_STALLED	= (1 << 6),	/* out of hw descriptors or dmamaps */
 };
 
+/* Listed in order of preference.  Update t4_sysctls too if you change these */
+enum {DOORBELL_UDB, DOORBELL_WCWR, DOORBELL_UDBWC, DOORBELL_KDB};
+
 /*
  * Egress Queue: driver is producer, T4 is consumer.
  *
@@ -351,6 +362,9 @@ struct sge_eq {
 	struct tx_desc *desc;	/* KVA of descriptor ring */
 	bus_addr_t ba;		/* bus address of descriptor ring */
 	struct sge_qstat *spg;	/* status page, for convenience */
+	int doorbells;
+	volatile uint32_t *udb;	/* KVA of doorbell (lies within BAR2) */
+	u_int udb_qid;		/* relative qid within the doorbell page */
 	uint16_t cap;		/* max # of desc, for convenience */
 	uint16_t avail;		/* available descriptors, for convenience */
 	uint16_t qsize;		/* size (# of entries) of the queue */
@@ -368,9 +382,24 @@ struct sge_eq {
 	uint32_t unstalled;	/* recovered from stall */
 };
 
+struct sw_zone_info {
+	uma_zone_t zone;	/* zone that this cluster comes from */
+	int size;		/* size of cluster: 2K, 4K, 9K, 16K, etc. */
+	int type;		/* EXT_xxx type of the cluster */
+	int8_t head_hwidx;
+	int8_t tail_hwidx;
+};
+
+struct hw_buf_info {
+	int8_t zidx;		/* backpointer to zone; -ve means unused */
+	int8_t next;		/* next hwidx for this zone; -1 means no more */
+	int size;
+};
+
 enum {
 	FL_STARVING	= (1 << 0), /* on the adapter's list of starving fl's */
 	FL_DOOMED	= (1 << 1), /* about to be destroyed */
+	FL_BUF_PACKING	= (1 << 2), /* buffer packing enabled */
 };
 
 #define FL_RUNNING_LOW(fl)	(fl->cap - fl->needed <= fl->lowat)
@@ -379,8 +408,8 @@ enum {
 struct sge_fl {
 	bus_dma_tag_t desc_tag;
 	bus_dmamap_t desc_map;
-	bus_dma_tag_t tag[FL_BUF_SIZES];
-	uint8_t tag_idx;
+	struct cluster_layout cll_def;	/* default refill zone, layout */
+	struct cluster_layout cll_alt;	/* alternate refill zone, layout */
 	struct mtx fl_lock;
 	char lockname[16];
 	int flags;
@@ -392,12 +421,22 @@ struct sge_fl {
 	uint16_t qsize;		/* size (# of entries) of the queue */
 	uint16_t cntxt_id;	/* SGE context id for the freelist */
 	uint32_t cidx;		/* consumer idx (buffer idx, NOT hw desc idx) */
+	uint32_t rx_offset;	/* offset in fl buf (when buffer packing) */
 	uint32_t pidx;		/* producer idx (buffer idx, NOT hw desc idx) */
 	uint32_t needed;	/* # of buffers needed to fill up fl. */
 	uint32_t lowat;		/* # of buffers <= this means fl needs help */
 	uint32_t pending;	/* # of bufs allocated since last doorbell */
-	unsigned int dmamap_failed;
 	TAILQ_ENTRY(sge_fl) link; /* All starving freelists */
+
+	struct mbuf *m0;
+	struct mbuf **pnext;
+	u_int remaining;
+
+	uint64_t mbuf_allocated;/* # of mbuf allocated from zone_mbuf */
+	uint64_t mbuf_inlined;	/* # of mbuf created within clusters */
+	uint64_t cl_allocated;	/* # of clusters allocated */
+	uint64_t cl_recycled;	/* # of clusters recycled */
+	uint64_t cl_fast_recycled; /* # of clusters recycled (fast) */
 };
 
 /* txq: SGE egress queue + what's needed for Ethernet NIC */
@@ -503,6 +542,9 @@ struct sge {
 	int timer_val[SGE_NTIMERS];
 	int counter_val[SGE_NCOUNTERS];
 	int fl_starve_threshold;
+	int fl_starve_threshold2;
+	int eq_s_qpp;
+	int iq_s_qpp;
 
 	int nrxq;	/* total # of Ethernet rx queues */
 	int ntxq;	/* total # of Ethernet tx tx queues */
@@ -527,6 +569,12 @@ struct sge {
 	int eq_start;
 	struct sge_iq **iqmap;	/* iq->cntxt_id to iq mapping */
 	struct sge_eq **eqmap;	/* eq->cntxt_id to eq mapping */
+
+	int pack_boundary;
+	int8_t safe_hwidx1;	/* may not have room for metadata */
+	int8_t safe_hwidx2;	/* with room for metadata and maybe more */
+	struct sw_zone_info sw_zone_info[SW_ZONE_SIZES];
+	struct hw_buf_info hw_buf_info[SGE_FLBUF_SIZES];
 };
 
 struct rss_header;
@@ -548,6 +596,9 @@ struct adapter {
 	bus_space_handle_t bh;
 	bus_space_tag_t bt;
 	bus_size_t mmio_len;
+	int udbs_rid;
+	struct resource *udbs_res;
+	volatile uint8_t *udbs_base;
 
 	unsigned int pf;
 	unsigned int mbox;
@@ -568,7 +619,6 @@ struct adapter {
 	struct taskqueue *tq[NCHAN];	/* taskqueues that flush data out */
 	struct port_info *port[MAX_NPORTS];
 	uint8_t chan_map[NCHAN];
-	uint32_t filter_mode;
 
 #ifdef TCP_OFFLOAD
 	void *tom_softc;	/* (struct tom_data *) */
@@ -577,6 +627,7 @@ struct adapter {
 	struct l2t_data *l2t;	/* L2 table */
 	struct tid_info tids;
 
+	int doorbells;
 	int open_device_map;
 #ifdef TCP_OFFLOAD
 	int offload_map;
@@ -614,6 +665,8 @@ struct adapter {
 	const char *last_op;
 	const void *last_op_thr;
 #endif
+
+	int sc_do_rxcopy;
 };
 
 #define ADAPTER_LOCK(sc)		mtx_lock(&(sc)->sc_lock)
@@ -755,13 +808,22 @@ t4_os_set_hw_addr(struct adapter *sc, in
 	bcopy(hw_addr, sc->port[idx]->hw_addr, ETHER_ADDR_LEN);
 }
 
-static inline bool is_10G_port(const struct port_info *pi)
+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)
+static inline bool
+is_40G_port(const struct port_info *pi)
+{
+
+	return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) != 0);
+}
+
+static inline int
+tx_resume_threshold(struct sge_eq *eq)
 {
 
 	return (eq->qsize / 4);
@@ -774,7 +836,7 @@ int t4_os_find_pci_capability(struct ada
 int t4_os_pci_save_state(struct adapter *);
 int t4_os_pci_restore_state(struct adapter *);
 void t4_os_portmod_changed(const struct adapter *, int);
-void t4_os_link_changed(struct adapter *, int, int);
+void t4_os_link_changed(struct adapter *, int, 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);
@@ -785,8 +847,12 @@ void end_synchronized_op(struct adapter 
 
 /* t4_sge.c */
 void t4_sge_modload(void);
-int t4_sge_init(struct adapter *);
+void t4_init_sge_cpl_handlers(struct adapter *);
+void t4_tweak_chip_settings(struct adapter *);
+int t4_read_chip_settings(struct adapter *);
 int t4_create_dma_tag(struct adapter *);
+void t4_sge_sysctls(struct adapter *, struct sysctl_ctx_list *,
+    struct sysctl_oid_list *);
 int t4_destroy_dma_tag(struct adapter *);
 int t4_setup_adapter_queues(struct adapter *);
 int t4_teardown_adapter_queues(struct adapter *);

Modified: stable/8/sys/dev/cxgbe/common/common.h
==============================================================================
--- stable/8/sys/dev/cxgbe/common/common.h	Sat Sep 13 22:16:40 2014	(r271554)
+++ stable/8/sys/dev/cxgbe/common/common.h	Sat Sep 13 22:30:04 2014	(r271555)
@@ -42,15 +42,19 @@ enum {
 	MACADDR_LEN    = 12,    /* MAC Address length */
 };
 
-enum { MEM_EDC0, MEM_EDC1, MEM_MC };
+enum { MEM_EDC0, MEM_EDC1, MEM_MC, MEM_MC0 = MEM_MC, MEM_MC1 };
 
 enum {
 	MEMWIN0_APERTURE = 2048,
 	MEMWIN0_BASE     = 0x1b800,
 	MEMWIN1_APERTURE = 32768,
 	MEMWIN1_BASE     = 0x28000,
-	MEMWIN2_APERTURE = 65536,
-	MEMWIN2_BASE     = 0x30000,
+
+	MEMWIN2_APERTURE_T4 = 65536,
+	MEMWIN2_BASE_T4     = 0x30000,
+
+	MEMWIN2_APERTURE_T5 = 128 * 1024,
+	MEMWIN2_BASE_T5     = 0x60000,
 };
 
 enum dev_master { MASTER_CANT, MASTER_MAY, MASTER_MUST };
@@ -63,15 +67,10 @@ enum {
 	PAUSE_AUTONEG = 1 << 2
 };
 
-#define FW_VERSION_MAJOR 1
-#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 memwin {
+	uint32_t base;
+	uint32_t aperture;
+};
 
 struct port_stats {
 	u64 tx_octets;            /* total # of octets in good frames */
@@ -220,6 +219,12 @@ struct tp_params {
 	unsigned int dack_re;        /* DACK timer resolution */
 	unsigned int la_mask;        /* what events are recorded by TP LA */
 	unsigned short tx_modq[NCHAN];  /* channel to modulation queue map */
+	uint32_t vlan_pri_map;
+	uint32_t ingress_config;
+	int8_t vlan_shift;
+	int8_t vnic_shift;
+	int8_t port_shift;
+	int8_t protocol_shift;
 };
 
 struct vpd_params {
@@ -241,7 +246,7 @@ struct pci_params {
  * Firmware device log.
  */
 struct devlog_params {
-	u32 memtype;			/* which memory (EDC0, EDC1, MC) */
+	u32 memtype;			/* which memory (FW_MEMTYPE_* ) */
 	u32 start;			/* start of log in firmware memory */
 	u32 size;			/* size of log */
 };
@@ -262,23 +267,29 @@ struct adapter_params {
 	unsigned short a_wnd[NCCTRL_WIN];
 	unsigned short b_wnd[NCCTRL_WIN];
 
-	unsigned int mc_size;		/* MC memory size */
-	unsigned int nfilters;		/* size of filter region */
+	u_int ftid_min;
+	u_int ftid_max;
+	u_int etid_min;
+	u_int netids;
 
 	unsigned int cim_la_size;
 
-	/* Used as int in sysctls, do not reduce size */
-	unsigned int nports;		/* # of ethernet ports */
-	unsigned int portvec;
-	unsigned int rev;		/* chip revision */
-	unsigned int offload;
+	uint8_t nports;		/* # of ethernet ports */
+	uint8_t portvec;
+	unsigned int chipid:4;	/* chip ID.  T4 = 4, T5 = 5, ... */
+	unsigned int rev:4;	/* chip revision */
+	unsigned int fpga:1;	/* this is an FPGA */
+	unsigned int offload:1;	/* hw is TOE capable, fw has divvied up card
+				   resources for TOE operation. */
+	unsigned int bypass:1;	/* this is a bypass card */
+	unsigned int ethoffload:1;
 
 	unsigned int ofldq_wr_cred;
+	unsigned int eo_wr_cred;
 };
 
-enum {					    /* chip revisions */
-	T4_REV_A  = 0,
-};
+#define CHELSIO_T4		0x4
+#define CHELSIO_T5		0x5
 
 struct trace_params {
 	u32 data[TRACE_LEN / 4];
@@ -311,11 +322,53 @@ struct link_config {
 #define for_each_port(adapter, iter) \
 	for (iter = 0; iter < (adapter)->params.nports; ++iter)
 
+static inline int is_ftid(const struct adapter *sc, u_int tid)
+{
+
+	return (tid >= sc->params.ftid_min && tid <= sc->params.ftid_max);
+}
+
+static inline int is_etid(const struct adapter *sc, u_int tid)
+{
+
+	return (tid >= sc->params.etid_min);
+}
+
 static inline int is_offload(const struct adapter *adap)
 {
 	return adap->params.offload;
 }
 
+static inline int is_ethoffload(const struct adapter *adap)
+{
+	return adap->params.ethoffload;
+}
+
+static inline int chip_id(struct adapter *adap)
+{
+	return adap->params.chipid;
+}
+
+static inline int chip_rev(struct adapter *adap)
+{
+	return adap->params.rev;
+}
+
+static inline int is_t4(struct adapter *adap)
+{
+	return adap->params.chipid == CHELSIO_T4;
+}
+
+static inline int is_t5(struct adapter *adap)
+{
+	return adap->params.chipid == CHELSIO_T5;
+}
+
+static inline int is_fpga(struct adapter *adap)
+{
+	 return adap->params.fpga;
+}
+
 static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
 {
 	return adap->params.vpd.cclk / 1000;
@@ -388,13 +441,15 @@ int t4_read_flash(struct adapter *adapte
 int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
 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_flash_cfg_addr(struct adapter *adapter);
 int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size);
 int t4_get_fw_version(struct adapter *adapter, u32 *vers);
 int t4_get_tp_version(struct adapter *adapter, u32 *vers);
 int t4_check_fw_version(struct adapter *adapter);
 int t4_init_hw(struct adapter *adapter, u32 fw_params);
 int t4_prep_adapter(struct adapter *adapter);
+int t4_init_tp_params(struct adapter *adap);
+int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
 int t4_port_init(struct port_info *p, int mbox, int pf, int vf);
 int t4_reinit_adapter(struct adapter *adap);
 void t4_fatal_err(struct adapter *adapter);
@@ -437,7 +492,8 @@ int t4_cim_read_la(struct adapter *adap,
 void t4_cim_read_pif_la(struct adapter *adap, u32 *pif_req, u32 *pif_rsp,
 		unsigned int *pif_req_wrptr, unsigned int *pif_rsp_wrptr);
 void t4_cim_read_ma_la(struct adapter *adap, u32 *ma_req, u32 *ma_rsp);
-int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity);
+int t4_mc_read(struct adapter *adap, int idx, u32 addr,
+	       __be32 *data, u64 *parity);
 int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *parity);
 int t4_mem_read(struct adapter *adap, int mtype, u32 addr, u32 size,
 		__be32 *data);
@@ -527,12 +583,18 @@ 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,
 	       unsigned int mmd, unsigned int reg, unsigned int val);
+int t4_i2c_rd(struct adapter *adap, unsigned int mbox,
+	      int port, unsigned int devid,
+	      unsigned int offset, unsigned int len,
+	      u8 *buf);
+int t4_i2c_wr(struct adapter *adap, unsigned int mbox,
+	      int port, unsigned int devid,
+	      unsigned int offset, unsigned int len,
+	      u8 *buf);
 int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
 		     unsigned int pf, unsigned int vf, unsigned int iqid,
 		     unsigned int fl0id, unsigned int fl1id);
@@ -552,4 +614,8 @@ int t4_sge_ctxt_rd_bd(struct adapter *ad
 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);
+int t4_sched_config(struct adapter *adapter, int type, int minmaxen);
+int t4_sched_params(struct adapter *adapter, int type, int level, int mode,
+		    int rateunit, int ratemode, int channel, int cl,
+		    int minrate, int maxrate, int weight, int pktsize);
 #endif /* __CHELSIO_COMMON_H */

Modified: stable/8/sys/dev/cxgbe/common/t4_hw.c
==============================================================================
--- stable/8/sys/dev/cxgbe/common/t4_hw.c	Sat Sep 13 22:16:40 2014	(r271554)
+++ stable/8/sys/dev/cxgbe/common/t4_hw.c	Sat Sep 13 22:30:04 2014	(r271555)
@@ -176,9 +176,7 @@ static void t4_report_fw_error(struct ad
 	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
+	if (pcie_fw & F_PCIE_FW_ERR)
 		CH_ERR(adap, "Firmware reports adapter error: %s\n",
 		       reason[G_PCIE_FW_EVAL(pcie_fw)]);
 }
@@ -312,6 +310,7 @@ int t4_wr_mbox_meat(struct adapter *adap
 /**
  *	t4_mc_read - read from MC through backdoor accesses
  *	@adap: the adapter
+ *	@idx: which MC to access
  *	@addr: address of first byte requested
  *	@data: 64 bytes of data containing the requested address
  *	@ecc: where to store the corresponding 64-bit ECC word
@@ -320,22 +319,40 @@ int t4_wr_mbox_meat(struct adapter *adap
  *	that covers the requested address @addr.  If @parity is not %NULL it
  *	is assigned the 64-bit ECC word for the read data.
  */
-int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *ecc)
+int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
 {
 	int i;
+	u32 mc_bist_cmd_reg, mc_bist_cmd_addr_reg, mc_bist_cmd_len_reg;
+	u32 mc_bist_status_rdata_reg, mc_bist_data_pattern_reg;
+
+	if (is_t4(adap)) {
+		mc_bist_cmd_reg = A_MC_BIST_CMD;
+		mc_bist_cmd_addr_reg = A_MC_BIST_CMD_ADDR;
+		mc_bist_cmd_len_reg = A_MC_BIST_CMD_LEN;
+		mc_bist_status_rdata_reg = A_MC_BIST_STATUS_RDATA;
+		mc_bist_data_pattern_reg = A_MC_BIST_DATA_PATTERN;
+	} else {
+		mc_bist_cmd_reg = MC_REG(A_MC_P_BIST_CMD, idx);
+		mc_bist_cmd_addr_reg = MC_REG(A_MC_P_BIST_CMD_ADDR, idx);
+		mc_bist_cmd_len_reg = MC_REG(A_MC_P_BIST_CMD_LEN, idx);
+		mc_bist_status_rdata_reg = MC_REG(A_MC_P_BIST_STATUS_RDATA,
+						  idx);
+		mc_bist_data_pattern_reg = MC_REG(A_MC_P_BIST_DATA_PATTERN,
+						  idx);
+	}
 
-	if (t4_read_reg(adap, A_MC_BIST_CMD) & F_START_BIST)
+	if (t4_read_reg(adap, mc_bist_cmd_reg) & F_START_BIST)
 		return -EBUSY;
-	t4_write_reg(adap, A_MC_BIST_CMD_ADDR, addr & ~0x3fU);
-	t4_write_reg(adap, A_MC_BIST_CMD_LEN, 64);
-	t4_write_reg(adap, A_MC_BIST_DATA_PATTERN, 0xc);
-	t4_write_reg(adap, A_MC_BIST_CMD, V_BIST_OPCODE(1) | F_START_BIST |
-		     V_BIST_CMD_GAP(1));
-	i = t4_wait_op_done(adap, A_MC_BIST_CMD, F_START_BIST, 0, 10, 1);
+	t4_write_reg(adap, mc_bist_cmd_addr_reg, addr & ~0x3fU);
+	t4_write_reg(adap, mc_bist_cmd_len_reg, 64);
+	t4_write_reg(adap, mc_bist_data_pattern_reg, 0xc);
+	t4_write_reg(adap, mc_bist_cmd_reg, V_BIST_OPCODE(1) |
+		     F_START_BIST | V_BIST_CMD_GAP(1));
+	i = t4_wait_op_done(adap, mc_bist_cmd_reg, F_START_BIST, 0, 10, 1);
 	if (i)
 		return i;
 
-#define MC_DATA(i) MC_BIST_STATUS_REG(A_MC_BIST_STATUS_RDATA, i)
+#define MC_DATA(i) MC_BIST_STATUS_REG(mc_bist_status_rdata_reg, i)
 
 	for (i = 15; i >= 0; i--)
 		*data++ = ntohl(t4_read_reg(adap, MC_DATA(i)));
@@ -360,20 +377,47 @@ int t4_mc_read(struct adapter *adap, u32
 int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
 {
 	int i;
+	u32 edc_bist_cmd_reg, edc_bist_cmd_addr_reg, edc_bist_cmd_len_reg;
+	u32 edc_bist_cmd_data_pattern, edc_bist_status_rdata_reg;
 
-	idx *= EDC_STRIDE;
-	if (t4_read_reg(adap, A_EDC_BIST_CMD + idx) & F_START_BIST)
+	if (is_t4(adap)) {
+		edc_bist_cmd_reg = EDC_REG(A_EDC_BIST_CMD, idx);
+		edc_bist_cmd_addr_reg = EDC_REG(A_EDC_BIST_CMD_ADDR, idx);
+		edc_bist_cmd_len_reg = EDC_REG(A_EDC_BIST_CMD_LEN, idx);
+		edc_bist_cmd_data_pattern = EDC_REG(A_EDC_BIST_DATA_PATTERN,
+						    idx);
+		edc_bist_status_rdata_reg = EDC_REG(A_EDC_BIST_STATUS_RDATA,
+						    idx);
+	} else {
+/*
+ * These macro are missing in t4_regs.h file.
+ * Added temporarily for testing.
+ */
+#define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR)
+#define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx)
+		edc_bist_cmd_reg = EDC_REG_T5(A_EDC_H_BIST_CMD, idx);
+		edc_bist_cmd_addr_reg = EDC_REG_T5(A_EDC_H_BIST_CMD_ADDR, idx);
+		edc_bist_cmd_len_reg = EDC_REG_T5(A_EDC_H_BIST_CMD_LEN, idx);
+		edc_bist_cmd_data_pattern = EDC_REG_T5(A_EDC_H_BIST_DATA_PATTERN,
+						    idx);
+		edc_bist_status_rdata_reg = EDC_REG_T5(A_EDC_H_BIST_STATUS_RDATA,
+						    idx);
+#undef EDC_REG_T5
+#undef EDC_STRIDE_T5
+	}
+
+	if (t4_read_reg(adap, edc_bist_cmd_reg) & F_START_BIST)
 		return -EBUSY;
-	t4_write_reg(adap, A_EDC_BIST_CMD_ADDR + idx, addr & ~0x3fU);
-	t4_write_reg(adap, A_EDC_BIST_CMD_LEN + idx, 64);
-	t4_write_reg(adap, A_EDC_BIST_DATA_PATTERN + idx, 0xc);
-	t4_write_reg(adap, A_EDC_BIST_CMD + idx,
+	t4_write_reg(adap, edc_bist_cmd_addr_reg, addr & ~0x3fU);
+	t4_write_reg(adap, edc_bist_cmd_len_reg, 64);
+	t4_write_reg(adap, edc_bist_cmd_data_pattern, 0xc);
+	t4_write_reg(adap, edc_bist_cmd_reg,
 		     V_BIST_OPCODE(1) | V_BIST_CMD_GAP(1) | F_START_BIST);
-	i = t4_wait_op_done(adap, A_EDC_BIST_CMD + idx, F_START_BIST, 0, 10, 1);
+	i = t4_wait_op_done(adap, edc_bist_cmd_reg, F_START_BIST, 0, 10, 1);
 	if (i)
 		return i;
 
-#define EDC_DATA(i) (EDC_BIST_STATUS_REG(A_EDC_BIST_STATUS_RDATA, i) + idx)
+#define EDC_DATA(i) EDC_BIST_STATUS_REG(edc_bist_status_rdata_reg, i)
 
 	for (i = 15; i >= 0; i--)
 		*data++ = ntohl(t4_read_reg(adap, EDC_DATA(i)));
@@ -425,8 +469,8 @@ int t4_mem_read(struct adapter *adap, in
 		/*
 		 * Read the chip's memory block and bail if there's an error.
 		 */
-		if (mtype == MEM_MC)
-			ret = t4_mc_read(adap, pos, data, NULL);
+		if ((mtype == MEM_MC) || (mtype == MEM_MC1))
+			ret = t4_mc_read(adap, mtype - MEM_MC, pos, data, NULL);
 		else
 			ret = t4_edc_read(adap, mtype, pos, data, NULL);
 		if (ret)
@@ -464,8 +508,9 @@ struct t4_vpd_hdr {
 #define EEPROM_STAT_ADDR   0x7bfc
 #define VPD_BASE           0x400
 #define VPD_BASE_OLD       0
-#define VPD_LEN            512
+#define VPD_LEN            1024
 #define VPD_INFO_FLD_HDR_SIZE	3
+#define CHELSIO_VPD_UNIQUE_ID 0x82
 
 /**
  *	t4_seeprom_read - read a serial EEPROM location
@@ -630,7 +675,7 @@ static int get_vpd_params(struct adapter
 	 * it at 0.
 	 */
 	ret = t4_seeprom_read(adapter, VPD_BASE, (u32 *)(vpd));
-	addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD; 
+	addr = *vpd == CHELSIO_VPD_UNIQUE_ID ? VPD_BASE : VPD_BASE_OLD;
 
 	for (i = 0; i < sizeof(vpd); i += 4) {
 		ret = t4_seeprom_read(adapter, addr + i, (u32 *)(vpd + i));
@@ -668,8 +713,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);
+	i = vpd[pn - VPD_INFO_FLD_HDR_SIZE + 2];
 	memcpy(p->pn, vpd + pn, min(i, PN_LEN));
 	strstrip((char *)p->pn);
+	i = vpd[na - VPD_INFO_FLD_HDR_SIZE + 2];
 	memcpy(p->na, vpd + na, min(i, MACADDR_LEN));
 	strstrip((char *)p->na);
 
@@ -914,6 +961,7 @@ int t4_get_tp_version(struct adapter *ad
 int t4_check_fw_version(struct adapter *adapter)
 {
 	int ret, major, minor, micro;
+	int exp_major, exp_minor, exp_micro;
 
 	ret = t4_get_fw_version(adapter, &adapter->params.fw_vers);
 	if (!ret)
@@ -925,13 +973,30 @@ int t4_check_fw_version(struct adapter *
 	minor = G_FW_HDR_FW_VER_MINOR(adapter->params.fw_vers);
 	micro = G_FW_HDR_FW_VER_MICRO(adapter->params.fw_vers);
 
-	if (major != FW_VERSION_MAJOR) {            /* major mismatch - fail */
+	switch (chip_id(adapter)) {
+	case CHELSIO_T4:
+		exp_major = T4FW_VERSION_MAJOR;
+		exp_minor = T4FW_VERSION_MINOR;
+		exp_micro = T4FW_VERSION_MICRO;
+		break;
+	case CHELSIO_T5:
+		exp_major = T5FW_VERSION_MAJOR;
+		exp_minor = T5FW_VERSION_MINOR;
+		exp_micro = T5FW_VERSION_MICRO;
+		break;
+	default:
+		CH_ERR(adapter, "Unsupported chip type, %x\n",
+		    chip_id(adapter));
+		return -EINVAL;
+	}
+
+	if (major != exp_major) {            /* major mismatch - fail */
 		CH_ERR(adapter, "card FW has major version %u, driver wants "
-		       "%u\n", major, FW_VERSION_MAJOR);

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


More information about the svn-src-stable-8 mailing list