Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Nov 2016 18:45:06 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r308304 - in stable/10: sys/conf sys/dev/cxgbe sys/dev/cxgbe/common sys/dev/cxgbe/firmware sys/dev/cxgbe/iw_cxgbe sys/dev/cxgbe/tom sys/modules/cxgbe/t4_firmware sys/modules/cxgbe/t5_fi...
Message-ID:  <201611041845.uA4Ij6sF071093@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Nov  4 18:45:06 2016
New Revision: 308304
URL: https://svnweb.freebsd.org/changeset/base/308304

Log:
  MFC 295778,296249,296333,296383,296471,296478,296481,296485,296488-296491,
  296493-296496,296544,296710-296711,297863,299685: Catch up to changes to
  the internal shared code.
  
  Note that this merge includes two different firmware updates, but the
  effective change is to update to the last version (1.15.37.0).  As such,
  I've trimmed the log message of the first update (1.15.28.0).
  
  In addition, the M_WAIT macro added in t4_regs.h had to be renamed to
  CXGBE_M_WAIT to avoid a collision on 10.x that is not present on 11.
  
  295778:
  cxgbe: catch up with the latest hardware-related definitions.
  
  296249:
  cxgbe(4): Update T5 and T4 firmwares to 1.15.28.0.
  
  296333:
  cxgbe(4): First of many changes to reduce diffs with internal shared
  code:
  
  - Rename some CamelCase variables.
  - s/t4_link_start/t4_link_l1cfg/g
  - Pull in t4_get_port_type_description.
  - Move t4_wait_op_done to t4_hw.c.
  - Flip the order of the RDMA stats.
  - Remove unsused function t4_iq_start_stop.
  - Move t4_wait_op_done and t4_wait_op_done_val to t4_hw.c
  
  296383:
  cxgbe(4): Very basic T6 awareness.  This is part of ongoing work to
  update to the latest internal shared code.
  
  - Add a chip_params structure to keep track of hardware constants for
    all generations of Terminators handled by cxgbe.
  - Update t4_hw_pci_read_cfg4 to work with T6.
  - Update the hardware debug sysctls (hidden within dev.<tNnex>.<n>.misc.*) to
    work with T6.  Most of the changes are in the decoders for the CIM
    logic analyzer and the MPS TCAM.
  - Acquire the regwin lock around indirect register accesses.
  
  296471:
  cxgbe(4): Updated register dumps.
  
  - Get the list of registers to read during a regdump from the shared
    code instead of the OS specific code.  This follows a similar move
    internally.  The shared code includes the list for T6.
  
  - Update cxgbetool to be able to decode T5 VF, T6, and T6 VF register
    dumps (and catch up with some updates to T4 and T5 register decode).
  
  296478:
  cxgbe(4): Add a struct sge_params to store per-adapter SGE parameters.
  Move the code that reads all the parameters to t4_init_sge_params in the
  shared code.  Use these per-adapter values instead of globals.
  
  296481:
  cxgbe(4): Overhaul the shared code that deals with the chip's TP block,
  which is responsible for filtering and RSS.
  
  Add the ability to use filters that match on PF/VF (aka "VNIC id") while
  here.  This is mutually exclusive with filtering on outer VLAN tag with
  Q-in-Q.
  
  296485:
  cxgbe(4): Update the interrupt handlers for hardware errors.
  
  296488:
  cxgbe(4): Updates to mailbox routines in the shared code.
  
  296489:
  cxgbe(4): Updates to the shared routines that deal with the serial EEPROM,
  flash, and VPD.
  
  296490:
  cxgbe(4): Remove __devinit and SPEED_<foo> as part of catch up with
  internal shared code.
  
  296491:
  cxgbe(4): Updates to shared routines that get/set various parameters via
  the firmware.
  
  296493:
  cxgbe(4): Use t4_link_down_rc_str in shared code to decode the reason
  the link is down, instead of doing it in OS specific code.
  
  296494:
  cxgbe(4): Many new functions in the shared code, unused at this time.
  
  296495:
  cxgbe(4): Fix t4_tp_get_rdma_stats.
  
  296496:
  cxgbe(4): Minor updates to the shared routines that deal with firmware images.
  
  296544:
  cxgbe(4): Reshuffle and rototill t4_hw.c, solely to reduce diffs with
  the internal shared code.
  
  296710:
  cxgbe(4): Catch up with the latest list of card capabilities as reported
  by the firmware.
  
  296711:
  cxgbe(4): Fix typo in previous commit.
  
  297863:
  Rename the 'M_B' macro in t4_regs.h to 'CXGBE_M_B'.
  
  This fixes a conflict with the M_B macro in powerpc's
  <machine/db_machdep.h> exposed by the recent addition of DDB commands
  to the cxgbe driver.
  
  299685:
  cxgbe(4): Update T5 and T4 firmwares to 1.15.37.0.
  
  These firmwares were obtained from the "Chelsio T5/T4 Unified Wire
  v2.12.0.3 for Linux" release.  Changes since 1.14.4.0 (which is the
  firmware in -STABLE branches) are in the "Release Notes" accompanying
  the Unified Wire release and are copy-pasted here as well.
  
  22.1. T5 Firmware
  +++++++++++++++++++++++++++++++++
  
  Version : 1.15.37.0
  Date    : 04/27/2016
  ================================================================================
  
  FIXES
  -----
  
  BASE:
   - Fixed an issue in FW_RSS_VI_CONFIG_CMD handling where the default ingress
     queue was ignored.
   - Fixed an issue where adapter failed to load fw by adjusting DRAM frequency.
   - Fixed an issue in watchdog which was causing VM bring-up failure after reboot.
   - Fixed 40G link failures with some switches when auto-negotiation enabled.
   - Fixed to improve on link bring-up time.
   - Per port buffer groups size doubled to improve performance.
   - Fixed an issue where bogus d3hot bits were set causing traffic stall.
   - Fixed an issue where sometimes adapter was not seen after reboot.
   - Fixed an issue where iWARP was crashing in conjunction with traffic management.
   - Fixed an issue where link failed to come up after removing twinax cable and
     inserting optical module.
  
  ETH
   - Fixed a link flap issue on T580-CR.
  
  OFLD
   - Fixed a potential iSCSI data corruption issue by disabling RxFragEn flag.
  
  FOiSCSI
   - Fixed an issue in recovery path where connection was getting closed before
     recovery processing was done.
   - Fixed an issue in TCP port reuse.
   - Fixed an issue in recovery path when large number (>64) of iSCSI connections
     were in use.
   - Returned ENETUNREACH if IP was not been provisioned yet and driver tried to
     use given inerface.
   - Fixed an issue where fw was sending ENETUNREACH event for normal tcp
     disconnection.
  
  DCBX
   - Fixed an issue where iscsi tlv is sent incorrectly to host. (DCBX CEE)
   - Fixed an issue where apply bit set for APP id was affecting the ETS and PFC
    settings.(DCBX IEEE)
   - Fixed an issue where app priority values are not handled correctly in fw.
    (DCBX IEEE)
   - Fixed an issue where enable/disable dcbx can cause crash. (DCBX CEE,DCBX IEEE)
  
  FOFCoE
   - Removed BB6 support.
  
  ENHANCEMENTS
  ------------
  
  BASE:
   - Added new interface to program DCA settings in SGE contexts; allow 32-byte
     IQE size
   - Added PTP interface fw_ptp_ts to support PTP Frequeny and Offset adjustment.
   - Added MPS raw interface.
  
  ETH:
   - New mailbox command FW_DCB_IEEE_CMD api added for IEEE dcbx.
  
  OFLD:
   - WR opcode is returned to host in cqe error response.
  
  22.2. T4 Firmware
  +++++++++++++++++
  
  Version : 1.15.37.0
  Date    : 04/27/2016
  ================================================================================
  
  FIXES
  -----
  
  BASE:
   - Fixed an issue in FW_RSS_VI_CONFIG_CMD handling where default ingress queue
     was ignored.
   - Fixed an issue in watchdog which was causing VM bring-up failure after reboot.
   - Per port buffer groups size doubled to improve performance.
   - Fixed an issue where iWARP was crashing in conjunction with traffic management.
  
  FOiSCSI:
   - Fixed an issue in recovery path where connection was getting closed before
     recovery processing was done.
   - Fixed an issue in TCP port reuse.
   - Fixed an issue in recovery path when large number (>64) of iSCSI connections
     were in use.
   - Returned ENETUNREACH if IP had not been provisioned yet and driver tried to
     use given inerface.
  
  DCBX
   - Fixed an issue where iscsi tlv is sent incorrectly to host.(DCBX CEE)
   - Fixed an issue where enable/disable dcbx can cause crash in firmware.(DCBX CEE)
  
  FOiSCSI
   - Fixes an issue where fw was sending ENETUNREACH event for normal tcp
     disconnection.
  
  FOFCoE
   - Removed BB6 support.
  
  ENHANCEMENTS
  ------------
  
  BASE:
   - Added MPS raw interface.
  
  ETH:
   - New mailbox command FW_DCB_IEEE_CMD api added for IEEE dcbx.
  ================================================================================
  
  Sponsored by:	Chelsio Communications

Added:
  stable/10/sys/dev/cxgbe/firmware/t4fw-1.15.37.0.bin.uu
     - copied unchanged from r299685, head/sys/dev/cxgbe/firmware/t4fw-1.15.37.0.bin.uu
  stable/10/sys/dev/cxgbe/firmware/t5fw-1.15.37.0.bin.uu
     - copied unchanged from r299685, head/sys/dev/cxgbe/firmware/t5fw-1.15.37.0.bin.uu
  stable/10/tools/tools/cxgbetool/reg_defs_t6.c
     - copied unchanged from r296471, head/tools/tools/cxgbetool/reg_defs_t6.c
Deleted:
  stable/10/sys/dev/cxgbe/firmware/t4fw-1.14.4.0.bin.uu
  stable/10/sys/dev/cxgbe/firmware/t5fw-1.14.4.0.bin.uu
Modified:
  stable/10/sys/conf/files
  stable/10/sys/dev/cxgbe/adapter.h
  stable/10/sys/dev/cxgbe/common/common.h
  stable/10/sys/dev/cxgbe/common/t4_hw.c
  stable/10/sys/dev/cxgbe/common/t4_hw.h
  stable/10/sys/dev/cxgbe/common/t4_msg.h
  stable/10/sys/dev/cxgbe/common/t4_regs.h
  stable/10/sys/dev/cxgbe/common/t4_regs_values.h
  stable/10/sys/dev/cxgbe/common/t4_tcb.h
  stable/10/sys/dev/cxgbe/firmware/t4fw_cfg.txt
  stable/10/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt
  stable/10/sys/dev/cxgbe/firmware/t4fw_interface.h
  stable/10/sys/dev/cxgbe/firmware/t5fw_cfg.txt
  stable/10/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt
  stable/10/sys/dev/cxgbe/iw_cxgbe/device.c
  stable/10/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h
  stable/10/sys/dev/cxgbe/iw_cxgbe/qp.c
  stable/10/sys/dev/cxgbe/osdep.h
  stable/10/sys/dev/cxgbe/t4_ioctl.h
  stable/10/sys/dev/cxgbe/t4_main.c
  stable/10/sys/dev/cxgbe/t4_netmap.c
  stable/10/sys/dev/cxgbe/t4_sge.c
  stable/10/sys/dev/cxgbe/tom/t4_connect.c
  stable/10/sys/modules/cxgbe/t4_firmware/Makefile
  stable/10/sys/modules/cxgbe/t5_firmware/Makefile
  stable/10/tools/tools/cxgbetool/cxgbetool.c
  stable/10/tools/tools/cxgbetool/reg_defs_t4.c
  stable/10/tools/tools/cxgbetool/reg_defs_t4vf.c
  stable/10/tools/tools/cxgbetool/reg_defs_t5.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/conf/files
==============================================================================
--- stable/10/sys/conf/files	Fri Nov  4 18:16:00 2016	(r308303)
+++ stable/10/sys/conf/files	Fri Nov  4 18:45:06 2016	(r308304)
@@ -1188,7 +1188,7 @@ t4fw.fwo		optional cxgbe					\
 	no-implicit-rule						\
 	clean		"t4fw.fwo"
 t4fw.fw			optional cxgbe					\
-	dependency	"$S/dev/cxgbe/firmware/t4fw-1.14.4.0.bin.uu"	\
+	dependency	"$S/dev/cxgbe/firmware/t4fw-1.15.37.0.bin.uu"	\
 	compile-with	"${NORMAL_FW}"					\
 	no-obj no-implicit-rule						\
 	clean		"t4fw.fw"
@@ -1212,7 +1212,7 @@ t5fw.fwo		optional cxgbe					\
 	no-implicit-rule						\
 	clean		"t5fw.fwo"
 t5fw.fw			optional cxgbe					\
-	dependency	"$S/dev/cxgbe/firmware/t5fw-1.14.4.0.bin.uu"	\
+	dependency	"$S/dev/cxgbe/firmware/t5fw-1.15.37.0.bin.uu"	\
 	compile-with	"${NORMAL_FW}"					\
 	no-obj no-implicit-rule						\
 	clean		"t5fw.fw"

Modified: stable/10/sys/dev/cxgbe/adapter.h
==============================================================================
--- stable/10/sys/dev/cxgbe/adapter.h	Fri Nov  4 18:16:00 2016	(r308303)
+++ stable/10/sys/dev/cxgbe/adapter.h	Fri Nov  4 18:45:06 2016	(r308304)
@@ -664,13 +664,6 @@ struct sge_nm_txq {
 } __aligned(CACHE_LINE_SIZE);
 
 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 */
 	int nofldrxq;	/* total # of TOE rx queues */
@@ -695,8 +688,6 @@ struct sge {
 	struct sge_iq **iqmap;	/* iq->cntxt_id to iq mapping */
 	struct sge_eq **eqmap;	/* eq->cntxt_id to eq mapping */
 
-	int pad_boundary;
-	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];
@@ -728,6 +719,8 @@ struct adapter {
 
 	unsigned int pf;
 	unsigned int mbox;
+	unsigned int vpd_busy;
+	unsigned int vpd_flag;
 
 	/* Interrupt information */
 	int intr_type;
@@ -746,9 +739,9 @@ struct adapter {
 	struct sge sge;
 	int lro_timeout;
 
-	struct taskqueue *tq[NCHAN];	/* General purpose taskqueues */
+	struct taskqueue *tq[MAX_NCHAN];	/* General purpose taskqueues */
 	struct port_info *port[MAX_NPORTS];
-	uint8_t chan_map[NCHAN];
+	uint8_t chan_map[MAX_NCHAN];
 
 	void *tom_softc;	/* (struct tom_data *) */
 	struct tom_tunables tt;
@@ -775,12 +768,16 @@ struct adapter {
 	char cfg_file[32];
 	u_int cfcsum;
 	struct adapter_params params;
+	const struct chip_params *chip_params;
 	struct t4_virt_res vres;
 
+	uint16_t nbmcaps;
 	uint16_t linkcaps;
+	uint16_t switchcaps;
 	uint16_t niccaps;
 	uint16_t toecaps;
 	uint16_t rdmacaps;
+	uint16_t tlscaps;
 	uint16_t iscsicaps;
 	uint16_t fcoecaps;
 
@@ -797,7 +794,7 @@ struct adapter {
 	struct mtx regwin_lock;	/* for indirect reads and memory windows */
 
 	an_handler_t an_handler __aligned(CACHE_LINE_SIZE);
-	fw_msg_handler_t fw_msg_handler[5];	/* NUM_FW6_TYPES */
+	fw_msg_handler_t fw_msg_handler[7];	/* NUM_FW6_TYPES */
 	cpl_handler_t cpl_handler[0xef];	/* NUM_CPL_CMDS */
 
 	const char *last_op;
@@ -1000,6 +997,17 @@ tx_resume_threshold(struct sge_eq *eq)
 	return (eq->sidx / 4);
 }
 
+static inline int
+t4_use_ldst(struct adapter *sc)
+{
+
+#ifdef notyet
+	return (sc->flags & FW_OK || !sc->use_bd);
+#else
+	return (0);
+#endif
+}
+
 /* t4_main.c */
 int t4_os_find_pci_capability(struct adapter *, int);
 int t4_os_pci_save_state(struct adapter *);

Modified: stable/10/sys/dev/cxgbe/common/common.h
==============================================================================
--- stable/10/sys/dev/cxgbe/common/common.h	Fri Nov  4 18:16:00 2016	(r308303)
+++ stable/10/sys/dev/cxgbe/common/common.h	Fri Nov  4 18:45:06 2016	(r308304)
@@ -32,6 +32,9 @@
 
 #include "t4_hw.h"
 
+#define GLBL_INTR_MASK (F_CIM | F_MPS | F_PL | F_PCIE | F_MC0 | F_EDC0 | \
+		F_EDC1 | F_LE | F_TP | F_MA | F_PM_TX | F_PM_RX | F_ULP_RX | \
+		F_CPL_SWITCH | F_SGE | F_ULP_TX)
 
 enum {
 	MAX_NPORTS     = 4,     /* max # of ports */
@@ -42,11 +45,17 @@ enum {
 	MACADDR_LEN    = 12,    /* MAC Address length */
 };
 
+enum {
+	T4_REGMAP_SIZE = (160 * 1024),
+	T5_REGMAP_SIZE = (332 * 1024),
+};
+
 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,
 
@@ -168,10 +177,10 @@ struct lb_port_stats {
 };
 
 struct tp_tcp_stats {
-	u32 tcpOutRsts;
-	u64 tcpInSegs;
-	u64 tcpOutSegs;
-	u64 tcpRetransSegs;
+	u32 tcp_out_rsts;
+	u64 tcp_in_segs;
+	u64 tcp_out_segs;
+	u64 tcp_retrans_segs;
 };
 
 struct tp_usm_stats {
@@ -181,50 +190,72 @@ struct tp_usm_stats {
 };
 
 struct tp_fcoe_stats {
-	u32 framesDDP;
-	u32 framesDrop;
-	u64 octetsDDP;
+	u32 frames_ddp;
+	u32 frames_drop;
+	u64 octets_ddp;
 };
 
 struct tp_err_stats {
-	u32 macInErrs[4];
-	u32 hdrInErrs[4];
-	u32 tcpInErrs[4];
-	u32 tnlCongDrops[4];
-	u32 ofldChanDrops[4];
-	u32 tnlTxDrops[4];
-	u32 ofldVlanDrops[4];
-	u32 tcp6InErrs[4];
-	u32 ofldNoNeigh;
-	u32 ofldCongDefer;
+	u32 mac_in_errs[MAX_NCHAN];
+	u32 hdr_in_errs[MAX_NCHAN];
+	u32 tcp_in_errs[MAX_NCHAN];
+	u32 tnl_cong_drops[MAX_NCHAN];
+	u32 ofld_chan_drops[MAX_NCHAN];
+	u32 tnl_tx_drops[MAX_NCHAN];
+	u32 ofld_vlan_drops[MAX_NCHAN];
+	u32 tcp6_in_errs[MAX_NCHAN];
+	u32 ofld_no_neigh;
+	u32 ofld_cong_defer;
 };
 
 struct tp_proxy_stats {
-	u32 proxy[4];
+	u32 proxy[MAX_NCHAN];
 };
 
 struct tp_cpl_stats {
-	u32 req[4];
-	u32 rsp[4];
+	u32 req[MAX_NCHAN];
+	u32 rsp[MAX_NCHAN];
 };
 
 struct tp_rdma_stats {
-	u32 rqe_dfr_mod;
 	u32 rqe_dfr_pkt;
+	u32 rqe_dfr_mod;
+};
+
+struct sge_params {
+	int timer_val[SGE_NTIMERS];
+	int counter_val[SGE_NCOUNTERS];
+	int fl_starve_threshold;
+	int fl_starve_threshold2;
+	int page_shift;
+	int eq_s_qpp;
+	int iq_s_qpp;
+	int spg_len;
+	int pad_boundary;
+	int pack_boundary;
+	int fl_pktshift;
 };
 
 struct tp_params {
-	unsigned int ntxchan;        /* # of Tx channels */
 	unsigned int tre;            /* log2 of core clocks per TP tick */
 	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 */
+	unsigned short tx_modq[MAX_NCHAN];  /* channel to modulation queue map */
+
 	uint32_t vlan_pri_map;
 	uint32_t ingress_config;
-	int8_t vlan_shift;
-	int8_t vnic_shift;
+	uint32_t rx_pkt_encap;
+
+	int8_t fcoe_shift;
 	int8_t port_shift;
+	int8_t vnic_shift;
+	int8_t vlan_shift;
+	int8_t tos_shift;
 	int8_t protocol_shift;
+	int8_t ethertype_shift;
+	int8_t macmatch_shift;
+	int8_t matchtype_shift;
+	int8_t frag_shift;
 };
 
 struct vpd_params {
@@ -252,7 +283,21 @@ struct devlog_params {
 	u32 size;			/* size of log */
 };
 
+/* Stores chip specific parameters */
+struct chip_params {
+	u8 nchan;
+	u8 pm_stats_cnt;
+	u8 cng_ch_bits_log;		/* congestion channel map bits width */
+	u8 nsched_cls;
+	u8 cim_num_obq;
+	u16 mps_rplc_size;
+	u16 vfcount;
+	u32 sge_fl_db;
+	u16 mps_tcam_size;
+};
+
 struct adapter_params {
+	struct sge_params sge;
 	struct tp_params  tp;
 	struct vpd_params vpd;
 	struct pci_params pci;
@@ -291,6 +336,19 @@ struct adapter_params {
 
 #define CHELSIO_T4		0x4
 #define CHELSIO_T5		0x5
+#define CHELSIO_T6		0x6
+
+/*
+ * State needed to monitor the forward progress of SGE Ingress DMA activities
+ * and possible hangs.
+ */
+struct sge_idma_monitor_state {
+	unsigned int idma_1s_thresh;	/* 1s threshold in Core Clock ticks */
+	unsigned int idma_stalled[2];	/* synthesized stalled timers in HZ */
+	unsigned int idma_state[2];	/* IDMA Hang detect state */
+	unsigned int idma_qid[2];	/* IDMA Hung Ingress Queue ID */
+	unsigned int idma_warn[2];	/* time to warning in HZ */
+};
 
 struct trace_params {
 	u32 data[TRACE_LEN / 4];
@@ -365,6 +423,11 @@ static inline int is_t5(struct adapter *
 	return adap->params.chipid == CHELSIO_T5;
 }
 
+static inline int is_t6(struct adapter *adap)
+{
+	return adap->params.chipid == CHELSIO_T6;
+}
+
 static inline int is_fpga(struct adapter *adap)
 {
 	 return adap->params.fpga;
@@ -381,6 +444,14 @@ static inline unsigned int us_to_core_ti
 	return (us * adap->params.vpd.cclk) / 1000;
 }
 
+static inline unsigned int core_ticks_to_us(const struct adapter *adapter,
+					    unsigned int ticks)
+{
+	/* add Core Clock / 2 to round ticks to nearest uS */
+	return ((ticks * 1000 + adapter->params.vpd.cclk/2) /
+		adapter->params.vpd.cclk);
+}
+
 static inline unsigned int dack_ticks_to_usec(const struct adapter *adap,
 					      unsigned int ticks)
 {
@@ -388,19 +459,20 @@ static inline unsigned int dack_ticks_to
 }
 
 void t4_set_reg_field(struct adapter *adap, unsigned int addr, u32 mask, u32 val);
-int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask, int polarity,
-			int attempts, int delay, u32 *valp);
-
-static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask,
-				  int polarity, int attempts, int delay)
-{
-	return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts,
-				   delay, NULL);
-}
 
+int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
+			    int size, void *rpl, bool sleep_ok, int timeout);
 int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
 		    void *rpl, bool sleep_ok);
 
+static inline int t4_wr_mbox_timeout(struct adapter *adap, int mbox,
+				     const void *cmd, int size, void *rpl,
+				     int timeout)
+{
+	return t4_wr_mbox_meat_timeout(adap, mbox, cmd, size, rpl, true,
+				       timeout);
+}
+
 static inline int t4_wr_mbox(struct adapter *adap, int mbox, const void *cmd,
 			     int size, void *rpl)
 {
@@ -430,7 +502,7 @@ void t4_intr_clear(struct adapter *adapt
 int t4_slow_intr_handler(struct adapter *adapter);
 
 int t4_hash_mac_addr(const u8 *addr);
-int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
+int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc);
 int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
 int t4_seeprom_read(struct adapter *adapter, u32 addr, u32 *data);
@@ -439,21 +511,31 @@ int t4_eeprom_ptov(unsigned int phys_add
 int t4_seeprom_wp(struct adapter *adapter, int enable);
 int t4_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords,
 		  u32 *data, int byte_oriented);
+int t4_write_flash(struct adapter *adapter, unsigned int addr,
+		   unsigned int n, const u8 *data, int byte_oriented);
 int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
+int t4_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op);
+int t5_fw_init_extern_mem(struct adapter *adap);
+int t4_load_bootcfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size);
 int t4_load_boot(struct adapter *adap, u8 *boot_data,
                  unsigned int boot_addr, unsigned int size);
+int t4_flash_erase_sectors(struct adapter *adapter, int start, int end);
 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_get_exprom_version(struct adapter *adapter, u32 *vers);
 int t4_init_hw(struct adapter *adapter, u32 fw_params);
-int t4_prep_adapter(struct adapter *adapter);
+int t4_prep_adapter(struct adapter *adapter, u8 *buf);
+int t4_shutdown_adapter(struct adapter *adapter);
+int t4_init_devlog_params(struct adapter *adapter, int fw_attach);
+int t4_init_sge_params(struct adapter *adapter);
 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);
+int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id);
 void t4_fatal_err(struct adapter *adapter);
+void t4_db_full(struct adapter *adapter);
+void t4_db_dropped(struct adapter *adapter);
 int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp,
 			int filter_index, int enable);
 void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp,
@@ -465,8 +547,10 @@ int t4_config_glbl_rss(struct adapter *a
 int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 		     unsigned int flags, unsigned int defq);
 int t4_read_rss(struct adapter *adapter, u16 *entries);
+void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
+		  unsigned int start_index, unsigned int rw);
 void t4_read_rss_key(struct adapter *adapter, u32 *key);
-void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx);
+void t4_write_rss_key(struct adapter *adap, u32 *key, int idx);
 void t4_read_rss_pf_config(struct adapter *adapter, unsigned int index, u32 *valp);
 void t4_write_rss_pf_config(struct adapter *adapter, unsigned int index, u32 val);
 void t4_read_rss_vf_config(struct adapter *adapter, unsigned int index,
@@ -493,12 +577,24 @@ 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_get_flash_params(struct adapter *adapter);
+
+u32 t4_read_pcie_cfg4(struct adapter *adap, int reg, int drv_fw_attach);
 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);
+void t4_idma_monitor_init(struct adapter *adapter,
+			  struct sge_idma_monitor_state *idma);
+void t4_idma_monitor(struct adapter *adapter,
+		     struct sge_idma_monitor_state *idma,
+		     int hz, int ticks);
+
+unsigned int t4_get_regs_len(struct adapter *adapter);
+void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size);
 
+const char *t4_get_port_type_description(enum fw_port_type port_type);
 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,
@@ -552,6 +648,13 @@ int t4_fw_initialize(struct adapter *ada
 int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
 		    unsigned int vf, unsigned int nparams, const u32 *params,
 		    u32 *val);
+int t4_query_params_rw(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		       unsigned int vf, unsigned int nparams, const u32 *params,
+		       u32 *val, int rw);
+int t4_set_params_timeout(struct adapter *adap, unsigned int mbox,
+			  unsigned int pf, unsigned int vf,
+			  unsigned int nparams, const u32 *params,
+			  const u32 *val, int timeout);
 int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
 		  unsigned int vf, unsigned int nparams, const u32 *params,
 		  const u32 *val);
@@ -580,6 +683,8 @@ int t4_change_mac(struct adapter *adap, 
 		  int idx, const u8 *addr, bool persist, bool add_smt);
 int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
 		     bool ucast, u64 vec, bool sleep_ok);
+int t4_enable_vi_params(struct adapter *adap, unsigned int mbox,
+			unsigned int viid, bool rx_en, bool tx_en, bool dcb_en);
 int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
 		 bool rx_en, bool tx_en);
 int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
@@ -596,9 +701,9 @@ int t4_i2c_wr(struct adapter *adap, unsi
 	      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);
+int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf,
+	       unsigned int vf, unsigned int iqtype, unsigned int iqid,
+	       unsigned int fl0id, unsigned int fl1id);
 int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
 	       unsigned int vf, unsigned int iqtype, unsigned int iqid,
 	       unsigned int fl0id, unsigned int fl1id);
@@ -613,6 +718,7 @@ int t4_sge_ctxt_rd(struct adapter *adap,
 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);
+const char *t4_link_down_rc_str(unsigned char link_down_rc);
 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,
@@ -621,4 +727,10 @@ int t4_sched_params(struct adapter *adap
 		    int rateunit, int ratemode, int channel, int cl,
 		    int minrate, int maxrate, int weight, int pktsize,
 		    int sleep_ok);
+int t4_config_watchdog(struct adapter *adapter, unsigned int mbox,
+		       unsigned int pf, unsigned int vf,
+		       unsigned int timeout, unsigned int action);
+int t4_get_devlog_level(struct adapter *adapter, unsigned int *level);
+int t4_set_devlog_level(struct adapter *adapter, unsigned int level);
+void t4_sge_decode_idma_state(struct adapter *adapter, int state);
 #endif /* __CHELSIO_COMMON_H */

Modified: stable/10/sys/dev/cxgbe/common/t4_hw.c
==============================================================================
--- stable/10/sys/dev/cxgbe/common/t4_hw.c	Fri Nov  4 18:16:00 2016	(r308303)
+++ stable/10/sys/dev/cxgbe/common/t4_hw.c	Fri Nov  4 18:45:06 2016	(r308304)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2012 Chelsio Communications, Inc.
+ * Copyright (c) 2012, 2016 Chelsio Communications, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,8 +57,8 @@ __FBSDID("$FreeBSD$");
  *	at the time it indicated completion is stored there.  Returns 0 if the
  *	operation completes and	-EAGAIN	otherwise.
  */
-int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
-		        int polarity, int attempts, int delay, u32 *valp)
+static int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
+			       int polarity, int attempts, int delay, u32 *valp)
 {
 	while (1) {
 		u32 val = t4_read_reg(adapter, reg);
@@ -75,6 +75,13 @@ int t4_wait_op_done_val(struct adapter *
 	}
 }
 
+static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask,
+				  int polarity, int attempts, int delay)
+{
+	return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts,
+				   delay, NULL);
+}
+
 /**
  *	t4_set_reg_field - set a register field to a value
  *	@adapter: the adapter to program
@@ -107,8 +114,8 @@ void t4_set_reg_field(struct adapter *ad
  *	register pair.
  */
 void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
-		      unsigned int data_reg, u32 *vals, unsigned int nregs,
-		      unsigned int start_idx)
+			     unsigned int data_reg, u32 *vals,
+			     unsigned int nregs, unsigned int start_idx)
 {
 	while (nregs--) {
 		t4_write_reg(adap, addr_reg, start_idx);
@@ -144,26 +151,49 @@ void t4_write_indirect(struct adapter *a
  * 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.
+ *
+ * N.B. This routine should only be used as a last resort: the firmware uses
+ *      the backdoor registers on a regular basis and we can end up
+ *      conflicting with it's uses!
  */
 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);
+	u32 req = V_FUNCTION(adap->pf) | V_REGISTER(reg);
+	u32 val;
+
+	if (chip_id(adap) <= CHELSIO_T5)
+		req |= F_ENABLE;
+	else
+		req |= F_T6_ENABLE;
+
+	if (is_t4(adap))
+		req |= F_LOCALCFG;
+
+	t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ, req);
+	val = t4_read_reg(adap, A_PCIE_CFG_SPACE_DATA);
+
+	/*
+	 * Reset F_ENABLE to 0 so reads of PCIE_CFG_SPACE_DATA won't cause a
+	 * Configuration Space read.  (None of the other fields matter when
+	 * F_ENABLE is 0 so a simple register write is easier than a
+	 * read-modify-write via t4_set_reg_field().)
+	 */
+	t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ, 0);
+
+	return val;
 }
 
 /*
- *	t4_report_fw_error - report firmware error
- *	@adap: the adapter
+ * 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).
+ * The adapter firmware can indicate error conditions to the host.
+ * If the firmware has indicated an error, print out the reason for
+ * the firmware error.
  */
 static void t4_report_fw_error(struct adapter *adap)
 {
-	static const char *reason[] = {
+	static const char *const reason[] = {
 		"Crash",			/* PCIE_FW_EVAL_CRASH */
 		"During Device Preparation",	/* PCIE_FW_EVAL_PREP */
 		"During Device Configuration",	/* PCIE_FW_EVAL_CONF */
@@ -178,7 +208,7 @@ static void t4_report_fw_error(struct ad
 	pcie_fw = t4_read_reg(adap, A_PCIE_FW);
 	if (pcie_fw & F_PCIE_FW_ERR)
 		CH_ERR(adap, "Firmware reports adapter error: %s\n",
-		       reason[G_PCIE_FW_EVAL(pcie_fw)]);
+			reason[G_PCIE_FW_EVAL(pcie_fw)]);
 }
 
 /*
@@ -194,25 +224,27 @@ static void get_mbox_rpl(struct adapter 
 /*
  * Handle a FW assertion reported in a mailbox.
  */
-static void fw_asrt(struct adapter *adap, u32 mbox_addr)
+static void fw_asrt(struct adapter *adap, struct fw_debug_cmd *asrt)
 {
-	struct fw_debug_cmd asrt;
-
-	get_mbox_rpl(adap, (__be64 *)&asrt, sizeof(asrt) / 8, mbox_addr);
-	CH_ALERT(adap, "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
-		 asrt.u.assert.filename_0_7, ntohl(asrt.u.assert.line),
-		 ntohl(asrt.u.assert.x), ntohl(asrt.u.assert.y));
+	CH_ALERT(adap,
+		  "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
+		  asrt->u.assert.filename_0_7,
+		  be32_to_cpu(asrt->u.assert.line),
+		  be32_to_cpu(asrt->u.assert.x),
+		  be32_to_cpu(asrt->u.assert.y));
 }
 
 #define X_CIM_PF_NOACCESS 0xeeeeeeee
 /**
- *	t4_wr_mbox_meat - send a command to FW through the given mailbox
+ *	t4_wr_mbox_meat_timeout - send a command to FW through the given mailbox
  *	@adap: the adapter
  *	@mbox: index of the mailbox to use
  *	@cmd: the command to write
  *	@size: command length in bytes
  *	@rpl: where to optionally store the reply
  *	@sleep_ok: if true we may sleep while awaiting command completion
+ *	@timeout: time to wait for command to finish before timing out
+ *		(negative implies @sleep_ok=false)
  *
  *	Sends the given command to FW through the selected mailbox and waits
  *	for the FW to execute the command.  If @rpl is not %NULL it is used to
@@ -221,14 +253,17 @@ static void fw_asrt(struct adapter *adap
  *	INITIALIZE can take a considerable amount of time to execute.
  *	@sleep_ok determines whether we may sleep while awaiting the response.
  *	If sleeping is allowed we use progressive backoff otherwise we spin.
+ *	Note that passing in a negative @timeout is an alternate mechanism
+ *	for specifying @sleep_ok=false.  This is useful when a higher level
+ *	interface allows for specification of @timeout but not @sleep_ok ...
  *
  *	The return value is 0 on success or a negative errno on failure.  A
  *	failure can happen either because we are not able to execute the
  *	command or FW executes it but signals an error.  In the latter case
  *	the return value is the error code indicated by FW (negated).
  */
-int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
-		    void *rpl, bool sleep_ok)
+int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
+			    int size, void *rpl, bool sleep_ok, int timeout)
 {
 	/*
 	 * We delay in small increments at first in an effort to maintain
@@ -238,43 +273,97 @@ int t4_wr_mbox_meat(struct adapter *adap
 	static const int delay[] = {
 		1, 1, 3, 5, 10, 10, 20, 50, 100
 	};
-
 	u32 v;
 	u64 res;
-	int i, ms, delay_idx;
+	int i, ms, delay_idx, ret;
 	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);
+	u32 ctl;
+	__be64 cmd_rpl[MBOX_LEN/8];
+	u32 pcie_fw;
 
 	if ((size & 15) || size > MBOX_LEN)
 		return -EINVAL;
 
-	v = G_MBOWNER(t4_read_reg(adap, ctl_reg));
-	for (i = 0; v == X_MBOWNER_NONE && i < 3; i++)
-		v = G_MBOWNER(t4_read_reg(adap, ctl_reg));
+	/*
+	 * If we have a negative timeout, that implies that we can't sleep.
+	 */
+	if (timeout < 0) {
+		sleep_ok = false;
+		timeout = -timeout;
+	}
+
+	/*
+	 * Attempt to gain access to the mailbox.
+	 */
+	for (i = 0; i < 4; i++) {
+		ctl = t4_read_reg(adap, ctl_reg);
+		v = G_MBOWNER(ctl);
+		if (v != X_MBOWNER_NONE)
+			break;
+	}
+
+	/*
+	 * If we were unable to gain access, dequeue ourselves from the
+	 * mailbox atomic access list and report the error to our caller.
+	 */
+	if (v != X_MBOWNER_PL) {
+		t4_report_fw_error(adap);
+		ret = (v == X_MBOWNER_FW) ? -EBUSY : -ETIMEDOUT;
+		return ret;
+	}
 
-	if (v != X_MBOWNER_PL)
-		return v ? -EBUSY : -ETIMEDOUT;
+	/*
+	 * If we gain ownership of the mailbox and there's a "valid" message
+	 * in it, this is likely an asynchronous error message from the
+	 * firmware.  So we'll report that and then proceed on with attempting
+	 * to issue our own command ... which may well fail if the error
+	 * presaged the firmware crashing ...
+	 */
+	if (ctl & F_MBMSGVALID) {
+		CH_ERR(adap, "found VALID command in mbox %u: "
+		       "%llx %llx %llx %llx %llx %llx %llx %llx\n", mbox,
+		       (unsigned long long)t4_read_reg64(adap, data_reg),
+		       (unsigned long long)t4_read_reg64(adap, data_reg + 8),
+		       (unsigned long long)t4_read_reg64(adap, data_reg + 16),
+		       (unsigned long long)t4_read_reg64(adap, data_reg + 24),
+		       (unsigned long long)t4_read_reg64(adap, data_reg + 32),
+		       (unsigned long long)t4_read_reg64(adap, data_reg + 40),
+		       (unsigned long long)t4_read_reg64(adap, data_reg + 48),
+		       (unsigned long long)t4_read_reg64(adap, data_reg + 56));
+	}
 
+	/*
+	 * Copy in the new mailbox command and send it on its way ...
+	 */
 	for (i = 0; i < size; i += 8, p++)
 		t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p));
 
 	CH_DUMP_MBOX(adap, mbox, data_reg);
 
 	t4_write_reg(adap, ctl_reg, F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW));
-	t4_read_reg(adap, ctl_reg);          /* flush write */
+	t4_read_reg(adap, ctl_reg);	/* flush write */
 
 	delay_idx = 0;
 	ms = delay[0];
 
-	for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
+	/*
+	 * Loop waiting for the reply; bail out if we time out or the firmware
+	 * reports an error.
+	 */
+	for (i = 0;
+	     !((pcie_fw = t4_read_reg(adap, A_PCIE_FW)) & F_PCIE_FW_ERR) &&
+	     i < timeout;
+	     i += ms) {
 		if (sleep_ok) {
 			ms = delay[delay_idx];  /* last element may repeat */
 			if (delay_idx < ARRAY_SIZE(delay) - 1)
 				delay_idx++;
 			msleep(ms);
-		} else
+		} else {
 			mdelay(ms);
+		}
 
 		v = t4_read_reg(adap, ctl_reg);
 		if (v == X_CIM_PF_NOACCESS)
@@ -286,15 +375,20 @@ int t4_wr_mbox_meat(struct adapter *adap
 				continue;
 			}
 
+			/*
+			 * Retrieve the command reply and release the mailbox.
+			 */
+			get_mbox_rpl(adap, cmd_rpl, size/8, data_reg);
+			t4_write_reg(adap, ctl_reg, V_MBOWNER(X_MBOWNER_NONE));
+
 			CH_DUMP_MBOX(adap, mbox, data_reg);
 
-			res = t4_read_reg64(adap, data_reg);
+			res = be64_to_cpu(cmd_rpl[0]);
 			if (G_FW_CMD_OP(res >> 32) == FW_DEBUG_CMD) {
-				fw_asrt(adap, data_reg);
+				fw_asrt(adap, (struct fw_debug_cmd *)cmd_rpl);
 				res = V_FW_CMD_RETVAL(EIO);
 			} else if (rpl)
-				get_mbox_rpl(adap, rpl, size / 8, data_reg);
-			t4_write_reg(adap, ctl_reg, V_MBOWNER(X_MBOWNER_NONE));
+				memcpy(rpl, cmd_rpl, size);
 			return -G_FW_CMD_RETVAL((int)res);
 		}
 	}
@@ -304,11 +398,58 @@ int t4_wr_mbox_meat(struct adapter *adap
 	 * the error and also check to see if the firmware reported any
 	 * errors ...
 	 */
+	ret = (pcie_fw & F_PCIE_FW_ERR) ? -ENXIO : -ETIMEDOUT;
 	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;
+
+	t4_report_fw_error(adap);
+	t4_fatal_err(adap);
+	return ret;
+}
+
+int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
+		    void *rpl, bool sleep_ok)
+{
+		return t4_wr_mbox_meat_timeout(adap, mbox, cmd, size, rpl,
+					       sleep_ok, FW_CMD_MAX_TIMEOUT);
+
+}
+
+static int t4_edc_err_read(struct adapter *adap, int idx)
+{
+	u32 edc_ecc_err_addr_reg;
+	u32 edc_bist_status_rdata_reg;
+
+	if (is_t4(adap)) {
+		CH_WARN(adap, "%s: T4 NOT supported.\n", __func__);
+		return 0;
+	}
+	if (idx != 0 && idx != 1) {
+		CH_WARN(adap, "%s: idx %d NOT supported.\n", __func__, idx);
+		return 0;
+	}
+
+	edc_ecc_err_addr_reg = EDC_T5_REG(A_EDC_H_ECC_ERR_ADDR, idx);
+	edc_bist_status_rdata_reg = EDC_T5_REG(A_EDC_H_BIST_STATUS_RDATA, idx);
+
+	CH_WARN(adap,
+		"edc%d err addr 0x%x: 0x%x.\n",
+		idx, edc_ecc_err_addr_reg,
+		t4_read_reg(adap, edc_ecc_err_addr_reg));
+	CH_WARN(adap,
+	 	"bist: 0x%x, status %llx %llx %llx %llx %llx %llx %llx %llx %llx.\n",
+		edc_bist_status_rdata_reg,
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 8),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 16),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 24),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 32),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 40),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 48),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 56),
+		(unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 64));
+
+	return 0;
 }
 
 /**
@@ -493,8 +634,1956 @@ int t4_mem_read(struct adapter *adap, in
 }
 
 /*
+ * Return the specified PCI-E Configuration Space register from our Physical
+ * Function.  We try first via a Firmware LDST Command (if fw_attach != 0)
+ * since we prefer to let the firmware own all of these registers, but if that
+ * fails we go for it directly ourselves.
+ */
+u32 t4_read_pcie_cfg4(struct adapter *adap, int reg, int drv_fw_attach)
+{
+
+	/*
+	 * If fw_attach != 0, construct and send the Firmware LDST Command to
+	 * retrieve the specified PCI-E Configuration Space register.
+	 */
+	if (drv_fw_attach != 0) {
+		struct fw_ldst_cmd ldst_cmd;
+		int ret;
+
+		memset(&ldst_cmd, 0, sizeof(ldst_cmd));
+		ldst_cmd.op_to_addrspace =
+			cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) |
+				    F_FW_CMD_REQUEST |
+				    F_FW_CMD_READ |
+				    V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE));
+		ldst_cmd.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst_cmd));
+		ldst_cmd.u.pcie.select_naccess = V_FW_LDST_CMD_NACCESS(1);
+		ldst_cmd.u.pcie.ctrl_to_fn =
+			(F_FW_LDST_CMD_LC | V_FW_LDST_CMD_FN(adap->pf));
+		ldst_cmd.u.pcie.r = reg;
+
+		/*
+		 * If the LDST Command succeeds, return the result, otherwise
+		 * fall through to reading it directly ourselves ...
+		 */
+		ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd, sizeof(ldst_cmd),
+				 &ldst_cmd);
+		if (ret == 0)
+			return be32_to_cpu(ldst_cmd.u.pcie.data[0]);
+
+		CH_WARN(adap, "Firmware failed to return "
+			"Configuration Space register %d, err = %d\n",
+			reg, -ret);
+	}
+
+	/*
+	 * Read the desired Configuration Space register via the PCI-E
+	 * Backdoor mechanism.
+	 */
+	return t4_hw_pci_read_cfg4(adap, reg);
+}
+
+/**
+ *	t4_get_regs_len - return the size of the chips register set
+ *	@adapter: the adapter
+ *
+ *	Returns the size of the chip's BAR0 register space.
+ */
+unsigned int t4_get_regs_len(struct adapter *adapter)
+{
+	unsigned int chip_version = chip_id(adapter);
+
+	switch (chip_version) {
+	case CHELSIO_T4:
+		return T4_REGMAP_SIZE;
+
+	case CHELSIO_T5:
+	case CHELSIO_T6:
+		return T5_REGMAP_SIZE;
+	}
+
+	CH_ERR(adapter,
+		"Unsupported chip version %d\n", chip_version);
+	return 0;
+}
+
+/**
+ *	t4_get_regs - read chip registers into provided buffer
+ *	@adap: the adapter
+ *	@buf: register buffer
+ *	@buf_size: size (in bytes) of register buffer
+ *
+ *	If the provided register buffer isn't large enough for the chip's
+ *	full register range, the register dump will be truncated to the
+ *	register buffer's size.
+ */
+void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size)
+{
+	static const unsigned int t4_reg_ranges[] = {
+		0x1008, 0x1108,
+		0x1180, 0x1184,
+		0x1190, 0x1194,
+		0x11a0, 0x11a4,
+		0x11b0, 0x11b4,
+		0x11fc, 0x123c,
+		0x1300, 0x173c,
+		0x1800, 0x18fc,
+		0x3000, 0x30d8,
+		0x30e0, 0x30e4,
+		0x30ec, 0x5910,
+		0x5920, 0x5924,
+		0x5960, 0x5960,
+		0x5968, 0x5968,
+		0x5970, 0x5970,
+		0x5978, 0x5978,
+		0x5980, 0x5980,
+		0x5988, 0x5988,
+		0x5990, 0x5990,
+		0x5998, 0x5998,
+		0x59a0, 0x59d4,
+		0x5a00, 0x5ae0,
+		0x5ae8, 0x5ae8,
+		0x5af0, 0x5af0,
+		0x5af8, 0x5af8,
+		0x6000, 0x6098,
+		0x6100, 0x6150,
+		0x6200, 0x6208,
+		0x6240, 0x6248,
+		0x6280, 0x62b0,
+		0x62c0, 0x6338,
+		0x6370, 0x638c,
+		0x6400, 0x643c,
+		0x6500, 0x6524,
+		0x6a00, 0x6a04,
+		0x6a14, 0x6a38,
+		0x6a60, 0x6a70,
+		0x6a78, 0x6a78,
+		0x6b00, 0x6b0c,
+		0x6b1c, 0x6b84,
+		0x6bf0, 0x6bf8,
+		0x6c00, 0x6c0c,
+		0x6c1c, 0x6c84,
+		0x6cf0, 0x6cf8,
+		0x6d00, 0x6d0c,
+		0x6d1c, 0x6d84,
+		0x6df0, 0x6df8,
+		0x6e00, 0x6e0c,
+		0x6e1c, 0x6e84,
+		0x6ef0, 0x6ef8,
+		0x6f00, 0x6f0c,
+		0x6f1c, 0x6f84,
+		0x6ff0, 0x6ff8,
+		0x7000, 0x700c,
+		0x701c, 0x7084,
+		0x70f0, 0x70f8,
+		0x7100, 0x710c,
+		0x711c, 0x7184,
+		0x71f0, 0x71f8,
+		0x7200, 0x720c,

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



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