summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2007-07-17 06:50:35 +0000
committerkmacy <kmacy@FreeBSD.org>2007-07-17 06:50:35 +0000
commit184f644f1c7454264aae840d0f2d00b8821565a1 (patch)
tree3a71c29bff9410f492cfa619778e43dc470c28c0
parent2d80191535ea4f0e6ebd0ab985542b868dec5405 (diff)
downloadFreeBSD-src-184f644f1c7454264aae840d0f2d00b8821565a1.zip
FreeBSD-src-184f644f1c7454264aae840d0f2d00b8821565a1.tar.gz
- integrate most recent changes from vendor branch and upgrade to firmware revision 4.5.5
- add filter support - further improvements for T304 - recover gracefully from spurious immediate packets Approved by: re(blanket) Supported by: Chelsio MFC after: 3 days
-rw-r--r--sys/dev/cxgb/common/cxgb_common.h27
-rw-r--r--sys/dev/cxgb/common/cxgb_ctl_defs.h24
-rw-r--r--sys/dev/cxgb/common/cxgb_mc5.c45
-rw-r--r--sys/dev/cxgb/common/cxgb_t3_cpl.h36
-rw-r--r--sys/dev/cxgb/common/cxgb_t3_hw.c145
-rw-r--r--sys/dev/cxgb/common/cxgb_vsc7323.c37
-rw-r--r--sys/dev/cxgb/common/cxgb_xgmac.c55
-rw-r--r--sys/dev/cxgb/cxgb_adapter.h9
-rw-r--r--sys/dev/cxgb/cxgb_ioctl.h27
-rw-r--r--sys/dev/cxgb/cxgb_main.c585
-rw-r--r--sys/dev/cxgb/cxgb_offload.c28
-rw-r--r--sys/dev/cxgb/cxgb_offload.h6
-rw-r--r--sys/dev/cxgb/cxgb_osdep.h14
-rw-r--r--sys/dev/cxgb/cxgb_sge.c103
-rw-r--r--sys/dev/cxgb/sys/mvec.h7
-rw-r--r--sys/dev/cxgb/t3b_protocol_sram-1.1.0.bin.gz.uu46
-rw-r--r--sys/dev/cxgb/t3b_tp_eeprom-1.1.0.bin.gz.uu46
-rw-r--r--sys/dev/cxgb/t3fw-4.1.0.bin.gz.uu482
-rw-r--r--sys/dev/cxgb/t3fw-4.5.0.bin.gz.uu442
-rw-r--r--sys/modules/cxgb/Makefile24
20 files changed, 1494 insertions, 694 deletions
diff --git a/sys/dev/cxgb/common/cxgb_common.h b/sys/dev/cxgb/common/cxgb_common.h
index 0a60a56..9d75102 100644
--- a/sys/dev/cxgb/common/cxgb_common.h
+++ b/sys/dev/cxgb/common/cxgb_common.h
@@ -38,8 +38,6 @@ $FreeBSD$
#endif
enum {
- MAX_NPORTS = 4,
- TP_TMR_RES = 200, /* TP timer resolution in usec */
MAX_FRAME_SIZE = 10240, /* max MAC frame size, includes header + FCS */
EEPROMSIZE = 8192, /* Serial EEPROM size */
RSS_TABLE_SIZE = 64, /* size of RSS lookup and mapping tables */
@@ -48,6 +46,10 @@ enum {
NCCTRL_WIN = 32, /* # of congestion control windows */
NTX_SCHED = 8, /* # of HW Tx scheduling queues */
PROTO_SRAM_LINES = 128, /* size of protocol sram */
+ MAX_NPORTS = 4,
+ TP_TMR_RES = 200,
+ TP_SRAM_OFFSET = 4096, /* TP SRAM content offset in eeprom */
+ TP_SRAM_LEN = 2112, /* TP SRAM content offset in eeprom */
};
#define MAX_RX_COALESCING_LEN 12288U
@@ -72,8 +74,8 @@ enum { /* adapter interrupt-maintained statistics */
enum {
TP_VERSION_MAJOR = 1,
- TP_VERSION_MINOR = 0,
- TP_VERSION_MICRO = 44
+ TP_VERSION_MINOR = 1,
+ TP_VERSION_MICRO = 0
};
#define S_TP_VERSION_MAJOR 16
@@ -96,7 +98,7 @@ enum {
enum {
FW_VERSION_MAJOR = 4,
- FW_VERSION_MINOR = 1,
+ FW_VERSION_MINOR = 5,
FW_VERSION_MICRO = 0
};
@@ -393,6 +395,7 @@ enum { /* chip revisions */
T3_REV_A = 0,
T3_REV_B = 2,
T3_REV_B2 = 3,
+ T3_REV_C = 4,
};
struct trace_params {
@@ -467,6 +470,7 @@ struct cmac {
unsigned int tx_xcnt;
u64 tx_mcnt;
unsigned int rx_xcnt;
+ unsigned int rx_ocnt;
u64 rx_mcnt;
unsigned int toggle_cnt;
unsigned int txen;
@@ -562,6 +566,9 @@ static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
/* Accumulate MAC statistics every 180 seconds. For 1G we multiply by 10. */
#define MAC_STATS_ACCUM_SECS 180
+/* The external MAC needs accumulation every 30 seconds */
+#define VSC_STATS_ACCUM_SECS 30
+
#define XGM_REG(reg_addr, idx) \
((reg_addr) + (idx) * (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR))
@@ -656,9 +663,10 @@ int t3_seeprom_write(adapter_t *adapter, u32 addr, u32 data);
int t3_seeprom_wp(adapter_t *adapter, int enable);
int t3_read_flash(adapter_t *adapter, unsigned int addr, unsigned int nwords,
u32 *data, int byte_oriented);
+int t3_get_tp_version(adapter_t *adapter, u32 *vers);
int t3_check_tpsram_version(adapter_t *adapter);
-int t3_check_tpsram(adapter_t *adapter, u8 *tp_ram, unsigned int size);
-int t3_load_fw(adapter_t *adapter, const u8 *fw_data, unsigned int size);
+int t3_check_tpsram(adapter_t *adapter, const u8 *tp_ram, unsigned int size);
+int t3_load_fw(adapter_t *adapter, const const u8 *fw_data, unsigned int size);
int t3_get_fw_version(adapter_t *adapter, u32 *vers);
int t3_check_fw_version(adapter_t *adapter);
int t3_init_hw(adapter_t *adapter, u32 fw_params);
@@ -668,10 +676,11 @@ int t3_prep_adapter(adapter_t *adapter, const struct adapter_info *ai, int reset
void t3_led_ready(adapter_t *adapter);
void t3_fatal_err(adapter_t *adapter);
void t3_set_vlan_accel(adapter_t *adapter, unsigned int ports, int on);
+void t3_enable_filters(adapter_t *adap);
void t3_config_rss(adapter_t *adapter, unsigned int rss_config, const u8 *cpus,
const u16 *rspq);
int t3_read_rss(adapter_t *adapter, u8 *lkup, u16 *map);
-int t3_set_proto_sram(adapter_t *adap, u8 *data);
+int t3_set_proto_sram(adapter_t *adap, const u8 *data);
int t3_mps_set_active_ports(adapter_t *adap, unsigned int port_mask);
void t3_port_failover(adapter_t *adapter, int port);
void t3_failover_done(adapter_t *adapter, int port);
@@ -753,8 +762,8 @@ int t3_elmr_blk_write(adapter_t *adap, int start, const u32 *vals, int n);
int t3_elmr_blk_read(adapter_t *adap, int start, u32 *vals, int n);
int t3_vsc7323_init(adapter_t *adap, int nports);
int t3_vsc7323_set_speed_fc(adapter_t *adap, int speed, int fc, int port);
-int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port);
int t3_vsc7323_set_mtu(adapter_t *adap, unsigned int mtu, int port);
+int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port);
int t3_vsc7323_enable(adapter_t *adap, int port, int which);
int t3_vsc7323_disable(adapter_t *adap, int port, int which);
const struct mac_stats *t3_vsc7323_update_stats(struct cmac *mac);
diff --git a/sys/dev/cxgb/common/cxgb_ctl_defs.h b/sys/dev/cxgb/common/cxgb_ctl_defs.h
index 5909955..e96f497 100644
--- a/sys/dev/cxgb/common/cxgb_ctl_defs.h
+++ b/sys/dev/cxgb/common/cxgb_ctl_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2007 Chelsio Communications. All rights reserved.
+ * Copyright (C) 2003-2006 Chelsio Communications. All rights reserved.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -12,7 +12,6 @@
#ifndef _CXGB3_OFFLOAD_CTL_DEFS_H
#define _CXGB3_OFFLOAD_CTL_DEFS_H
-
enum {
GET_MAX_OUTSTANDING_WR,
GET_TX_MAX_CHUNK,
@@ -25,9 +24,6 @@ enum {
GET_IFF_FROM_MAC,
GET_DDP_PARAMS,
GET_PORTS,
- FAILOVER,
- FAILOVER_DONE,
- FAILOVER_CLEAR,
ULP_ISCSI_GET_PARAMS,
ULP_ISCSI_SET_PARAMS,
@@ -38,6 +34,14 @@ enum {
RDMA_CQ_DISABLE,
RDMA_CTRL_QP_SETUP,
RDMA_GET_MEM,
+
+ FAILOVER,
+ FAILOVER_DONE,
+ FAILOVER_CLEAR,
+
+ GET_CPUIDX_OF_QSET,
+
+ GET_RX_PAGE_INFO,
};
/*
@@ -81,7 +85,7 @@ struct ddp_params {
struct adap_ports {
unsigned int nports; /* number of ports on this adapter */
- struct ifnet *lldevs[4];
+ struct net_device *lldevs[2];
};
/*
@@ -102,6 +106,14 @@ struct ulp_iscsi_info {
};
/*
+ * Offload TX/RX page information.
+ */
+struct ofld_page_info {
+ unsigned int page_size; /* Page size, should be a power of 2 */
+ unsigned int num; /* Number of pages */
+};
+
+/*
* Structure used to return information to the RDMA layer.
*/
struct rdma_info {
diff --git a/sys/dev/cxgb/common/cxgb_mc5.c b/sys/dev/cxgb/common/cxgb_mc5.c
index 07a4d39..d3eed4a 100644
--- a/sys/dev/cxgb/common/cxgb_mc5.c
+++ b/sys/dev/cxgb/common/cxgb_mc5.c
@@ -165,16 +165,26 @@ static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base,
return -1;
/* Initialize the mask array. */
- dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
- for (i = 0; i < size72; i++) {
- if (i == server_base) /* entering server or routing region */
- t3_write_reg(adap, A_MC5_DB_DBGI_REQ_DATA0,
- mc5->mode == MC5_MODE_144_BIT ?
- 0xfffffff9 : 0xfffffffd);
+ for (i = 0; i < server_base; i++) {
+ dbgi_wr_data3(adap, 0x3fffffff, 0xfff80000, 0xff);
+ if (mc5_write(adap, mask_array_base + (i << addr_shift),
+ write_cmd))
+ return -1;
+ i++;
+ dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
if (mc5_write(adap, mask_array_base + (i << addr_shift),
write_cmd))
return -1;
}
+
+ dbgi_wr_data3(adap,
+ mc5->mode == MC5_MODE_144_BIT ? 0xfffffff9 : 0xfffffffd,
+ 0xffffffff, 0xff);
+ for (; i < size72; i++)
+ if (mc5_write(adap, mask_array_base + (i << addr_shift),
+ write_cmd))
+ return -1;
+
return 0;
}
@@ -305,17 +315,15 @@ static int init_idt43102(struct mc5 *mc5)
/* Put MC5 in DBGI mode. */
static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5)
{
- t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
- V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_DBGIEN);
+ t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_PRTYEN | F_MBUSEN,
+ F_DBGIEN);
}
/* Put MC5 in M-Bus mode. */
static void mc5_dbgi_mode_disable(const struct mc5 *mc5)
{
- t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
- V_TMMODE(mc5->mode == MC5_MODE_72_BIT) |
- V_COMPEN(mc5->mode == MC5_MODE_72_BIT) |
- V_PRTYEN(mc5->parity_enabled) | F_MBUSEN);
+ t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_DBGIEN,
+ V_PRTYEN(mc5->parity_enabled) | F_MBUSEN);
}
/*
@@ -325,9 +333,9 @@ static void mc5_dbgi_mode_disable(const struct mc5 *mc5)
int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
unsigned int nroutes)
{
- u32 cfg;
int err;
unsigned int tcam_size = mc5->tcam_size;
+ unsigned int mode72 = mc5->mode == MC5_MODE_72_BIT;
adapter_t *adap = mc5->adapter;
if (!tcam_size)
@@ -336,10 +344,12 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
return -EINVAL;
+ if (nfilters && adap->params.rev < T3_REV_C)
+ mc5->parity_enabled = 0;
+
/* Reset the TCAM */
- cfg = t3_read_reg(adap, A_MC5_DB_CONFIG) & ~F_TMMODE;
- cfg |= V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_TMRST;
- t3_write_reg(adap, A_MC5_DB_CONFIG, cfg);
+ t3_set_reg_field(adap, A_MC5_DB_CONFIG, F_TMMODE | F_COMPEN,
+ V_COMPEN(mode72) | V_TMMODE(mode72) | F_TMRST);
if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) {
CH_ERR(adap, "TCAM reset timed out\n");
return -1;
@@ -351,8 +361,6 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
t3_write_reg(adap, A_MC5_DB_SERVER_INDEX,
tcam_size - nroutes - nfilters - nservers);
- mc5->parity_enabled = 1;
-
/* All the TCAM addresses we access have only the low 32 bits non 0 */
t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0);
t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0);
@@ -467,6 +475,7 @@ void __devinit t3_mc5_prep(adapter_t *adapter, struct mc5 *mc5, int mode)
u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG);
mc5->adapter = adapter;
+ mc5->parity_enabled = 1;
mc5->mode = (unsigned char) mode;
mc5->part_type = (unsigned char) G_TMTYPE(cfg);
if (cfg & F_TMTYPEHI)
diff --git a/sys/dev/cxgb/common/cxgb_t3_cpl.h b/sys/dev/cxgb/common/cxgb_t3_cpl.h
index 06e99f2..e1b4030 100644
--- a/sys/dev/cxgb/common/cxgb_t3_cpl.h
+++ b/sys/dev/cxgb/common/cxgb_t3_cpl.h
@@ -31,10 +31,6 @@ $FreeBSD$
#ifndef T3_CPL_H
#define T3_CPL_H
-#if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD)
-# include <asm/byteorder.h>
-#endif
-
enum CPL_opcode {
CPL_PASS_OPEN_REQ = 0x1,
CPL_PASS_ACCEPT_RPL = 0x2,
@@ -133,6 +129,7 @@ enum CPL_error {
enum {
CPL_CONN_POLICY_AUTO = 0,
CPL_CONN_POLICY_ASK = 1,
+ CPL_CONN_POLICY_FILTER = 2,
CPL_CONN_POLICY_DENY = 3
};
@@ -259,16 +256,16 @@ struct work_request_hdr {
/* Applicable to BYPASS WRs only: the uP will added a CPL_BARRIER before
* and after the BYPASS WR if the ATOMIC bit is set.
*/
-#define S_WR_ATOMIC 16
-#define V_WR_ATOMIC(x) ((x) << S_WR_ATOMIC)
-#define F_WR_ATOMIC V_WR_ATOMIC(1U)
+#define S_WR_ATOMIC 16
+#define V_WR_ATOMIC(x) ((x) << S_WR_ATOMIC)
+#define F_WR_ATOMIC V_WR_ATOMIC(1U)
/* Applicable to BYPASS WRs only: the uP will flush buffered non abort
* related WRs.
*/
-#define S_WR_FLUSH 17
-#define V_WR_FLUSH(x) ((x) << S_WR_FLUSH)
-#define F_WR_FLUSH V_WR_FLUSH(1U)
+#define S_WR_FLUSH 17
+#define V_WR_FLUSH(x) ((x) << S_WR_FLUSH)
+#define F_WR_FLUSH V_WR_FLUSH(1U)
#define S_WR_DATATYPE 20
#define V_WR_DATATYPE(x) ((x) << S_WR_DATATYPE)
@@ -415,6 +412,11 @@ struct work_request_hdr {
#define V_CPU_IDX(x) ((x) << S_CPU_IDX)
#define G_CPU_IDX(x) (((x) >> S_CPU_IDX) & M_CPU_IDX)
+#define S_OPT1_VLAN 6
+#define M_OPT1_VLAN 0xFFF
+#define V_OPT1_VLAN(x) ((x) << S_OPT1_VLAN)
+#define G_OPT1_VLAN(x) (((x) >> S_OPT1_VLAN) & M_OPT1_VLAN)
+
#define S_MAC_MATCH_VALID 18
#define V_MAC_MATCH_VALID(x) ((x) << S_MAC_MATCH_VALID)
#define F_MAC_MATCH_VALID V_MAC_MATCH_VALID(1U)
@@ -808,6 +810,12 @@ struct tx_data_wr {
__be32 param;
};
+/* tx_data_wr.flags fields */
+#define S_TX_ACK_PAGES 21
+#define M_TX_ACK_PAGES 0x7
+#define V_TX_ACK_PAGES(x) ((x) << S_TX_ACK_PAGES)
+#define G_TX_ACK_PAGES(x) (((x) >> S_TX_ACK_PAGES) & M_TX_ACK_PAGES)
+
/* tx_data_wr.param fields */
#define S_TX_PORT 0
#define M_TX_PORT 0x7
@@ -1009,7 +1017,7 @@ struct cpl_rx_data_ddp {
union {
__be32 nxt_seq;
__be32 ddp_report;
- } __U;
+ } u;
__be32 ulp_crc;
__be32 ddpvld_status;
};
@@ -1515,7 +1523,7 @@ struct ulp_mem_io {
__be32 len;
};
- /* ulp_mem_io.cmd_lock_addr fields */
+/* ulp_mem_io.cmd_lock_addr fields */
#define S_ULP_MEMIO_ADDR 0
#define M_ULP_MEMIO_ADDR 0x7FFFFFF
#define V_ULP_MEMIO_ADDR(x) ((x) << S_ULP_MEMIO_ADDR)
@@ -1524,7 +1532,7 @@ struct ulp_mem_io {
#define V_ULP_MEMIO_LOCK(x) ((x) << S_ULP_MEMIO_LOCK)
#define F_ULP_MEMIO_LOCK V_ULP_MEMIO_LOCK(1U)
- /* ulp_mem_io.len fields */
+/* ulp_mem_io.len fields */
#define S_ULP_MEMIO_DATA_LEN 28
#define M_ULP_MEMIO_DATA_LEN 0xF
#define V_ULP_MEMIO_DATA_LEN(x) ((x) << S_ULP_MEMIO_DATA_LEN)
@@ -1534,7 +1542,7 @@ struct ulp_txpkt {
__be32 len;
};
- /* ulp_txpkt.cmd_dest fields */
+/* ulp_txpkt.cmd_dest fields */
#define S_ULP_TXPKT_DEST 24
#define M_ULP_TXPKT_DEST 0xF
#define V_ULP_TXPKT_DEST(x) ((x) << S_ULP_TXPKT_DEST)
diff --git a/sys/dev/cxgb/common/cxgb_t3_hw.c b/sys/dev/cxgb/common/cxgb_t3_hw.c
index 2e92187..a8d9e11 100644
--- a/sys/dev/cxgb/common/cxgb_t3_hw.c
+++ b/sys/dev/cxgb/common/cxgb_t3_hw.c
@@ -37,8 +37,8 @@ __FBSDID("$FreeBSD$");
#include <dev/cxgb/cxgb_include.h>
#endif
-#define DENTER() printf("entered %s\n", __FUNCTION__);
-#define DEXIT() printf("exiting %s\n", __FUNCTION__);
+#undef msleep
+#define msleep t3_os_sleep
/**
@@ -355,7 +355,7 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait)
return err;
ctl &= BMCR_RESET;
if (ctl)
- t3_os_sleep(1);
+ msleep(1);
} while (ctl && --wait);
return ctl ? -1 : 0;
@@ -482,7 +482,7 @@ const struct adapter_info *t3_get_adapter_info(unsigned int id)
#define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI)
static struct port_type_info port_types[] = {
- { NULL, 0, NULL },
+ { NULL },
{ t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE,
"10GBASE-XR" },
{ t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ,
@@ -594,7 +594,7 @@ int t3_seeprom_write(adapter_t *adapter, u32 addr, u32 data)
t3_os_pci_write_config_2(adapter, base + PCI_VPD_ADDR,
(u16)addr | PCI_VPD_ADDR_F);
do {
- t3_os_sleep(1);
+ msleep(1);
t3_os_pci_read_config_2(adapter, base + PCI_VPD_ADDR, &val);
} while ((val & PCI_VPD_ADDR_F) && --attempts);
@@ -770,7 +770,7 @@ static int flash_wait_op(adapter_t *adapter, int attempts, int delay)
if (--attempts == 0)
return -EAGAIN;
if (delay)
- t3_os_sleep(delay);
+ msleep(delay);
}
}
@@ -860,10 +860,32 @@ static int t3_write_flash(adapter_t *adapter, unsigned int addr,
}
/**
+ * t3_get_tp_version - read the tp sram version
+ * @adapter: the adapter
+ * @vers: where to place the version
+ *
+ * Reads the protocol sram version from sram.
+ */
+int t3_get_tp_version(adapter_t *adapter, u32 *vers)
+{
+ int ret;
+
+ /* Get version loaded in SRAM */
+ t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
+ ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
+ 1, 1, 5, 1);
+ if (ret)
+ return ret;
+
+ *vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
+
+ return 0;
+}
+
+/**
* t3_check_tpsram_version - read the tp sram version
* @adapter: the adapter
*
- * Reads the protocol sram version from serial eeprom.
*/
int t3_check_tpsram_version(adapter_t *adapter)
{
@@ -886,6 +908,9 @@ int t3_check_tpsram_version(adapter_t *adapter)
if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
return 0;
+ CH_ERR(adapter, "found wrong TP version (%u.%u), "
+ "driver needs version %d.%d\n", major, minor,
+ TP_VERSION_MAJOR, TP_VERSION_MINOR);
return -EINVAL;
}
@@ -899,7 +924,7 @@ int t3_check_tpsram_version(adapter_t *adapter)
* Checks if an adapter's tp sram is compatible with the driver.
* Returns 0 if the versions are compatible, a negative error otherwise.
*/
-int t3_check_tpsram(adapter_t *adapter, u8 *tp_sram, unsigned int size)
+int t3_check_tpsram(adapter_t *adapter, const u8 *tp_sram, unsigned int size)
{
u32 csum;
unsigned int i;
@@ -960,8 +985,8 @@ int t3_check_fw_version(adapter_t *adapter)
return 0;
CH_ERR(adapter, "found wrong FW version (%u.%u), "
- "driver needs version %d.%d\n", major, minor,
- FW_VERSION_MAJOR, FW_VERSION_MINOR);
+ "driver needs version %d.%d\n", major, minor,
+ FW_VERSION_MAJOR, FW_VERSION_MINOR);
return -EINVAL;
}
@@ -2329,6 +2354,28 @@ void t3_tp_set_offload_mode(adapter_t *adap, int enable)
V_NICMODE(!enable));
}
+static void tp_wr_bits_indirect(adapter_t *adap, unsigned int addr,
+ unsigned int mask, unsigned int val)
+{
+ t3_write_reg(adap, A_TP_PIO_ADDR, addr);
+ val |= t3_read_reg(adap, A_TP_PIO_DATA) & ~mask;
+ t3_write_reg(adap, A_TP_PIO_DATA, val);
+}
+
+/**
+ * t3_enable_filters - enable the HW filters
+ * @adap: the adapter
+ *
+ * Enables the HW filters for NIC traffic.
+ */
+void t3_enable_filters(adapter_t *adap)
+{
+ t3_set_reg_field(adap, A_TP_IN_CONFIG, F_NICMODE, 0);
+ t3_set_reg_field(adap, A_MC5_DB_CONFIG, 0, F_FILTEREN);
+ t3_set_reg_field(adap, A_TP_GLOBAL_CONFIG, 0, V_FIVETUPLELOOKUP(3));
+ tp_wr_bits_indirect(adap, A_TP_INGRESS_CONFIG, 0, F_LOOKUPEVERYPKT);
+}
+
/**
* pm_num_pages - calculate the number of pages of the payload memory
* @mem_size: the size of the payload memory
@@ -2422,14 +2469,6 @@ static inline void tp_wr_indirect(adapter_t *adap, unsigned int addr, u32 val)
t3_write_reg(adap, A_TP_PIO_DATA, val);
}
-static void tp_wr_bits_indirect(adapter_t *adap, unsigned int addr,
- unsigned int mask, unsigned int val)
-{
- t3_write_reg(adap, A_TP_PIO_ADDR, addr);
- val |= t3_read_reg(adap, A_TP_PIO_DATA) & ~mask;
- t3_write_reg(adap, A_TP_PIO_DATA, val);
-}
-
static void tp_config(adapter_t *adap, const struct tp_params *p)
{
t3_write_reg(adap, A_TP_GLOBAL_CONFIG, F_TXPACINGENABLE | F_PATHMTU |
@@ -2459,10 +2498,12 @@ static void tp_config(adapter_t *adap, const struct tp_params *p)
if (adap->params.rev > 0) {
tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
- t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO,
- F_TXPACEAUTO);
+ t3_set_reg_field(adap, A_TP_PARA_REG3, 0,
+ F_TXPACEAUTO | F_TXPACEAUTOSTRICT);
t3_set_reg_field(adap, A_TP_PC_CONFIG, F_LOCKTID, F_LOCKTID);
- t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEAUTOSTRICT);
+ tp_wr_indirect(adap, A_TP_VLAN_PRI_MAP, 0xfa50);
+ tp_wr_indirect(adap, A_TP_MAC_MATCH_MAP0, 0xfac688);
+ tp_wr_indirect(adap, A_TP_MAC_MATCH_MAP1, 0xfac688);
} else
t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
@@ -2816,17 +2857,17 @@ static void ulp_config(adapter_t *adap, const struct tp_params *p)
*
* Write the contents of the protocol SRAM.
*/
-int t3_set_proto_sram(adapter_t *adap, u8 *data)
+int t3_set_proto_sram(adapter_t *adap, const u8 *data)
{
int i;
- u32 *buf = (u32 *)data;
+ u32 *buf = (u32 *)(uintptr_t)data;
for (i = 0; i < PROTO_SRAM_LINES; i++) {
- t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, htobe32(*buf++));
- t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, htobe32(*buf++));
- t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, htobe32(*buf++));
- t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, htobe32(*buf++));
- t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, htobe32(*buf++));
+ t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
+ t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
+ t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
+ t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
+ t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
@@ -3053,7 +3094,7 @@ static int calibrate_xgm(adapter_t *adapter)
for (i = 0; i < 5; ++i) {
t3_write_reg(adapter, A_XGM_XAUI_IMP, 0);
(void) t3_read_reg(adapter, A_XGM_XAUI_IMP);
- t3_os_sleep(1);
+ msleep(1);
v = t3_read_reg(adapter, A_XGM_XAUI_IMP);
if (!(v & (F_XGM_CALFAULT | F_CALBUSY))) {
t3_write_reg(adapter, A_XGM_XAUI_IMP,
@@ -3140,12 +3181,12 @@ static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
t3_write_reg(adapter, mc7->offset + A_MC7_CFG, val | F_IFEN);
val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); /* flush */
- t3_os_sleep(1);
+ msleep(1);
if (!slow) {
t3_write_reg(adapter, mc7->offset + A_MC7_CAL, F_SGL_CAL_EN);
(void) t3_read_reg(adapter, mc7->offset + A_MC7_CAL);
- t3_os_sleep(1);
+ msleep(1);
if (t3_read_reg(adapter, mc7->offset + A_MC7_CAL) &
(F_BUSY | F_SGL_CAL_EN | F_CAL_FAULT)) {
CH_ERR(adapter, "%s MC7 calibration timed out\n",
@@ -3211,7 +3252,7 @@ static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
attempts = 50;
do {
- t3_os_sleep(250);
+ msleep(250);
val = t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP);
} while ((val & F_BUSY) && --attempts);
if (val & F_BUSY) {
@@ -3297,11 +3338,8 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
else if (calibrate_xgm(adapter))
goto out_err;
- if (adapter->params.nports > 2) {
+ if (adapter->params.nports > 2)
t3_mac_reset(&adap2pinfo(adapter, 0)->mac);
- if ((err = t3_vsc7323_init(adapter, adapter->params.nports)))
- goto out_err;
- }
if (vpd->mclk) {
partition_mem(adapter, &adapter->params.tp);
@@ -3341,7 +3379,7 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
(void) t3_read_reg(adapter, A_CIM_BOOT_CFG); /* flush */
do { /* wait for uP to initialize */
- t3_os_sleep(20);
+ msleep(20);
} while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
if (!attempts) {
CH_ERR(adapter, "uP initialization timed out\n");
@@ -3453,7 +3491,6 @@ void mac_prep(struct cmac *mac, adapter_t *adapter, int index)
{
mac->adapter = adapter;
mac->multiport = adapter->params.nports > 2;
-
if (mac->multiport) {
mac->ext_port = (unsigned char)index;
mac->nucast = 8;
@@ -3516,7 +3553,7 @@ static int t3_reset_adapter(adapter_t *adapter)
* XXX The delay time should be modified.
*/
for (i = 0; i < 10; i++) {
- t3_os_sleep(50);
+ msleep(50);
t3_os_pci_read_config_2(adapter, 0x00, &devid);
if (devid == 0x1425)
break;
@@ -3548,16 +3585,18 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1);
adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
adapter->params.linkpoll_period = 0;
- adapter->params.stats_update_period = is_10G(adapter) ?
- MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
+ if (adapter->params.nports > 2)
+ adapter->params.stats_update_period = VSC_STATS_ACCUM_SECS;
+ else
+ adapter->params.stats_update_period = is_10G(adapter) ?
+ MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
adapter->params.pci.vpd_cap_addr =
t3_os_find_pci_capability(adapter, PCI_CAP_ID_VPD);
ret = get_vpd_params(adapter, &adapter->params.vpd);
- if (ret < 0) {
- printf("failed to get VPD params\n");
+ if (ret < 0)
return ret;
- }
+
if (reset && t3_reset_adapter(adapter))
return -1;
@@ -3606,24 +3645,18 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
early_hw_init(adapter, ai);
+ if (adapter->params.nports > 2 &&
+ (ret = t3_vsc7323_init(adapter, adapter->params.nports)))
+ return ret;
+
for_each_port(adapter, i) {
u8 hw_addr[6];
struct port_info *p = adap2pinfo(adapter, i);
- while (adapter->params.vpd.port_type[j] == 0) {
+ while (!adapter->params.vpd.port_type[j])
++j;
- }
- if (adapter->params.vpd.port_type[j] > sizeof(port_types)/sizeof(port_types[0])) {
- printf("bad port type idx=%d\n", adapter->params.vpd.port_type[j]);
- printf("port types: ");
- for (i = 0; i < j; i++)
- printf("port[%d]=%d ", i, adapter->params.vpd.port_type[i]);
- printf("\n");
- return -1;
- }
-
- p->port_type = &port_types[adapter->params.vpd.port_type[j]];
+ p->port_type = &port_types[adapter->params.vpd.port_type[j]];
p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
ai->mdio_ops);
mac_prep(&p->mac, adapter, j);
diff --git a/sys/dev/cxgb/common/cxgb_vsc7323.c b/sys/dev/cxgb/common/cxgb_vsc7323.c
index 51e254e..4efd24e 100644
--- a/sys/dev/cxgb/common/cxgb_vsc7323.c
+++ b/sys/dev/cxgb/common/cxgb_vsc7323.c
@@ -115,13 +115,16 @@ int t3_vsc7323_init(adapter_t *adap, int nports)
{ VSC_REG(2, 0, 0x2f), 0 },
{ VSC_REG(2, 0, 0xf), 0xa0010291 },
{ VSC_REG(2, 1, 0x2f), 1 },
- { VSC_REG(2, 1, 0xf), 0xa0026301 }
+ { VSC_REG(2, 1, 0xf), 0xa026301 }
};
static struct addr_val_pair xg_avp[] = {
{ VSC_REG(1, 10, 0), 0x600b },
- { VSC_REG(1, 10, 2), 0x4000 },
+ { VSC_REG(1, 10, 1), 0x70600 }, //QUANTA = 96*1024*8/512
+ { VSC_REG(1, 10, 2), 0x2710 },
{ VSC_REG(1, 10, 5), 0x65 },
- { VSC_REG(1, 10, 7), 3 },
+ { VSC_REG(1, 10, 7), 0x23 },
+ { VSC_REG(1, 10, 0x23), 0x800007bf },
+ { VSC_REG(1, 10, 0x23), 0x000007bf },
{ VSC_REG(1, 10, 0x23), 0x800007bf },
{ VSC_REG(1, 10, 0x24), 4 }
};
@@ -130,10 +133,9 @@ int t3_vsc7323_init(adapter_t *adap, int nports)
for (i = 0; i < ARRAY_SIZE(sys_avp); i++)
if ((ret = t3_elmr_blk_write(adap, sys_avp[i].reg_addr,
- &sys_avp[i].val, 1)))
+ &sys_avp[i].val, 1)))
return ret;
-
ing_step = 0xc0 / nports;
egr_step = 0x40 / nports;
ing_bot = egr_bot = 0;
@@ -141,22 +143,27 @@ int t3_vsc7323_init(adapter_t *adap, int nports)
// egr_wm = egr_step * 64;
/* {ING,EGR}_CONTROL.CLR = 1 here */
- for (i = 0; i < nports; i++)
- if ((ret = elmr_write(adap, VSC_REG(2, 0, 0x10 + i),
+ for (i = 0; i < nports; i++) {
+ if (
+ (ret = elmr_write(adap, VSC_REG(2, 0, 0x10 + i),
((ing_bot + ing_step) << 16) | ing_bot)) ||
- (ret = elmr_write(adap, VSC_REG(2, 0, 0x50 + i), 0)) ||
+ (ret = elmr_write(adap, VSC_REG(2, 0, 0x40 + i),
+ 0x6000a00)) ||
+ (ret = elmr_write(adap, VSC_REG(2, 0, 0x50 + i), 1)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x10 + i),
((egr_bot + egr_step) << 16) | egr_bot)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x40 + i),
0x2000280)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x50 + i), 0)))
return ret;
-
+ ing_bot += ing_step;
+ egr_bot += egr_step;
+ }
for (i = 0; i < ARRAY_SIZE(fifo_avp); i++)
if ((ret = t3_elmr_blk_write(adap, fifo_avp[i].reg_addr,
- &fifo_avp[i].val, 1)))
- return ret;
+ &fifo_avp[i].val, 1)))
+ return ret;
for (i = 0; i < ARRAY_SIZE(xg_avp); i++)
if ((ret = t3_elmr_blk_write(adap, xg_avp[i].reg_addr,
@@ -198,7 +205,7 @@ int t3_vsc7323_set_speed_fc(adapter_t *adap, int speed, int fc, int port)
return r;
}
- r = (fc & PAUSE_RX) ? 0x6ffff : 0x2ffff;
+ r = (fc & PAUSE_RX) ? 0x60200 : 0x20200; //QUANTA = 32*1024*8/512
if (fc & PAUSE_TX)
r |= (1 << 19);
return elmr_write(adap, VSC_REG(1, port, 1), r);
@@ -212,12 +219,12 @@ int t3_vsc7323_set_mtu(adapter_t *adap, unsigned int mtu, int port)
int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port)
{
int ret;
-
+
ret = elmr_write(adap, VSC_REG(1, port, 3),
- (addr[0] << 16) | (addr[1] << 8) | addr[2]);
+ (addr[0] << 16) | (addr[1] << 8) | addr[2]);
if (!ret)
ret = elmr_write(adap, VSC_REG(1, port, 4),
- (addr[3] << 16) | (addr[4] << 8) | addr[5]);
+ (addr[3] << 16) | (addr[4] << 8) | addr[5]);
return ret;
}
diff --git a/sys/dev/cxgb/common/cxgb_xgmac.c b/sys/dev/cxgb/common/cxgb_xgmac.c
index 34b05cd..f11b343 100644
--- a/sys/dev/cxgb/common/cxgb_xgmac.c
+++ b/sys/dev/cxgb/common/cxgb_xgmac.c
@@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
#include <dev/cxgb/cxgb_include.h>
#endif
+#undef msleep
+#define msleep t3_os_sleep
+
/*
* # of exact address filters. The first one is used for the station address,
* the rest are available for multicast addresses.
@@ -154,7 +157,7 @@ int t3_mac_reset(struct cmac *mac)
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
(void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
if ((val & F_PCS_RESET_) && adap->params.rev) {
- t3_os_sleep(1);
+ msleep(1);
t3b_pcs_reset(mac);
}
@@ -179,7 +182,7 @@ static int t3b2_mac_reset(struct cmac *mac)
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
(void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
- t3_os_sleep(10);
+ msleep(10);
/* Check for xgm Rx fifo empty */
if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft,
@@ -202,7 +205,7 @@ static int t3b2_mac_reset(struct cmac *mac)
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
(void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
if ((val & F_PCS_RESET_) && adap->params.rev) {
- t3_os_sleep(1);
+ msleep(1);
t3b_pcs_reset(mac);
}
t3_write_reg(adap, A_XGM_RX_CFG + oft,
@@ -243,7 +246,6 @@ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6])
set_addr_filter(mac, idx, addr);
if (mac->multiport && idx < mac->adapter->params.nports)
t3_vsc7323_set_addr(mac->adapter, addr, idx);
-
return 0;
}
@@ -425,8 +427,17 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
if (duplex >= 0 && duplex != DUPLEX_FULL)
return -EINVAL;
- if (mac->multiport)
+ if (mac->multiport) {
+ val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
+ val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
+ val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(t3_read_reg(adap,
+ A_XGM_RX_MAX_PKT_SIZE + oft)) / 8);
+ t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
+
+ t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
+ F_TXPAUSEEN);
return t3_vsc7323_set_speed_fc(adap, speed, fc, mac->ext_port);
+ }
if (speed >= 0) {
if (speed == SPEED_10)
val = V_PORTSPEED(0);
@@ -451,7 +462,7 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
- (fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
+ (fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
return 0;
}
@@ -466,12 +477,13 @@ int t3_mac_enable(struct cmac *mac, int which)
return t3_vsc7323_enable(adap, mac->ext_port, which);
if (which & MAC_DIRECTION_TX) {
- t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+ t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
+
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
mac->tx_mcnt = s->tx_frames;
mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
@@ -493,7 +505,6 @@ int t3_mac_enable(struct cmac *mac, int which)
int t3_mac_disable(struct cmac *mac, int which)
{
- int idx = macidx(mac);
adapter_t *adap = mac->adapter;
int val;
@@ -501,17 +512,14 @@ int t3_mac_disable(struct cmac *mac, int which)
return t3_vsc7323_disable(adap, mac->ext_port, which);
if (which & MAC_DIRECTION_TX) {
+ val = t3_read_reg(adap, A_MPS_CFG);
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
- t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
- t3_write_reg(adap, A_TP_PIO_DATA, 0xc000001f);
- t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
- t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
mac->txen = 0;
}
if (which & MAC_DIRECTION_RX) {
t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
F_PCS_RESET_, 0);
- t3_os_sleep(100);
+ msleep(100);
t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
val = F_MAC_RESET_;
if (is_10G(adap))
@@ -535,6 +543,13 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
unsigned int rx_mcnt = (unsigned int)s->rx_frames;
unsigned int rx_xcnt;
+ if (mac->multiport) {
+ tx_mcnt = t3_read_reg(adap, A_XGM_STAT_TX_FRAME_LOW);
+ rx_mcnt = t3_read_reg(adap, A_XGM_STAT_RX_FRAMES_LOW);
+ } else {
+ tx_mcnt = (unsigned int)s->tx_frames;
+ rx_mcnt = (unsigned int)s->rx_frames;
+ }
status = 0;
tx_xcnt = 1; /* By default tx_xcnt is making progress*/
tx_tcnt = mac->tx_tcnt; /* If tx_mcnt is progressing ignore tx_tcnt*/
@@ -573,15 +588,18 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
}
rxcheck:
- if (rx_mcnt != mac->rx_mcnt)
+ if (rx_mcnt != mac->rx_mcnt) {
rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
A_XGM_RX_SPI4_SOP_EOP_CNT +
- mac->offset)));
- else
+ mac->offset))) +
+ (s->rx_fifo_ovfl - mac->rx_ocnt);
+ mac->rx_ocnt = s->rx_fifo_ovfl;
+ } else
goto out;
if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0) {
- status = 2;
+ if (!mac->multiport)
+ status = 2;
goto out;
}
@@ -622,6 +640,9 @@ const struct mac_stats *t3_mac_update_stats(struct cmac *mac)
u32 v, lo;
+ if (mac->multiport)
+ return t3_vsc7323_update_stats(mac);
+
RMON_UPDATE64(mac, rx_octets, RX_BYTES_LOW, RX_BYTES_HIGH);
RMON_UPDATE64(mac, rx_frames, RX_FRAMES_LOW, RX_FRAMES_HIGH);
RMON_UPDATE(mac, rx_mcast_frames, RX_MCAST_FRAMES);
diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h
index 751dad5..d1e3df6 100644
--- a/sys/dev/cxgb/cxgb_adapter.h
+++ b/sys/dev/cxgb/cxgb_adapter.h
@@ -138,6 +138,7 @@ enum { /* adapter flags */
USING_MSIX = (1 << 2),
QUEUES_BOUND = (1 << 3),
FW_UPTODATE = (1 << 4),
+ TPS_UPTODATE = (1 << 5),
};
@@ -239,7 +240,7 @@ struct sge_fl {
struct tx_desc;
struct tx_sw_desc;
-#define TXQ_TRANSMITTING 0x1
+#define TXQ_TRANSMITTING 0x1
struct sge_txq {
uint64_t flags;
@@ -301,6 +302,8 @@ struct sge {
struct mtx reg_lock;
};
+struct filter_info;
+
struct adapter {
device_t dev;
int flags;
@@ -331,7 +334,11 @@ struct adapter {
struct resource *msix_irq_res[SGE_QSETS];
int msix_irq_rid[SGE_QSETS];
void *msix_intr_tag[SGE_QSETS];
+ uint8_t rxpkt_map[8]; /* maps RX_PKT interface values to port ids */
+ uint8_t rrss_map[SGE_QSETS]; /* revers RSS map table */
+ struct filter_info *filters;
+
/* Tasks */
struct task ext_intr_task;
struct task slow_intr_task;
diff --git a/sys/dev/cxgb/cxgb_ioctl.h b/sys/dev/cxgb/cxgb_ioctl.h
index d725a9a..21d3cce 100644
--- a/sys/dev/cxgb/cxgb_ioctl.h
+++ b/sys/dev/cxgb/cxgb_ioctl.h
@@ -66,6 +66,7 @@ enum {
CH_SETMIIREGS,
CH_SET_FILTER,
CH_SET_HW_SCHED,
+ CH_DEL_FILTER,
};
struct ch_reg {
@@ -130,6 +131,30 @@ struct ch_hw_sched {
int32_t flow_ipg; /* usec */
};
+struct ch_filter_tuple {
+ uint32_t sip;
+ uint32_t dip;
+ uint16_t sport;
+ uint16_t dport;
+ uint16_t vlan:12;
+ uint16_t vlan_prio:3;
+};
+
+struct ch_filter {
+ uint32_t cmd;
+ uint32_t filter_id;
+ struct ch_filter_tuple val;
+ struct ch_filter_tuple mask;
+ uint16_t mac_addr_idx;
+ uint8_t mac_hit:1;
+ uint8_t proto:2;
+
+ uint8_t want_filter_id:1; /* report filter TID instead of RSS hash */
+ uint8_t pass:1; /* whether to pass or drop packets */
+ uint8_t rss:1; /* use RSS or specified qset */
+ uint8_t qset;
+};
+
#ifndef TCB_SIZE
# define TCB_SIZE 128
#endif
@@ -232,5 +257,7 @@ struct mii_data {
#define SIOCGMIIREG _IOWR('f', CH_GETMIIREGS, struct mii_data)
#define SIOCSMIIREG _IOWR('f', CH_SETMIIREGS, struct mii_data)
#define CHELSIO_SET_HW_SCHED _IOWR('f', CH_SET_HW_SCHED, struct ch_hw_sched)
+#define CHELSIO_SET_FILTER _IOW('f', CH_SET_FILTER, struct ch_filter)
+#define CHELSIO_DEL_FILTER _IOW('f', CH_DEL_FILTER, struct ch_filter)
#define CHELSIO_DEVUP _IO('f', CH_DEVUP)
#endif
diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index 3cc930f..56d54e2 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -225,6 +225,28 @@ enum {
MIN_FL_ENTRIES = 32
};
+struct filter_info {
+ u32 sip;
+ u32 sip_mask;
+ u32 dip;
+ u16 sport;
+ u16 dport;
+ u32 vlan:12;
+ u32 vlan_prio:3;
+ u32 mac_hit:1;
+ u32 mac_idx:4;
+ u32 mac_vld:1;
+ u32 pkt_type:2;
+ u32 report_filter_id:1;
+ u32 pass:1;
+ u32 rss:1;
+ u32 qset:3;
+ u32 locked:1;
+ u32 valid:1;
+};
+
+enum { FILTER_NO_VLAN_PRI = 7 };
+
#define PORT_MASK ((1 << MAX_NPORTS) - 1)
/* Table for probing the cards. The desc field isn't actually used */
@@ -248,6 +270,29 @@ struct cxgb_ident {
{0, 0, 0, NULL}
};
+
+static int set_eeprom(struct port_info *pi, const uint8_t *data, int len, int offset);
+
+static inline char
+t3rev2char(struct adapter *adapter)
+{
+ char rev = 'z';
+
+ switch(adapter->params.rev) {
+ case T3_REV_A:
+ rev = 'a';
+ break;
+ case T3_REV_B:
+ case T3_REV_B2:
+ rev = 'b';
+ break;
+ case T3_REV_C:
+ rev = 'c';
+ break;
+ }
+ return rev;
+}
+
static struct cxgb_ident *
cxgb_get_ident(device_t dev)
{
@@ -299,6 +344,10 @@ cxgb_controller_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
+#define FW_FNAME "t3fw%d%d%d"
+#define TPEEPROM_NAME "t3%ctpe%d%d%d"
+#define TPSRAM_NAME "t3%cps%d%d%d"
+
static int
upgrade_fw(adapter_t *sc)
{
@@ -310,7 +359,7 @@ upgrade_fw(adapter_t *sc)
#endif
int status;
- snprintf(&buf[0], sizeof(buf), "t3fw%d%d%d", FW_VERSION_MAJOR,
+ snprintf(&buf[0], sizeof(buf), FW_FNAME, FW_VERSION_MAJOR,
FW_VERSION_MINOR, FW_VERSION_MICRO);
fw = firmware_get(buf);
@@ -318,9 +367,12 @@ upgrade_fw(adapter_t *sc)
if (fw == NULL) {
device_printf(sc->dev, "Could not find firmware image %s\n", buf);
return (ENOENT);
- }
+ } else
+ device_printf(sc->dev, "updating firmware on card with %s\n", buf);
status = t3_load_fw(sc, (const uint8_t *)fw->data, fw->datasize);
+ device_printf(sc->dev, "firmware update returned %s %d\n", (status == 0) ? "success" : "fail", status);
+
firmware_put(fw, FIRMWARE_UNLOAD);
return (status);
@@ -350,7 +402,10 @@ cxgb_controller_attach(device_t dev)
pectl = (pectl & ~0x7000) | (5 << 12);
pci_write_config(dev, reg + 0x8, pectl, 2);
}
- if (sc->link_width != 0 && sc->link_width <= 4) {
+
+ ai = cxgb_get_adapter_info(dev);
+ if (sc->link_width != 0 && sc->link_width <= 4 &&
+ (ai->nports0 + ai->nports1) <= 2) {
device_printf(sc->dev,
"PCIe x%d Link, expect reduced performance\n",
sc->link_width);
@@ -387,7 +442,6 @@ cxgb_controller_attach(device_t dev)
sc->bh = rman_get_bushandle(sc->regs_res);
sc->mmio_len = rman_get_size(sc->regs_res);
- ai = cxgb_get_adapter_info(dev);
if (t3_prep_adapter(sc, ai, 1) < 0) {
printf("prep adapter failed\n");
error = ENODEV;
@@ -475,6 +529,17 @@ cxgb_controller_attach(device_t dev)
} else {
sc->flags |= FW_UPTODATE;
}
+
+ if (t3_check_tpsram_version(sc) != 0) {
+ /*
+ * Warn user that a firmware update will be attempted in init.
+ */
+ device_printf(dev, "SRAM needs to be updated to version %c-%d.%d.%d\n",
+ t3rev2char(sc), TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+ sc->flags &= ~TPS_UPTODATE;
+ } else {
+ sc->flags |= TPS_UPTODATE;
+ }
if ((sc->flags & USING_MSIX) && !singleq)
port_qsets = min((SGE_QSETS/(sc)->params.nports), mp_ncpus);
@@ -489,11 +554,11 @@ cxgb_controller_attach(device_t dev)
error = EINVAL;
goto out;
}
- sc->portdev[i] = child;
sc->port[i].adapter = sc;
sc->port[i].nqsets = port_qsets;
sc->port[i].first_qset = i*port_qsets;
sc->port[i].port = i;
+ sc->portdev[i] = child;
device_set_softc(child, &sc->port[i]);
}
if ((error = bus_generic_attach(dev)) != 0)
@@ -590,6 +655,7 @@ cxgb_free(struct adapter *sc)
}
#endif
t3_free_sge_resources(sc);
+ free(sc->filters, M_DEVBUF);
t3_sge_free(sc);
cxgb_offload_exit();
@@ -606,6 +672,113 @@ cxgb_free(struct adapter *sc)
return;
}
+
+
+static int
+alloc_filters(struct adapter *adap)
+{
+ struct filter_info *p;
+ int nfilters;
+
+ if ((nfilters = adap->params.mc5.nfilters) == 0)
+ return (0);
+
+ adap->filters = malloc(nfilters*sizeof(struct filter_info),
+ M_DEVBUF, M_ZERO|M_WAITOK);
+
+ if (adap->filters == NULL)
+ return (ENOMEM);
+
+ /* Set the default filters, only need to set non-0 fields here. */
+ p = &adap->filters[nfilters - 1];
+ p->vlan = 0xfff;
+ p->vlan_prio = FILTER_NO_VLAN_PRI;
+ p->pass = p->rss = p->valid = p->locked = 1;
+
+ return (0);
+}
+
+static inline void
+set_tcb_field_ulp(struct cpl_set_tcb_field *req,
+ unsigned int tid, unsigned int word,
+ uint64_t mask, uint64_t val)
+{
+ struct ulp_txpkt *txpkt = (struct ulp_txpkt *)req;
+
+ txpkt->cmd_dest = htonl(V_ULPTX_CMD(ULP_TXPKT));
+ txpkt->len = htonl(V_ULPTX_NFLITS(sizeof(*req) / 8));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
+ req->reply = V_NO_REPLY(1);
+ req->cpu_idx = 0;
+ req->word = htons(word);
+ req->mask = htobe64(mask);
+ req->val = htobe64(val);
+}
+
+static int
+set_filter(struct adapter *adap, int id, const struct filter_info *f)
+{
+ int len;
+ struct mbuf *m;
+ struct ulp_txpkt *txpkt;
+ struct work_request_hdr *wr;
+ struct cpl_pass_open_req *oreq;
+ struct cpl_set_tcb_field *sreq;
+
+ len = sizeof(*wr) + sizeof(*oreq) + 2 * sizeof(*sreq);
+ id += t3_mc5_size(&adap->mc5) - adap->params.mc5.nroutes -
+ adap->params.mc5.nfilters;
+
+ m = m_gethdr(M_TRYWAIT, MT_DATA);
+ wr = mtod(m, struct work_request_hdr *);
+ wr->wr_hi = htonl(V_WR_OP(FW_WROPCODE_BYPASS) | F_WR_ATOMIC);
+ m->m_len = m->m_pkthdr.len = len;
+
+ oreq = (struct cpl_pass_open_req *)(wr + 1);
+ txpkt = (struct ulp_txpkt *)oreq;
+ txpkt->cmd_dest = htonl(V_ULPTX_CMD(ULP_TXPKT));
+ txpkt->len = htonl(V_ULPTX_NFLITS(sizeof(*oreq) / 8));
+ OPCODE_TID(oreq) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, id));
+ oreq->local_port = htons(f->dport);
+ oreq->peer_port = htons(f->sport);
+ oreq->local_ip = htonl(f->dip);
+ oreq->peer_ip = htonl(f->sip);
+ oreq->peer_netmask = htonl(f->sip_mask);
+ oreq->opt0h = 0;
+ oreq->opt0l = htonl(F_NO_OFFLOAD);
+ oreq->opt1 = htonl(V_MAC_MATCH_VALID(f->mac_vld) |
+ V_CONN_POLICY(CPL_CONN_POLICY_FILTER) |
+ V_VLAN_PRI(f->vlan_prio >> 1) |
+ V_VLAN_PRI_VALID(f->vlan_prio != FILTER_NO_VLAN_PRI) |
+ V_PKT_TYPE(f->pkt_type) | V_OPT1_VLAN(f->vlan) |
+ V_MAC_MATCH(f->mac_idx | (f->mac_hit << 4)));
+
+ sreq = (struct cpl_set_tcb_field *)(oreq + 1);
+ set_tcb_field_ulp(sreq, id, 1, 0x1800808000ULL,
+ (f->report_filter_id << 15) | (1 << 23) |
+ ((u64)f->pass << 35) | ((u64)!f->rss << 36));
+ set_tcb_field_ulp(sreq + 1, id, 25, 0x3f80000,
+ (u64)adap->rrss_map[f->qset] << 19);
+ t3_mgmt_tx(adap, m);
+ return 0;
+}
+
+static int
+setup_hw_filters(struct adapter *adap)
+{
+ int i, err;
+
+ if (adap->filters == NULL)
+ return 0;
+
+ t3_enable_filters(adap);
+
+ for (i = err = 0; i < adap->params.mc5.nfilters && !err; i++)
+ if (adap->filters[i].locked)
+ err = set_filter(adap, i, &adap->filters[i]);
+ return err;
+}
+
/**
* setup_sge_qsets - configure SGE Tx/Rx/response queues
* @sc: the controller softc
@@ -807,11 +980,21 @@ cxgb_port_attach(device_t dev)
ifp->if_capabilities |= CXGB_CAP;
ifp->if_capenable |= CXGB_CAP_ENABLE;
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO);
-
+ /*
+ * disable TSO on 4-port - it isn't supported by the firmware yet
+ */
+ if (p->adapter->params.nports > 2) {
+ ifp->if_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6);
+ ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TSO6);
+ ifp->if_hwassist &= ~CSUM_TSO;
+ }
+
ether_ifattach(ifp, p->hw_addr);
-#ifdef DEFAULT_JUMBO
- ifp->if_mtu = 9000;
-#endif
+ /*
+ * Only default to jumbo frames on 10GigE
+ */
+ if (p->adapter->params.nports <= 2)
+ ifp->if_mtu = 9000;
if ((err = cxgb_makedev(p)) != 0) {
printf("makedev failed %d\n", err);
return (err);
@@ -1089,23 +1272,30 @@ static void
setup_rss(adapter_t *adap)
{
int i;
- u_int nq0 = adap->port[0].nqsets;
- u_int nq1 = max((u_int)adap->port[1].nqsets, 1U);
+ u_int nq[2];
uint8_t cpus[SGE_QSETS + 1];
uint16_t rspq_map[RSS_TABLE_SIZE];
-
+
+ nq[0] = adap->port[0].nqsets;
+ nq[1] = max((u_int)adap->port[1].nqsets, 1U);
+
for (i = 0; i < SGE_QSETS; ++i)
cpus[i] = i;
cpus[SGE_QSETS] = 0xff;
for (i = 0; i < RSS_TABLE_SIZE / 2; ++i) {
- rspq_map[i] = i % nq0;
- rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0;
+ rspq_map[i] = nq[0] ? i % nq[0] : 0;
+ rspq_map[i + RSS_TABLE_SIZE / 2] = nq[1] ? i % nq[1] + nq[0] : 0;
}
+ /* Calculate the reverse RSS map table */
+ for (i = 0; i < RSS_TABLE_SIZE; ++i)
+ if (adap->rrss_map[rspq_map[i]] == 0xff)
+ adap->rrss_map[rspq_map[i]] = i;
t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN |
- F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN |
- V_RRCPLCPUSIZE(6), cpus, rspq_map);
+ F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | F_OFDMAPEN |
+ F_RRCPLMAPEN | V_RRCPLCPUSIZE(6), cpus, rspq_map);
+
}
/*
@@ -1175,7 +1365,7 @@ send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
struct mbuf *m;
struct mngt_pktsched_wr *req;
- m = m_gethdr(M_NOWAIT, MT_DATA);
+ m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m) {
req = mtod(m, struct mngt_pktsched_wr *);
req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
@@ -1204,6 +1394,101 @@ bind_qsets(adapter_t *sc)
}
}
+static void
+update_tpeeprom(struct adapter *adap)
+{
+ const struct firmware *tpeeprom;
+ char buf[64];
+ uint32_t version;
+ unsigned int major, minor;
+ int ret, len;
+ char rev;
+
+ t3_seeprom_read(adap, TP_SRAM_OFFSET, &version);
+
+ major = G_TP_VERSION_MAJOR(version);
+ minor = G_TP_VERSION_MINOR(version);
+ if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
+ return;
+
+ rev = t3rev2char(adap);
+
+ snprintf(buf, sizeof(buf), TPEEPROM_NAME, rev,
+ TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+
+ tpeeprom = firmware_get(buf);
+ if (tpeeprom == NULL) {
+ device_printf(adap->dev, "could not load TP EEPROM: unable to load %s\n",
+ buf);
+ return;
+ }
+
+ len = tpeeprom->datasize - 4;
+
+ ret = t3_check_tpsram(adap, tpeeprom->data, tpeeprom->datasize);
+ if (ret)
+ goto release_tpeeprom;
+
+ if (len != TP_SRAM_LEN) {
+ device_printf(adap->dev, "%s length is wrong len=%d expected=%d\n", buf, len, TP_SRAM_LEN);
+ return;
+ }
+
+ ret = set_eeprom(&adap->port[0], tpeeprom->data, tpeeprom->datasize,
+ TP_SRAM_OFFSET);
+
+ if (!ret) {
+ device_printf(adap->dev,
+ "Protocol SRAM image updated in EEPROM to %d.%d.%d\n",
+ TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+ } else
+ device_printf(adap->dev, "Protocol SRAM image update in EEPROM failed\n");
+
+release_tpeeprom:
+ firmware_put(tpeeprom, FIRMWARE_UNLOAD);
+
+ return;
+}
+
+static int
+update_tpsram(struct adapter *adap)
+{
+ const struct firmware *tpsram;
+ char buf[64];
+ int ret;
+ char rev;
+
+ rev = t3rev2char(adap);
+ if (!rev)
+ return 0;
+
+ update_tpeeprom(adap);
+
+ snprintf(buf, sizeof(buf), TPSRAM_NAME, rev,
+ TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+
+ tpsram = firmware_get(buf);
+ if (tpsram == NULL){
+ device_printf(adap->dev, "could not load TP SRAM: unable to load %s\n",
+ buf);
+ return (EINVAL);
+ } else
+ device_printf(adap->dev, "updating TP SRAM with %s\n", buf);
+
+ ret = t3_check_tpsram(adap, tpsram->data, tpsram->datasize);
+ if (ret)
+ goto release_tpsram;
+
+ ret = t3_set_proto_sram(adap, tpsram->data);
+ if (ret)
+ device_printf(adap->dev, "loading protocol SRAM failed\n");
+
+release_tpsram:
+ firmware_put(tpsram, FIRMWARE_UNLOAD);
+
+ return ret;
+}
+
/**
* cxgb_up - enable the adapter
* @adap: adapter being enabled
@@ -1221,11 +1506,11 @@ cxgb_up(struct adapter *sc)
if ((sc->flags & FULL_INIT_DONE) == 0) {
if ((sc->flags & FW_UPTODATE) == 0)
- err = upgrade_fw(sc);
-
- if (err)
- goto out;
-
+ if ((err = upgrade_fw(sc)))
+ goto out;
+ if ((sc->flags & TPS_UPTODATE) == 0)
+ if ((err = update_tpsram(sc)))
+ goto out;
err = t3_init_hw(sc, 0);
if (err)
goto out;
@@ -1236,6 +1521,7 @@ cxgb_up(struct adapter *sc)
if (err)
goto out;
+ alloc_filters(sc);
setup_rss(sc);
sc->flags |= FULL_INIT_DONE;
}
@@ -1268,9 +1554,11 @@ cxgb_up(struct adapter *sc)
t3_sge_start(sc);
t3_intr_enable(sc);
- if ((sc->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
+ if ((sc->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX) {
bind_qsets(sc);
- sc->flags |= QUEUES_BOUND;
+ setup_hw_filters(sc);
+ sc->flags |= QUEUES_BOUND;
+ }
out:
return (err);
irq_err:
@@ -1334,7 +1622,7 @@ offload_open(struct port_info *pi)
if (!adap_up)
err = cxgb_up(adapter);
ADAPTER_UNLOCK(pi->adapter);
- if (err < 0)
+ if (err)
return (err);
t3_tp_set_offload_mode(adapter, 1);
@@ -1407,7 +1695,7 @@ cxgb_init_locked(struct port_info *p)
ifp = p->ifp;
ADAPTER_LOCK(p->adapter);
- if ((sc->open_device_map == 0) && ((err = cxgb_up(sc)) < 0)) {
+ if ((sc->open_device_map == 0) && (err = cxgb_up(sc))) {
ADAPTER_UNLOCK(p->adapter);
cxgb_stop_locked(p);
return;
@@ -1866,10 +2154,170 @@ cxgb_tick_handler(void *arg, int count)
*/
ADAPTER_UNLOCK(sc);
- if (p->rev == T3_REV_B2)
+ if (p->rev == T3_REV_B2 && p->nports < 4)
check_t3b2_mac(sc);
}
+#if 0
+static void *
+filter_get_idx(struct seq_file *seq, loff_t pos)
+{
+ int i;
+ struct adapter *adap = seq->private;
+ struct filter_info *p = adap->filters;
+
+ if (!p)
+ return NULL;
+
+ for (i = 0; i < adap->params.mc5.nfilters; i++, p++)
+ if (p->valid) {
+ if (!pos)
+ return p;
+ pos--;
+ }
+ return NULL;
+}
+
+static void *filter_get_nxt_idx(struct seq_file *seq, struct filter_info *p)
+{
+ struct adapter *adap = seq->private;
+ struct filter_info *end = &adap->filters[adap->params.mc5.nfilters];
+
+ while (++p < end && !p->valid)
+ ;
+ return p < end ? p : NULL;
+}
+
+static void *filter_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return *pos ? filter_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *filter_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ v = *pos ? filter_get_nxt_idx(seq, v) : filter_get_idx(seq, 0);
+ if (v)
+ ++*pos;
+ return v;
+}
+
+static void filter_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static int filter_seq_show(struct seq_file *seq, void *v)
+{
+ static const char *pkt_type[] = { "any", "tcp", "udp", "frag" };
+
+ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "index SIP DIP sport "
+ "dport VLAN PRI MAC type Q\n");
+ else {
+ char sip[20], dip[20];
+ struct filter_info *f = v;
+ struct adapter *adap = seq->private;
+
+ sprintf(sip, NIPQUAD_FMT "/%-2u", HIPQUAD(f->sip),
+ f->sip_mask ? 33 - ffs(f->sip_mask) : 0);
+ sprintf(dip, NIPQUAD_FMT, HIPQUAD(f->dip));
+ seq_printf(seq, "%5zu %18s %15s ", f - adap->filters, sip, dip);
+ seq_printf(seq, f->sport ? "%5u " : " * ", f->sport);
+ seq_printf(seq, f->dport ? "%5u " : " * ", f->dport);
+ seq_printf(seq, f->vlan != 0xfff ? "%4u " : " * ", f->vlan);
+ seq_printf(seq, f->vlan_prio == FILTER_NO_VLAN_PRI ?
+ " * " : "%1u/%1u ", f->vlan_prio, f->vlan_prio | 1);
+ if (!f->mac_vld)
+ seq_printf(seq, " * ");
+ else if (f->mac_hit)
+ seq_printf(seq, "%3u ", f->mac_idx);
+ else
+ seq_printf(seq, " -1 ");
+ seq_printf(seq, "%4s ", pkt_type[f->pkt_type]);
+ if (!f->pass)
+ seq_printf(seq, "-\n");
+ else if (f->rss)
+ seq_printf(seq, "*\n");
+ else
+ seq_printf(seq, "%1u\n", f->qset);
+ }
+ return 0;
+}
+
+static struct seq_operations filter_seq_ops = {
+ .start = filter_seq_start,
+ .next = filter_seq_next,
+ .stop = filter_seq_stop,
+ .show = filter_seq_show
+};
+
+static int filter_seq_open(struct inode *inode, struct file *file)
+{
+ int rc = seq_open(file, &filter_seq_ops);
+
+ if (!rc) {
+ struct proc_dir_entry *dp = PDE(inode);
+ struct seq_file *seq = file->private_data;
+
+ seq->private = dp->data;
+ }
+ return rc;
+}
+
+static struct file_operations filter_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = filter_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+#endif
+
+static int
+set_eeprom(struct port_info *pi, const uint8_t *data, int len, int offset)
+{
+ uint8_t *buf;
+ int err = 0;
+ u32 aligned_offset, aligned_len, *p;
+ struct adapter *adapter = pi->adapter;
+
+
+ aligned_offset = offset & ~3;
+ aligned_len = (len + (offset & 3) + 3) & ~3;
+
+ if (aligned_offset != offset || aligned_len != len) {
+ buf = malloc(aligned_len, M_DEVBUF, M_WAITOK|M_ZERO);
+ if (!buf)
+ return (ENOMEM);
+ err = t3_seeprom_read(adapter, aligned_offset, (u32 *)buf);
+ if (!err && aligned_len > 4)
+ err = t3_seeprom_read(adapter,
+ aligned_offset + aligned_len - 4,
+ (u32 *)&buf[aligned_len - 4]);
+ if (err)
+ goto out;
+ memcpy(buf + (offset & 3), data, len);
+ } else
+ buf = (uint8_t *)(uintptr_t)data;
+
+ err = t3_seeprom_wp(adapter, 0);
+ if (err)
+ goto out;
+
+ for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) {
+ err = t3_seeprom_write(adapter, aligned_offset, *p);
+ aligned_offset += 4;
+ }
+
+ if (!err)
+ err = t3_seeprom_wp(adapter, 1);
+out:
+ if (buf != data)
+ free(buf, M_DEVBUF);
+ return err;
+}
+
+
static int
in_range(int val, int lo, int hi)
{
@@ -1923,7 +2371,7 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
if (!mmd)
mmd = MDIO_DEV_PCS;
else if (mmd > MDIO_DEV_XGXS)
- return -EINVAL;
+ return (EINVAL);
error = phy->mdio_read(sc, mid->phy_id & 0x1f, mmd,
mid->reg_num, &val);
@@ -2013,7 +2461,7 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
struct ch_qset_params *t = (struct ch_qset_params *)data;
if (t->qset_idx >= SGE_QSETS)
- return -EINVAL;
+ return (EINVAL);
if (!in_range(t->intr_lat, 0, M_NEWTIMER) ||
!in_range(t->cong_thres, 0, 255) ||
!in_range(t->txq_size[0], MIN_TXQ_ENTRIES,
@@ -2026,13 +2474,13 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
!in_range(t->fl_size[1], MIN_FL_ENTRIES,
MAX_RX_JUMBO_BUFFERS) ||
!in_range(t->rspq_size, MIN_RSPQ_ENTRIES, MAX_RSPQ_ENTRIES))
- return -EINVAL;
+ return (EINVAL);
if ((sc->flags & FULL_INIT_DONE) &&
(t->rspq_size >= 0 || t->fl_size[0] >= 0 ||
t->fl_size[1] >= 0 || t->txq_size[0] >= 0 ||
t->txq_size[1] >= 0 || t->txq_size[2] >= 0 ||
t->polling >= 0 || t->cong_thres >= 0))
- return -EBUSY;
+ return (EBUSY);
q = &sc->params.sge.qset[t->qset_idx];
@@ -2141,6 +2589,79 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
memcpy(m->mtus, sc->params.mtus, sizeof(m->mtus));
m->nmtus = NMTUS;
break;
+ }
+ case CHELSIO_SET_FILTER: {
+ struct ch_filter *f = (struct ch_filter *)data;
+ struct filter_info *p;
+ int ret;
+
+ if (sc->params.mc5.nfilters == 0)
+ return (EOPNOTSUPP);
+ if (!(sc->flags & FULL_INIT_DONE))
+ return (EAGAIN); /* can still change nfilters */
+ if (sc->filters == NULL)
+ return (ENOMEM);
+
+ if (f->filter_id >= sc->params.mc5.nfilters ||
+ (f->val.dip && f->mask.dip != 0xffffffff) ||
+ (f->val.sport && f->mask.sport != 0xffff) ||
+ (f->val.dport && f->mask.dport != 0xffff) ||
+ (f->mask.vlan && f->mask.vlan != 0xfff) ||
+ (f->mask.vlan_prio && f->mask.vlan_prio != 7) ||
+ (f->mac_addr_idx != 0xffff && f->mac_addr_idx > 15) ||
+ f->qset >= SGE_QSETS ||
+ sc->rrss_map[f->qset] >= RSS_TABLE_SIZE)
+ return (EINVAL);
+
+ p = &sc->filters[f->filter_id];
+ if (p->locked)
+ return (EPERM);
+
+ p->sip = f->val.sip;
+ p->sip_mask = f->mask.sip;
+ p->dip = f->val.dip;
+ p->sport = f->val.sport;
+ p->dport = f->val.dport;
+ p->vlan = f->mask.vlan ? f->val.vlan : 0xfff;
+ p->vlan_prio = f->mask.vlan_prio ? (f->val.vlan_prio & 6) :
+ FILTER_NO_VLAN_PRI;
+ p->mac_hit = f->mac_hit;
+ p->mac_vld = f->mac_addr_idx != 0xffff;
+ p->mac_idx = f->mac_addr_idx;
+ p->pkt_type = f->proto;
+ p->report_filter_id = f->want_filter_id;
+ p->pass = f->pass;
+ p->rss = f->rss;
+ p->qset = f->qset;
+
+ ret = set_filter(sc, f->filter_id, p);
+ if (ret)
+ return ret;
+ p->valid = 1;
+ break;
+ }
+ case CHELSIO_DEL_FILTER: {
+ struct ch_filter *f = (struct ch_filter *)data;
+ struct filter_info *p;
+
+ if (sc->params.mc5.nfilters == 0)
+ return (EOPNOTSUPP);
+ if (!(sc->flags & FULL_INIT_DONE))
+ return (EAGAIN); /* can still change nfilters */
+ if (sc->filters == NULL)
+ return (ENOMEM);
+ if (f->filter_id >= sc->params.mc5.nfilters)
+ return (EINVAL);
+
+ p = &sc->filters[f->filter_id];
+ if (p->locked)
+ return (EPERM);
+ memset(p, 0, sizeof(*p));
+ p->sip_mask = 0xffffffff;
+ p->vlan = 0xfff;
+ p->vlan_prio = FILTER_NO_VLAN_PRI;
+ p->pkt_type = 1;
+ return set_filter(sc, f->filter_id, p);
}
case CHELSIO_DEVUP:
if (!is_offload(sc))
@@ -2199,6 +2720,8 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
if (!is_offload(sc))
return (EOPNOTSUPP);
+ if (!(sc->flags & FULL_INIT_DONE))
+ return (EIO); /* need MC5 */
return -t3_read_mc5_range(&sc->mc5, t->addr, 1, t->buf);
break;
}
diff --git a/sys/dev/cxgb/cxgb_offload.c b/sys/dev/cxgb/cxgb_offload.c
index 7a91a09..efab4e3 100644
--- a/sys/dev/cxgb/cxgb_offload.c
+++ b/sys/dev/cxgb/cxgb_offload.c
@@ -272,7 +272,7 @@ cxgb_ulp_iscsi_ctl(adapter_t *adapter, unsigned int req, void *data)
t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask);
break;
default:
- ret = -EOPNOTSUPP;
+ ret = (EOPNOTSUPP);
}
return ret;
}
@@ -315,7 +315,7 @@ cxgb_rdma_ctl(adapter_t *adapter, unsigned int req, void *data)
struct mc7 *mem;
if ((t->addr & 7) || (t->len & 7))
- return -EINVAL;
+ return (EINVAL);
if (t->mem_id == MEM_CM)
mem = &adapter->cm;
else if (t->mem_id == MEM_PMRX)
@@ -323,11 +323,11 @@ cxgb_rdma_ctl(adapter_t *adapter, unsigned int req, void *data)
else if (t->mem_id == MEM_PMTX)
mem = &adapter->pmtx;
else
- return -EINVAL;
+ return (EINVAL);
ret = t3_mc7_bd_read(mem, t->addr/8, t->len/8, (u64 *)t->buf);
if (ret)
- return ret;
+ return (ret);
break;
}
case RDMA_CQ_SETUP: {
@@ -358,9 +358,9 @@ cxgb_rdma_ctl(adapter_t *adapter, unsigned int req, void *data)
break;
}
default:
- ret = -EOPNOTSUPP;
+ ret = EOPNOTSUPP;
}
- return ret;
+ return (ret);
}
static int
@@ -439,7 +439,7 @@ cxgb_offload_ctl(struct toedev *tdev, unsigned int req, void *data)
case ULP_ISCSI_GET_PARAMS:
case ULP_ISCSI_SET_PARAMS:
if (!offload_running(adapter))
- return -EAGAIN;
+ return (EAGAIN);
return cxgb_ulp_iscsi_ctl(adapter, req, data);
case RDMA_GET_PARAMS:
case RDMA_CQ_OP:
@@ -448,10 +448,10 @@ cxgb_offload_ctl(struct toedev *tdev, unsigned int req, void *data)
case RDMA_CTRL_QP_SETUP:
case RDMA_GET_MEM:
if (!offload_running(adapter))
- return -EAGAIN;
+ return (EAGAIN);
return cxgb_rdma_ctl(adapter, req, data);
default:
- return -EOPNOTSUPP;
+ return (EOPNOTSUPP);
}
return 0;
}
@@ -464,8 +464,8 @@ cxgb_offload_ctl(struct toedev *tdev, unsigned int req, void *data)
static int
rx_offload_blackhole(struct toedev *dev, struct mbuf **m, int n)
{
- CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n",
- n, ntohl(*mtod(m[0], uint32_t *)));
+ CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data 0x%x\n",
+ n, *mtod(m[0], uint32_t *));
while (n--)
m_freem(m[n]);
return 0;
@@ -1308,7 +1308,7 @@ init_tid_tabs(struct tid_info *t, unsigned int ntids,
t->tid_tab = cxgb_alloc_mem(size);
if (!t->tid_tab)
- return -ENOMEM;
+ return (ENOMEM);
t->stid_tab = (union listen_entry *)&t->tid_tab[ntids];
t->atid_tab = (union active_open_entry *)&t->stid_tab[nstids];
@@ -1598,11 +1598,11 @@ offload_info_proc_setup(struct proc_dir_entry *dir,
struct proc_dir_entry *p;
if (!dir)
- return -EINVAL;
+ return (EINVAL);
p = create_proc_read_entry("info", 0, dir, offload_info_read_proc, d);
if (!p)
- return -ENOMEM;
+ return (ENOMEM);
p->owner = THIS_MODULE;
return 0;
diff --git a/sys/dev/cxgb/cxgb_offload.h b/sys/dev/cxgb/cxgb_offload.h
index fdfea35..131640a 100644
--- a/sys/dev/cxgb/cxgb_offload.h
+++ b/sys/dev/cxgb/cxgb_offload.h
@@ -10,11 +10,7 @@ modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Chelsio Corporation nor the names of its
+ 2. Neither the name of the Chelsio Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
diff --git a/sys/dev/cxgb/cxgb_osdep.h b/sys/dev/cxgb/cxgb_osdep.h
index 9159e1a..d1e69c9 100644
--- a/sys/dev/cxgb/cxgb_osdep.h
+++ b/sys/dev/cxgb/cxgb_osdep.h
@@ -38,8 +38,13 @@ $FreeBSD$
#include <dev/mii/mii.h>
+#ifdef CONFIG_DEFINED
+#include <common/cxgb_version.h>
+#include <cxgb_config.h>
+#else
#include <dev/cxgb/common/cxgb_version.h>
#include <dev/cxgb/cxgb_config.h>
+#endif
#ifndef _CXGB_OSDEP_H_
#define _CXGB_OSDEP_H_
@@ -95,8 +100,16 @@ struct sge_rspq;
#define TX_MAX_SIZE (1 << 16) /* 64KB */
#define TX_MAX_SEGS 36 /* maximum supported by card */
#define TX_MAX_DESC 4 /* max descriptors per packet */
+
+#define TX_START_MIN_DESC (TX_MAX_DESC << 2)
+
+#if 0
+#define TX_START_MAX_DESC (TX_ETH_Q_SIZE >> 2) /* maximum number of descriptors */
+#endif
+
#define TX_START_MAX_DESC (TX_MAX_DESC << 3) /* maximum number of descriptors
* call to start used per */
+
#define TX_CLEAN_MAX_DESC (TX_MAX_DESC << 4) /* maximum tx descriptors
* to clean per iteration */
@@ -159,6 +172,7 @@ static const int debug_flags = DBG_RX;
#define max_t(type, a, b) (type)max((a), (b))
#define net_device ifnet
+#define cpu_to_be32 htobe32
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index cf7a981..e4c121e 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -69,7 +69,7 @@ uint32_t mb_free_vec_free = 0;
int txq_fills = 0;
int collapse_mbufs = 0;
static int recycle_enable = 1;
-
+static int bogus_imm = 0;
/*
* XXX GC
@@ -292,20 +292,23 @@ sgl_len(unsigned int n)
*
* Return a packet containing the immediate data of the given response.
*/
-static __inline void
-get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void *cl)
+static int
+get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void *cl, uint32_t flags)
{
- int len;
- uint32_t flags = ntohl(resp->flags);
+ int len, error;
uint8_t sopeop = G_RSPD_SOP_EOP(flags);
-
+
/*
* would be a firmware bug
*/
- if (sopeop == RSPQ_NSOP_NEOP || sopeop == RSPQ_SOP)
- return;
-
len = G_RSPD_LEN(ntohl(resp->len_cq));
+ if (sopeop == RSPQ_NSOP_NEOP || sopeop == RSPQ_SOP) {
+ if (cxgb_debug)
+ device_printf(sc->dev, "unexpected value sopeop=%d flags=0x%x len=%din get_imm_packet\n", sopeop, flags, len);
+ bogus_imm++;
+ return (EINVAL);
+ }
+ error = 0;
switch (sopeop) {
case RSPQ_SOP_EOP:
m->m_len = m->m_pkthdr.len = len;
@@ -315,7 +318,12 @@ get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void
memcpy(cl, resp->imm_data, len);
m_iovappend(m, cl, MSIZE, len, 0);
break;
+ default:
+ bogus_imm++;
+ error = EINVAL;
}
+
+ return (error);
}
@@ -362,8 +370,11 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p)
q->polling = adap->params.rev > 0;
- q->coalesce_nsecs = 5000;
-
+ if (adap->params.nports > 2)
+ q->coalesce_nsecs = 50000;
+ else
+ q->coalesce_nsecs = 5000;
+
q->rspq_size = RSPQ_Q_SIZE;
q->fl_size = FL_Q_SIZE;
q->jumbo_size = JUMBO_Q_SIZE;
@@ -664,6 +675,35 @@ sge_slow_intr_handler(void *arg, int ncount)
t3_slow_intr_handler(sc);
}
+/**
+ * sge_timer_cb - perform periodic maintenance of an SGE qset
+ * @data: the SGE queue set to maintain
+ *
+ * Runs periodically from a timer to perform maintenance of an SGE queue
+ * set. It performs two tasks:
+ *
+ * a) Cleans up any completed Tx descriptors that may still be pending.
+ * Normal descriptor cleanup happens when new packets are added to a Tx
+ * queue so this timer is relatively infrequent and does any cleanup only
+ * if the Tx queue has not seen any new packets in a while. We make a
+ * best effort attempt to reclaim descriptors, in that we don't wait
+ * around if we cannot get a queue's lock (which most likely is because
+ * someone else is queueing new packets and so will also handle the clean
+ * up). Since control queues use immediate data exclusively we don't
+ * bother cleaning them up here.
+ *
+ * b) Replenishes Rx queues that have run out due to memory shortage.
+ * Normally new Rx buffers are added when existing ones are consumed but
+ * when out of memory a queue can become empty. We try to add only a few
+ * buffers here, the queue will be replenished fully as these new buffers
+ * are used up if memory shortage has subsided.
+ *
+ * c) Return coalesced response queue credits in case a response queue is
+ * starved.
+ *
+ * d) Ring doorbells for T304 tunnel queues since we have seen doorbell
+ * fifo overflows and the FW doesn't implement any recovery scheme yet.
+ */
static void
sge_timer_cb(void *arg)
{
@@ -688,6 +728,17 @@ sge_timer_cb(void *arg)
break;
}
}
+ if (sc->params.nports > 2) {
+ int i;
+
+ for_each_port(sc, i) {
+ struct port_info *pi = &sc->port[i];
+
+ t3_write_reg(sc, A_SG_KDOORBELL,
+ F_SELEGRCNTX |
+ (FW_TUNNEL_SGEEC_START + pi->first_qset));
+ }
+ }
if (sc->open_device_map != 0)
callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc);
}
@@ -920,7 +971,7 @@ busdma_map_mbufs(struct mbuf **m, struct sge_txq *txq,
#endif
if (err == EFBIG) {
/* Too many segments, try to defrag */
- m0 = m_defrag(m0, M_NOWAIT);
+ m0 = m_defrag(m0, M_DONTWAIT);
if (m0 == NULL) {
m_freem(*m);
*m = NULL;
@@ -2051,6 +2102,7 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx,
q->fl[1].size = p->jumbo_size;
q->rspq.gen = 1;
+ q->rspq.cidx = 0;
q->rspq.size = p->rspq_size;
q->txq[TXQ_ETH].stop_thres = nports *
@@ -2211,7 +2263,7 @@ get_packet(adapter_t *adap, unsigned int drop_thres, struct sge_qset *qs,
int ret = 0;
prefetch(sd->cl);
-
+
fl->credits--;
bus_dmamap_sync(fl->entry_tag, sd->map, BUS_DMASYNC_POSTREAD);
@@ -2328,7 +2380,7 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
int ngathered = 0;
#ifdef DEBUG
static int last_holdoff = 0;
- if (rspq->holdoff_tmr != last_holdoff) {
+ if (cxgb_debug && rspq->holdoff_tmr != last_holdoff) {
printf("next_holdoff=%d\n", rspq->holdoff_tmr);
last_holdoff = rspq->holdoff_tmr;
}
@@ -2349,26 +2401,31 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
} else if (flags & F_RSPD_IMM_DATA_VALID) {
struct mbuf *m = NULL;
+
if (cxgb_debug)
- printf("IMM DATA VALID\n");
+ printf("IMM DATA VALID opcode=0x%x rspq->cidx=%d\n", r->rss_hdr.opcode, rspq->cidx);
if (rspq->m == NULL)
- rspq->m = m_gethdr(M_NOWAIT, MT_DATA);
+ rspq->m = m_gethdr(M_DONTWAIT, MT_DATA);
else
- m = m_gethdr(M_NOWAIT, MT_DATA);
+ m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (rspq->m == NULL || m == NULL) {
+ /*
+ * XXX revisit me
+ */
+ if (rspq->m == NULL && m == NULL) {
rspq->next_holdoff = NOMEM_INTR_DELAY;
budget_left--;
break;
}
- get_imm_packet(adap, r, rspq->m, m);
+ if (get_imm_packet(adap, r, rspq->m, m, flags))
+ goto skip;
eop = 1;
rspq->imm_data++;
} else if (r->len_cq) {
int drop_thresh = eth ? SGE_RX_DROP_THRES : 0;
if (rspq->m == NULL)
- rspq->m = m_gethdr(M_NOWAIT, MT_DATA);
+ rspq->m = m_gethdr(M_DONTWAIT, MT_DATA);
if (rspq->m == NULL) {
log(LOG_WARNING, "failed to get mbuf for packet\n");
break;
@@ -2385,7 +2442,7 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
sleeping |= flags & RSPD_GTS_MASK;
handle_rsp_cntrl_info(qs, flags);
}
-
+ skip:
r++;
if (__predict_false(++rspq->cidx == rspq->size)) {
rspq->cidx = 0;
@@ -2661,6 +2718,10 @@ t3_add_sysctls(adapter_t *sc)
"txq_overrun",
CTLFLAG_RD, &txq_fills,
0, "#times txq overrun");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "bogus_imm",
+ CTLFLAG_RD, &bogus_imm,
+ 0, "#times a bogus immediate response was seen");
}
/**
diff --git a/sys/dev/cxgb/sys/mvec.h b/sys/dev/cxgb/sys/mvec.h
index 12566dc..4752070 100644
--- a/sys/dev/cxgb/sys/mvec.h
+++ b/sys/dev/cxgb/sys/mvec.h
@@ -134,13 +134,18 @@ m_free_vec(struct mbuf *m)
mb_free_ext(m);
else
uma_zfree(zone_mbuf, m);
+
+ if (n)
+ n->m_flags &= ~M_PKTHDR;
+
return (n);
}
static __inline void
m_freem_vec(struct mbuf *m)
{
- while (m != NULL)
+
+ while (m != NULL)
m = m_free_vec(m);
}
diff --git a/sys/dev/cxgb/t3b_protocol_sram-1.1.0.bin.gz.uu b/sys/dev/cxgb/t3b_protocol_sram-1.1.0.bin.gz.uu
new file mode 100644
index 0000000..fc8472b
--- /dev/null
+++ b/sys/dev/cxgb/t3b_protocol_sram-1.1.0.bin.gz.uu
@@ -0,0 +1,46 @@
+/**************************************************************************
+
+Copyright (c) 2007, Chelsio Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Neither the name of the Chelsio Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$FreeBSD$
+
+***************************************************************************/
+
+begin 644 t3b_protocol_sram-1.1.0.bin.gz
+M'XL(".):ED8``W0S8E]P<F]T;V-O;%]S<F%M+3$N,2XP+F)I;@#EECU+PT`8
+MQY]<VAA*D?@R:%4(%$L4!X,5<2NZ.91^A([2*?@%3%L<%(6`XN"NLQ_A?"O%
+MJ3B(DX-"$:>S=K!5J,]=J20Q@U#:#AXD>>[/O?SRSSUW:;5:7]`NLKA+$K3\
+M&I9_J'U6DG+53LRON[0/L$1(\,J70@/G>[*-N;B;3P&R(MU0&#L*Y4MA2V@%
+M(,J*K`:-1W0;\@?UGO`UKDT,C(6B2V-IB\P`\F&1+B8&ZM\;!?R^AA$/:$?0
+M/R2T!LG7U)+`(=P:RP(HNJP27(;,GCUQ>N%+V21*!,@:5O-V6VN43;D4.9YW
+M:RQD<KZ0AT\_%R'W3[J8]/C'BP2@=<O'\('SIF`SJO/QN`<-:EY5(9%+N>9H
+M:G6!XLG?;$85L175._XQ171*!?$18U^S=VC7S('OD?ZMX9HDCZ#$.$S!6:9]
+MRX5;\^HR<ISS>)7.C*].WU"_][WV)4A[OUV*WP_[^'`9*'K%^WVATJE!T3'[
+MYA_R/?OY&&1B&BSZ^'`OQOSEQTC#&=GK1?[^>7^FF:DSN//PL120(4P!OK^\
+M.,F-0?)A_A(5J)>O$V_MEQ\.=T7NLX(C.O:;CP5H-:SJD!CU>RIK6O_/MX#_
+6EYJ:)(M`PS_MK-?3[6^9;',3!`H`````
+`
+end
diff --git a/sys/dev/cxgb/t3b_tp_eeprom-1.1.0.bin.gz.uu b/sys/dev/cxgb/t3b_tp_eeprom-1.1.0.bin.gz.uu
new file mode 100644
index 0000000..73b5298
--- /dev/null
+++ b/sys/dev/cxgb/t3b_tp_eeprom-1.1.0.bin.gz.uu
@@ -0,0 +1,46 @@
+/**************************************************************************
+
+Copyright (c) 2007, Chelsio Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Neither the name of the Chelsio Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$FreeBSD$
+
+***************************************************************************/
+
+begin 644 t3b_tp_eeprom-1.1.0.bin.gz
+M'XL(".):ED8``W0S8E]T<%]E97!R;VTM,2XQ+C`N8FEN`-V5,4O#0!3'_[FK
+M[;5634&PZ(&I%8VBT(J@A5J#=7`JW43H$!W$T8\0+8@.@DXBN+4(^0#N410<
+M'(I?0'%0W%W<O*MI(@41(77P$=Z1X\][O[R\=P=%@32*3XN[:\9='7?])X+B
+MY)CU3&<;W3!,S@#M<SMB_2%#>D*WGIH,JR9?,7(**GP[#=-G8'0N3+#+8#PD
+M&=A(\`S5*5WX['445H(W=RKQ1@HOH>!2_%P'71?_`HZ"`<`P<JG@4_PL$-T?
+MPJP:L]<(ZP/&K0PVQ'XXD!36CG!+!+$PR=[*.4O*EJMOV&9>K9YY$4*2(2O\
+M28+[=>@F4`$%OOV>X4A&T.);,&0*:8H,"M0WB5G@U&,H$NG?W#I<(2)?+73M
+M>0Q&<Q%U42J,7>YWH"==04GT(IU@$G(=C],`#SR%+ZAOVEJ>U_P4S@W/]9=+
+MK.TS\6V$(!A>S8696KXE*)*&%A9_BX'3'/,R]UB=9BA\9<A`'2P#=E(Y[9,'
+MI)@+3;9$YQC:!45RC_.ALA.UE^E!KYA-T7O;6JN1_XK!`2-B+J+'\P>'=WH$
+M;4:;S]$NOHL0'*278G2=8,:[NZ1`52F1,]XQAM:]V3J.,F6A31M5;?C]8O$#
+(X@X'9$0(````
+`
+end
diff --git a/sys/dev/cxgb/t3fw-4.1.0.bin.gz.uu b/sys/dev/cxgb/t3fw-4.1.0.bin.gz.uu
deleted file mode 100644
index e434c1d..0000000
--- a/sys/dev/cxgb/t3fw-4.1.0.bin.gz.uu
+++ /dev/null
@@ -1,482 +0,0 @@
-/**************************************************************************
-
-Copyright (c) 2007, Chelsio Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Neither the name of the Chelsio Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-$FreeBSD$
-
-***************************************************************************/
-
-begin 644 t3fw-4.1.0.bin.gz
-M'XL("$@Q:T8``W0S9G<M-"XQ+C`N8FEN`.R\"UP3U]HO/)D$DDPFY$+`@!"2
-M$&!RCUAOK;74NFM;[5ML:S>[=K=L$ZRV6FUKJU4KB$##/2!B`@206B]X`VJM
-M5ML.:!&5MBBM52'<5-2J>*F]*_,]:P)J^^Z]?^_Y?N=WOO.=\T;7S)HUZ_*L
-MM9[+_UEK#<D8#SN#85(YPQ!J#,.2L<>P7@S/P/@8NCLQ#H;U8&RHAB@V9<J4
-M!/1\!N.$W(WS$M2<GCOY<+BKL:1R&L/.CL*^'X5=&855C\+6C\)PC-;@_:,X
-M.-:DCB:P!520>9S-/.X^\[CQYG$3HQ_D0(Y&-6V#%]9QF'6<U#I.;1UG\[_0
-M$E)_F;AQ6-PX:=PX=1S[BHMC<J8]F&DG<6R-6LX<OR=*CUJC3H=(6S!S#"6T
-MA3#'0IECM.T[=<`<3C*FX(T-@*HY,AS^OS5*P9^J"!A-\GF/O#WJ++QZ:\(5
-M#-7>',(TTS8\#D_&`NYDX4V"]]?8UNDCZM7J#$VF=O'HP-:'6O^>C,FR$G?-
-M++5%3^0M'OV#UD3:&9^<^3B:2%LP@0]-K5%K30ELU1_2\5Q+`%M+?3!3OT8M
-M8^H)*?;?O__^_:_X@9R>_+<93HR2,C\3__)UU"U_.(,%;OB7<8;&4/CG\:9.
-M?[RITQ\7IL&])XHYT@KQ##5+(R?M#"9;BNX0,LY@\E_4(#P0(B!^"]TAJ,]@
-MP4ITAS`1XBAM(H0$B(]'=PC3(8[2ID-(A/ACZ`[A!8BCM!<@)$,\"=TAS(<X
-M2IL/81'$YZ([A#R(H[2\H;@3[BX(VX;BVX;B&^#>IL:X=?XXM\X?5V3\[QE/
-MMOKCR59__'7>_U?Q/_+HB[HHYFL:3)4:^*(-XDO]]#Y;`?EU/6!S4($HYN!9
-M-?;,94AO56,O[8*\W_AYJ>D:Q-']8-2M00R3,`RR40$0$B"D85A8%\-@7=L_
-MN_HP/(]!C=)@%"&+#;U/QK!%+!W`G"S3_X+*J"!P,`&&_F-B"$I_'K8@"15'
-M0.`EL(\8"8'+ML7#`ME>V;!N#%$A()G/&8;IAM##9U!MOV!\!H2`095!W_A<
-M>,6@Q&M\AAGD,JGP>`#"<+$HYL"U:G\_HI+9N@5IB=`<RL%VEKD&::$P;DW0
-M*^;G#_QCE0'!Y>^!2*VV,FG,(+0"N3',A$%Y'%$>Q;0H4:]02U#V*@>3H;+K
-M(10QS%64]GL4\]DUAOD9Q6_#.)_$.+]#6T=`G@]U]F)(=\1)>Z'7:IL?2\`<
-MV"`L@CK60)Z3$&!^6GB]0$HO:I;;YC(FVM.,B>]`<$'8F`;M2A`645L'43UI
-M0"_4!+1RF%^,B?5I\$X*=\R8V`#A4PKN4.[3:DB7&1,_@;3]:;TP]KT`;'J@
-MC5YV]M.@+X>`1P[U1-W&!'"_"70(?/"#>P30[()P&;)J:';,6DQJ[+EO(%R&
-M_H%.>>XF!-`KSR5',8=-D&8#WDR&9C20!GJ)NQ_*[&%^9ZZIL1>^4&-_CX'0
-M#OP<#'GWJS'>LRP[,4=:[N5WSI]TK%J*)=P)"N@[,-.=,)PV')08K8[@8'>"
-MFI/`I@T'E/;G9Y3G;DC^0]!QJM78])X_AFDG[PG*H2!58T_`_?'[U-A4T,%_
-MZ;PKO]-!5J>O&+I#F/;/@L!_GPIZ]]%.*.^Z6YYW4(W90-_R=JFQA^$=#\9N
-M`NA3'NC9AR!=W:+&QKK5V'V@FZT@_Y;%:LQ@4V,Z:#-^LQJ+A.=PT`W!"C4F
-MWZ/&I-"6%.H5@ST1@0U`=N8O<_TA@%1C?-!%DR!]#.3CM2(:XAU^6M#=\:=_
-M_S-^(`L]_GMS*_`AZ+M#*_ZG5/S?O__^_6_X`WZ_X+>,_^SW3](?B4[[K]3K
-MU\E_K1[2S3?_F/Y_16#MT=`=0A+HPQ<==Y__SP[#\XT@$[+30_&'X)9VS_/G
-M<$NXYQF!"?6?GJ5_>A;\Z9GWIV?\3\\<A`6&XL-I=W\OE'#^7H*_6,)]J01[
-MY+_"V7_ZO>#B_-V%O^CBON3"GOE_4;ZB!(MT<;PE>&4)MZJ$)R@)$)8$$B5\
-MT7^1G`HH[,(K7?Q(%[?*Q5OJ"GC'%;C,Q5_^7R2GDVW?5X)WE7"[2WB\DH"`
-MDL#`$CZ_1"`H$0I+"*)$].]HZ83"+KS+)8+VNUV\7:Z`CUR!NUW\CUV"/2[A
-M7A?QB4NT[U_3`C+Q-TW$R0IY!--%T/_Y/<)SF@A7L6)-2#!S&[]@*PGE1A.K
-M;6M'$#9_^9E2[#CXQH/$4'TSD[#V/SR[L6_^\'P3^_;N\__(+T"!V9E?_X>+
-M_?_F-U\:P)'A2:'EQR1H)8[&:`V&C\(?'X4]AI8*:4QVE0R^*N:R"X?*JZ*1
-M5TG:)?B$?'>30)^%47D\P[9;*S81GC1]%H?*$QBV_4(\H5BP1>1)\ZSRI.NS
-MN%2>5'$5XR=@B@$F=("!B'R`"1Y@UJCI9'J1<F!0,3!(I?LSW(8K2Q.N&/@=
-MQ7GLX,^7\FB;?.#G=/6;&CP9>X!."![X<;5MM6WQJ+C0@1]"!FYD)NZ:N399
-M,7`M(T'W)*.;_)`H`:,7A0Y<CIV-P?\E\[Y3#ER@7X_+PJ";J#YT8^M50^R>
-MYS_?Z6H]P3-J590V4J\+-,3@R[-Q8BM^>%_PP(EVB:F.;ZG#Z&/<`<+2-^6T
-M6M2#=52G[#S/UHK*"PP:/);`WMHD==ZGCP](?4^06A40^`H.%1&B:2V?MO[U
-MM+K#UIF0)/X.E1DY<,#24$F?7-F.)W/*S`W>[C;',7><FJ3I=5)RB6SK2GU?
-M%D40[ZR&]V9]7Z9J8(^C2$?%<P1.19"3LW"5CNZEVRD-K_('@5,F=N*1`_7N
-MZ]YK)(Y1#5[S+265IZ1V>]^[CSZ;NN0^Y<#6PC&=/:J!VHJB2E>!NK1$,(!7
-M%M-]RH&-E6O=:R2"!(E31I7R4W\66)_`)#MQ:PR^<DD`-4I,Q6C?71)@&"4Q
-MQ&A6+!EOF*BV$AR*P,2_C!<()CO25BD'UD4-K+-F3<*JG5A;WKU7(,;0X#5L
-M4QIV>W-L2S9-L&IX^:,+XND,X2'1KE;WZ\J!'!XC<R]R&BO?]BZ)''BO]"WH
-MBOL-PIT0Z)0)&)PB(N!J?9MWF#:H2;)6)JH5Z&LRA8=%^HV9*8EOT&IP\X$:
-M@J4FI?!U.[,D8N!5Y<`K]/I\J46KVK8"B-`WI&/'>%AM.+4*%V[!];O3(5%P
-M=E0A77DMG\YNVN7STN]Z`BQ-'$LS9M7@_O[;!Q]OEY@)S#[X#R,1B!OPI*`-
-M]L$Q!M/BCH2DH#7'JX])YDN)$[9HT^(UP<$#3R5CKX0/3#N8IAIX`O@(6K#&
-MIUMZ<43_6-1@T-E1^=O+V[*W.W?N\N@WBM_)YA;NJ-JNU^`&(H'PX/H8_*MG
-MLY.%\V;,70.S/AD8)ADQS#2Z[D1=R\?TC(QZ^G4>;RI_!>YHE-&+*`UN(C"!
-M8%I*8;-^-@;EYJWYU!!?N7`C;F<66^*]NQYS7)T/PV:</E@FA[%[?Z?^1I:O
-MCN6IO^EO9#J*GJ$;Z=7A`UJ8EXHS93T"!HUY52\0:XKW&N9+3:U*TUAORHRW
-M.UT6@F,E,.'5\1+)9,>U4M5`F'(@C.J?]$I]>.K'`6B^Z3Q1E&+!KR)_W'\U
-M$%A><LB`;,FA:4Z[6<-[;[;P,Q$])6J`+.FMZLDPKNMWG^?Y9`%3\)(^^EK5
-M.;(J(9"127QXXVVX>,_JU>3Q:M(C>]]#%6?N^E1P4D259AZ30/)PXO'JX40D
-M5T`BP9*8PKQ@9V9[I'.+_YJM,ZDE1G50?:M))ZF;OF%?W3ZC+FC/JY2+;W!Q
-M-SCK:PTEW#HG5<+/"4X2\O*E<X^![O'2/;DZ@UJBO'+&L(NK5P<5UNEW\='P
-MU%7J[(/SVR5#\T.>*=/I=$%TO5$GH>OL@T]'7CE*UU-:58%\^W8_%V"]/&Q?
-MN.K*0<GG.'#$'7;(;G.["ML*CN]BJMI2+P98CG,L)UC^^YSEO]M7<X*]"H^L
-M/(1NR)/Y@!5J<D/R%=DR^^`6:.GV!=`[@90Z$#AHGE,A%$X[7'1'S9"?LJ(!
-M_\.O;#'65*JN?+!P-\P[9J[QTJ\[VGZQ@JYI)G^2U;ZJ;\BB"UBFB-8W9"JO
-M5#F*PD&YV.-`N;2[VP2ILD#H];&LL<HK)8&%BL#`J9%7JIP9WJ+(*Y4[G5%7
-M*I'(NO(-PCG20!^.IJTXUB:WVDR4+9ADI#RG-'".5#`'EZ3BJ*(U^?=[2YSC
-MW&NSQD=><966QM9X"R?$SE=6K7..J2QWNT'!H0K+\FVQ&[U+OANGO)*NNI*6
-M-SHGGKY9Y:VLR#*:2H/I(X92.5T-M996&DIE8I9M>"MED@'$.0.XI50*0\PJ
-MPTQ!BXC:#<HB6TN@\8B\,OL@;64%U%B3KN_%R7VX<2.:$>'944Y?55JN+[M[
-MU[YRWW(/KZ#+<D(,$T(R?H50!88SXLJSV'6>&53+?&QY.&J"K46P!Z?NU$)[
-MT[)I9],NCX=^)SO`W,0Q-V,6#1[T&6Y!U23Y=8@XW:]#!`9UH%&#S]W,F[N)
-M<TPB$DQK*403V9G084LBI_G)5ET9I^^K7%@*TY1H[?/2/L?UQ\!>L-9BQ]OZ
-MV5F-F>P</F2:G<F=`!IB+/VZ\HJI1*[3\-S7UOU`OREX3,:'@;W^GMFJB51>
-ML?)_%@J6X.OH$5>L5)]W76.<30I&@UPBY4_!1UPQ4OU>B)0TO3<F0^Y8]%B7
-MS2OST:E+0G9-*)A`Q8=6'G(WYX^S3)2:FP7F5I*O5"S(UI@[E7L\T<4*Y\4U
-M;>YCSO.KK[B/4\4A:[YQMZ^^9+FL7O-MOHR^C^ZI9R22IUY=/(Z^C_^.D/00
-M_'$DG_OPX?A*]WY/W>B6^]G[^)9T=(<\E'Q!CJBRTE(JJW17ENLK;,HK`='-
-MP2,N_Z371,0URZTQD7%:+-43`.)OB8FT-(^@FD/#+M\.8&369F74Y4OZYA#@
-M/FNS8NZFE]&,S<Y$2F,.,,4&5DR&]+O89!_,''FY,^SR:7H]L$B^=.MRO^$P
-M]Z7KBW#Q=MS</SS'=55I^779#6`[ZI#M:.!8=M]K.Q[,IBAMX#NKGFILMS9'
-M6)I5EF8-71Q^^3"=H6^.#KM\PM"L-32'AU_^5M\<:6B.HII'*B^WT^NIYACE
-MY>/$)[A@*4XUZP`_V)EI?GXA?T+\0KL!G]B9<<`W>G4@&(&Y;M[<=<`W8`E:
-M\N\H`-&G2!\:U63HY2WD)[*-M:::+#U!KD"FY;"I)M/1>,`XNY+5"5\89WL;
-M\QSUG^HU:F%:LED]\1"#\2=QB$GU._C?3R!JA>(=,LOEB*"@AR4#W/H!N`?5
-MB@S;(KZK7OE=A%D38PV_M:PC6+R#E/0F8\))'/ZD^J7"]R802XCL6$K+%SK)
-M);G03@5]TJ")MF@T];4$\90A)GK9)7G=-N!\4TRT&(00=752NX1NHZ_1Q25R
-MNE=Y><7:8'I*#"BB#]UU]&K!3)D@"7?74^J).39>!H=W=;R`D0J=',&5\7R?
-M%%0/49A`E"7P:Z6434J[='F#O(OC)5<GB!@IX9%*/+C8@Q<:S=!-!M=K8L1F
-MA5"O4%Q>(IB)\T`UT1EJT%:"*3+!%)S.@4M)8Z&!YY%5'806H:A@?$*`4THX
-M<2'(4;-./9%W7P(QA;5>API'TVE5!_+CW2V5A[U->JVB\87Z,D.L8NT7[J.>
-M(QGC2UH+[Z_ZLN"!RJ_R)WB_SAD3,]MK:)9FCXUY0:EOECG'Q<SQ4LUR'1BV
-M*;*-4ZR3,S.#K;<2K8]F9L@/+\J)S=9OJC7$!A(>4BA\3!\3DY*XD.5<Q+;D
-M2OM@8+LDXK+Q8+7RLM'"ZC;]['1`.PA6S!E&.U\"VODR]VO@V"_?W<O-_LKS
-M)8P]X1_XVU]4R$ZKRZ7\Y7A2X-_R9+E2N@U,/@'3?V5\2M<4^^T-0TPX$S'A
-M'S`UR1V+PW@#-\Y[#Z:Y>)@AP2[1BX3$M,,;OTQ$QI(W'4\2C8C;P&4I9]DS
-M'EO\L=2DB383O)9#8B]N1CS0%G;IEJ6X<F$_5/:"H=CK6/^<(92@;QS:">RL
-MO/0CN5^VN57?!/A8RJJ\1TQ-P,X/&C76@CFB2V.!?QWUFZT:M:2.Y4;)I/I?
-MA(43)(Q0Q(@D@H<))[?>*1`\O)F1_`8`$U_:AG@XM2.4"K\E_HT4K&=+`?-O
-M%N9,D-02^;%Z+5_L(9>50UL9^7;O@>S9GB9GBKO%FBR=]S-@A:/K#E-:I54;
-M7`Z3775DY3Z45A;67EVNH%=%73I*G\D/KP@Q@2)NKVH3M,J"6O&*8Q&7#NB3
-MI<8FKV$VW[A?:6SV'MVINM2.!BHOI%!A3N9ZI*1/)EX@,'>JDSB_6K3!<;'*
-M^@%+;'#+0\[80OW[3G>L@"$EDL>LP`\S`M&`FN>K59>:/-+A6I(X&^S,P7;)
-MPK6@DEX[V.-7#K[$),$Y5I?L1OPC&K`/OL!&+ML'GRG_@BX"$;Q1==@+C+OR
-M0YB0T14AY8JR,$?B#KK'7S/T'`BLDA8JO$H@<OL"EL:V;$6!,C]LQPZ+@YL7
-MFZO?WDKN(T6BQRIB<^888V*$M639'!@H^H;0*:!BE?9!$]A3:K_2'0K30>1P
-MD5YXV!#*!Y`/3D/J2:!Y%4S-LG:(+'6&%H[8S(#QA#)^>DZKC7)A4L".E.V5
-M.6&YBKR0@CGVP1?];"K:BOHWI`N)92>JZ1G`>';F0<2W"')KH@$P&;8Q?DTT
-MM^3!>>XQ1HUF^58K8%;`[R9M)'("#W,ZJL$'O#3SW_F`P,TI.S^#@9XO59RP
-M60A>'(&!-$1>>F*N.V#N.CP9+S5H=(ZGN91&NPPT(?X:4`#-MWA9=8U0)#&#
-ME0=M2$[\\O608UG>>/J&HVDY<#SMSAE'9Q'N">ZHACPQN&FA0:#0Q;4"2TW6
-MR@.0=XH%U'G?)*/&DO.R:.M8T%5QFB@J5.QHF,*ONU<A'ZKB+R%$2PB^X&'A
-ML!`L<4;&A?)3TZR4)L:M7)(;IPU5O*=TCM"&W^*_1^*O)T>'AF!<5(5V!8<;
-M-T&PA-#*%='RD.Q89]R09L=5M,MSP>EP7\R>XTPI/Z?O%U']Q#(0`]P$7$\7
-MK38XDX'O!3F@G2>(:J6`\22@M=T30`FO&1FMB0(US(U6\)W2-1&KU>XP9Y1@
-MM$PP&E=>DH/ZA<B:\&BMR%'W55RH4A<:&A,Z(G,NO7CM97I&^17G*QGSW%=+
-M!D`=TVG\J1S)%`XO:3R=P']V_(A+W,R1_)GX>V%KSV9&\)%J!SB**[X?%&P&
-M98Y#/"/<W5/2"T,6L'9(O0,F@B)Q<N7:?J@R1C["K^1Y!W$)Z/GS.GEHG@IF
-M1:_1D?MDV_<9&C+K/-MJ#;LS*6V(/D97[Z1B0PXORH_-TV_RF6,#Q:TD23YF
-M`@E].HGE%,,V#LMS.L#W]"KH#;TK%DA/$+W*D<SA!&:,IY-%6>-S1Y:?S8UP
-MAHO*<7<O?PK@9VG@%#ST^V.\#3CO/ASB)3U0+",L<&Q"`/N.MP\O[X>.`('0
-M$0+<YQ9<`G;JO)UYLO%+4XS)0J3YY2'@[W@2'^0?B)E7`CKMR[FE?4A6DHC+
-M]MO@V#2>-,>8[,Q7=*\%W9L/%<;M5ZR3\_D/"Y9PG9'U2R"V3K9U2=P*1:H3
-M3,=-8!TJ5+!D-<0O..7`0.FRS5IM*!\8Q7Y[!\BK*51F"96#O(8&=RQ*XC4:
-MY<&1WZ^VR.7T#9-<EK+MYYR7[;<_:9<80J6.&1_0:=ESW<'E5SR7L^<Y7_$,
-MN*\ZYQGD4K<T^Q5WZ):]'L7R\H!L:;W'$TIG`"OH-5%^MC"$A@'8!7X%"QZG
-MB0&>XL<I>$MDPB7XZM`<Q9IY]*BR5V)@K*L%21S)3$[`_>,!*=")@C'C@3UG
-M2@-J<4%F0L"8":N-HIE28B8>,!H/^?XM@3L!(FMZ<M2948):&:2'?S\_^/OY
-M$%G;FV,`MN+6XF5GH6*#/"Q@3$+`3"G@">"AM?V0!HP$:<1,A!*`F89Y:'5*
-M0;!SSOL#F_=0H0$@3<MS<<MECF@KZ0RI3''/`>'2;_*`>`D$CU$Q,4Z5)[;\
-M9>`Z<J]LNU=_/!,4@,`CT)_(C/Q^E/WW&WZ=1[S&SJD_F]@C,!1G+=P$IBC=
-M6ISIN+:"?C_X>ZM9@R12Y)/Q6F7B5MS\A!RNE==5W\?Y$BJO%1C7_;CNYW4_
-M5=SD#N"5-Y"+5)S9N<BX7VTLS>Q(,.@"H:4D`D.ZE9U0F%B84^X#.++M0C4[
-MK^+A>3U1[=Q$SZ!"I?9!(S(OQ+/^-3D!R*EH,O]^1?T64=D$_70;72_<XU]-
-MNAKY/3?B>Z[IQ*17UH>G;@K`$IV8*X]0*19<%/GC_BO=EFNCB^E5=`^:SYN2
-MESB2@O&"`:EP)H>^%E`XGL]()0MQO5PJRDPP50R2^>,#,B<XC>`9HIGU20-\
-M>)`/!S\3S$O$Q=L`!$DGOGN;0:-V)V2J>6XI@IHS<4K#"_@"7_MPH4'@E%5-
-M$54E6-03H>Z@20D!`U*H[:TY`H,FBC`HDC$<KCRPU]M1S=Y'K>J)`C<N>2B!
-M\"^J3+6HR:B+S>2`;.>`N2]3_*7(W(\6+:X%?.Y?K^#9&6*^E*!I>J.1P%(6
-MG:`7T8ET":"9`B.]:K5->(HC?&^\8(E4+U=P"Q,DA0C5`@GT#8D/.BW.',^?
-M":`-NLKS2<4+</%,W%PQ*"X<3S!2/H,',#ADYE8E`/F5"?EJ7J54X).A0=B.
-M>Q^&82!;I#`,<5H".@$Z$+H>]R@/N@L]O[>[)DT4:8+N!I@T:HB(O_QWW<T9
-M[N[Q.O%VU&%@3U]"P8PC?0VU]:WF3FG0TK%N:(TL3'2?JCJ9_4SATQYYE=33
-M475ZY6JB?E_,"U+'RI_L3&N^W"G;GB^X2.J?XRSMX!9*ZQGO,U5/VP=/(7ON
-ML#T98$O&B$D<X:1Z-Y$]P:B>*)Q.'=JY;327Q7M4'@=LG6"T8.7'409-C"G\
-MUIM;0XD'2+*>-8_XI'I*F#Z!JR6`ON,VF)4B._,)BW%)L.,`;X<AK4&#@VTG
-M!-,.9]W%M(+9]V+:7)N>X"W^&,8G.J4I//SBX^::RH4G0`P'335>^@<'_5/D
-MQ4>=XP%<.U9Q3*&!(*X1%Q-`H+?Y730I<M&P+G--IE?I:#O1>-"JL13,/:V6
-M#(PU:Z(Z>BK#9C$'D/$M&P'Z`<$)S@/YRFR[I]TY>]U)]_'"E*I3!2_GA%5V
-MY,TI^[;B=.[<Y5LA3US413W=FQ\*TL]BT,IV^HP?AU[4(#E'.%0XA$,WJ2[>
-MS^(\96$8G09`SRT=`GG4+.:O!2-:KB+\N>./^#/:CS\IU47C4,EJ0RCR3V8Q
-M@+L.@U^W&TR,\!G[X$&P"$@?"!/M@WN@^^4*L*3$/H&^81C28Y?T#9D.U[E8
-M#<]+5QX0S)4A2];(+K9X\VQH;7NC=\FA!Y07?L\9G1]/WU1=^+FJJ-)5:%RW
-MMFP=XK]BLC(A<$#F+>4M0$S>V(.XM(1=D,XT;%,;T(*0BYTSA"+Y2=R(E!W@
-M_7_4+G$D9J@N'/=WG[[F1[EAWI"[`S`B_^6"$*<?Y1;,V9[?V;.T@U-_V1F6
-M.Z)BCO=EY*MMK?4[:F6QA7/!68-1JIIK'U2`@6,5M9"'%*AP&SB^8#(_.JW.
-M520)Q?;;6_VO!;?NP:[\HW>PZ\M(=S:^0:&=!@%X^T>ROGP1Y4(\R&^$LJ`W
-M3(0\B=L>NP&+V\!'$^)?/`J_L%E?4QEQ80.[?I1O!$:\[JC/!!DEK\AJ3U%@
-M*#+AQ8>FXDS.09ZCL99NM\1+G9-B1PE+I!D/Q<;P!'-DXCEXY(6/O'6E]:`]
-MLI2E'])S2S_"#O)X&4I!RS,80"2P&;L"NF1!3EQU86OHA4*(N!OH='>CZL*6
-M4AIF0%?C]3;IIBMU&[T'=AJ^"(3YT!5GZJ9+=:69!6,J#?ECO<:<<66F[/%F
-M`R;\F\)CID8%6VR4;M0(BVYB4-!4'B\AUJ;7Q43JY!@5$Q&K>]`P*@1&@Q`^
-M+-Q"ZBLNZV.B5IX?(:Y.QLA)',$D8QZ'W#,A","0AX175DV4\L)[DE7)C306
-M-(DCFE3_:5#'!$O%+4N,FMPWEJ:I42,-H\),,=&F&!U@-D!-IEBE:"!"Q$10
-M,5IKC,428S6K%888C5C\B%FG@$'_*I$>U=@$0Y_$?8M>YQ]Y4!-Z72#``G`A
-MT"QT)/@2:#I)$$^OHT?]^:7JPH,'VRC_CD%-NK$1%S.XE5U*%)T=E7W%[2J\
-MDGMU%U-U)74OUSG@O@*^@YC=+;#?'@1)4EZP8KT\O58U\H)Y:Q=V.]Q8@SQ_
-M4<?0JB9X_KD]GCIG3V[?+J>[9^G>`%,?Q]3/KD=VL>N1MS\&'7I:'7'AX<@+
-M,;F:J`L)HL=%.ZEW5D^E>T1[<2/!$7XV/BAH\I'SUB]OFW^:],K#X:E3`S`;
-M,L0\)5J;\\?]U_3UP'`6`N.R95*N'K$S7W;91%J2+J((3*(5X`_)16Z_N;=3
-M4&'6I$.NU+(H_2UIZKH`K,>)U>4)H^3MD@6_B?Q/_NO[^OU;Z5XZ370!E3V:
-M98&B_4!+`:+%A7+PHN2H#!OW7UE:H%6NV[\]5&AGBNEKPJ$=@OUV=$(!9(I2
-M!\Y]#[2.,Y;@@'I/>;H""2*2JUG,7KI.=?YVWH;@\U\6JBDBC=H@IM.#6CET
-M3]P&TJR)X(*RJ8E6/TA?YW(3N(/CB0$I4JL;4%*/8#0'DJ+.#XC`?+9RHLY?
-M@7>J\Y<K-L`3F^VUXZ$+!&#IL'H>-B_\W7*!G1F`206R@\^?59T_:]7PZC[5
-M5T=0U2,EDJ?`%@N=.-KP$S\B],GT.:G"PQQ@!G.UPK-!*)PJ\,C8IY#A2*@_
-M$N3A1)X_;JE6(<;9$"K,5N@WA+!7!7L-UE='1IX_ZJ\;I#;[`ZX3ZN7DFU7G
-MF\61BB`?1^Q#%7D^R#9$GF\2"I\*\"!2J`TJ\.6H#9'L-:)@DYB1B0<X`!6L
-MU>K*32"Q@@$9^Z09CFC]$>X`)[HFF"TVLM#$_>$QZ%X`@]X4;K%LT`85*"P;
-M-.Q5[=S,WJ.RC6(G!YH6LTV'G:\QUVB$#"?L?'7`:!G`(_'V1]V;83ZB:[3-
-MA=R@Q[GO*V`"`D?+`,Q:-FH/(AL@%C\:R/8D\GQ)=`Z7RP`548?RH?T@R`=S
-MN47`<)RUT)!^HR9:/3'R?"XW.D'"OCLTJ6H+`"(H$Z1*`$(KM^C5$X//9W`\
-M4K0@6`M/,&S""0DXFQ!V_F5$+XH\FK_!75M(%<1R?3`V)'T]:'`"#HP"-FG#
-M:DC.7LL=("$MZOP;7.`4'X=]$QL;'!NKB(T-B8O!G;'Y9K<>0+T^5AQ\_CY]
-M/+L5@'49XKV.ZI,(\G\B>[_67).U9_J[!^!%F[X&#.@1C[2D"'B9KH\\;]Q3
-M82[%>$^"K9!:-)'$)MS1\R@%!9TRKE-@3<^4/"6R9F7&QD0>>>>KOQJU*KTV
-M<KD'I!\[O#?X?,B_6OTXO@AXU4E9M8%+KS]&7U.>U]!-D7`YFRL-.Q\DFB;:
-M/<535UF?HZ[:Y?ZHZF/5>:5G#VBPR@\#/7C%7N^^R/,C(LYS$0C]A`0WJ@'I
-M->9ENL6$%KE?8C$#_U&D)E%DRMW]=I!90SQW83KT]2:='-Q_><3YF(C^`8LZ
-MI#!V9/_W,6J13@-@7VB>H9LW&3(=*J.6_8K6Y0ZEYC7D?KBP$^Q=!-;(J[N`
-M.<,W;T;;-[%\`'MSUQB@[P;H^Q8.77=XS[_?^Z?4#KH7HWG0??ZGT`L.\2LI
-MODV*Q6'"BQ-@MMY)K]>KR9']+:1'MM5C*<YZ[7PUN%2.S\N4_;_2WZCZCWCK
-M*^M,:J+T0P&H@X8"-=J8WV56\\L^KMIM_HB(U?'1;FQQIJE5;2K-M#/_^"99
-MAX;(BIJGZV-U(=98?M!)=B]@IFY>,73QQWGKX)HS=PUDB]=KHU*J3'KU\_.*
-MX#&:S=`3WG_*$J\Q;&>*>\SQ&E-\]"Z?>:/FW<,!IGBM::/&J'O>/O@+=(LN
-M(GXA!>X)_+U<X1:.\%?`-&%;G`+A5+TN1'"!W'P2FG2X5J)A]&*^\.W;Q9_B
-MWKB4_]AM(?"@__!O=M6".O/OUVZKH)JRZ-^6_@"$K-`W93JJWA[9OR>\?Z^R
-M?S5]-K)_=661UU6H+EU7MK:TI'R-'\;AF*4IDSYIN:RV-&<BF_B]S:P+C(W!
-MR]$.7P[XED]5Q=F9G'9)+)ML'WP(+2JR?$WF":Q-60M_AO9(MKU`>E=D_X)R
-M:(:"(5^#ML.*"]7@'565Y,=:8-#7>4LM:X<&W=B4B1S?YLQ8&([;%Y%OYNIP
-MI2SZP3!=:9RHI!O!L(A:_(;LJ\C^F1'],\%O_2[QE6>C3"_<3CW$;HK7Y9$J
-M9,N^%_F?_-?<!`.4+9@:))DJ(I\1/9;(:Y62*_"*41']LW8YT1X$D&3+?\2I
-M]HX!Q]0=7QB[D;'&!N8G1/6_NNS$5.YR$?U-1/_]WOJ*.NB)YT,$CX%YD%+:
-ME1]K4O.]NYV4Z2/"_;%53>IU?'E_',G(:ACMC<Q=*_$!D>6G3(0QX:6\7\.^
-ML=R`E*"5Z,W0D8H6O\W4V1D#"USS$LKER[^*IC\T353Z$K]+3`H8S)73KG(I
-MW6N&WEP9[^A^,3>A0&IGXOR+S%W)93*$\S%>1^)WU3FRI,!':1==#W@`_*HX
-M&,$Z^D!4__T%"3NM0053>5=$I]M2VW&#[Q>Z[:U+2ZI"DC&5IYK:)L72G&XY
-MG89=RZL*=J]W)#^G!T3BX[YUZ9D]6PJK^2<)R<*Q._=)YI!5:2==*+.4?U*T
-MQXFEY;EE5`TV#VWG9S:TZD-Y[M"E/[R4O;Y0D5*UX<,!ZS9E=LCI:^_\@!MN
-M_Y*R<+,9Z0EN_N2.MO#^4)@:ZQ28D3*;83+7JL66'PM0]LL$M1SEN1_*QJ#Y
-MB2^8+!H@*R?GQV[_U!N;/>4XO66O9\HQ2>;[DBSR@Q]+J[-JUKX?N`!/G<6I
-M7^"MR9]L9S;6M\:M4'H4=F8QVKLWJ$/TZE#%N<_`6W"X)IO4(MY70F.O3OCI
-M6/$^TGA.M[V6(*8:="%'JG,?*:2R)]=MQHIX2%\QDGVX,99?&"O90RY]8`3K
-M=X(4#*`MEQK_61):<TPBKB6A.G\=V_=!A8[J1;F/Y%.%D^MV8-=YV$#X#I]X
-M'UX>1Z\?>:[RXZ_"SE6:`8A>E:$3"[7A._<ACZLXW?HP+MB,4Z4(3DK.CBJH
-M\_9DUSD;=GD\=>]DRYWUT*J[#AVLB<&U!`?8!RUO;QDF`HEG)>M+EX2M"6E/
-MR`AQ)M!%@I=G"`13`]SCJ=#`9"S^JQ?T:L4*I+=^`)<FH=/F6Y04,.6;ZL,U
-M]`SZ'ZO7OU?-Y4[E"Z9";O[+,SJ3';2;3J:K47]IH7!:2M6G\][\)/N1=Y%_
-M(\BG5I0&&-7/.QK""V.%KTX5#Y*.GOFJ<\[&-,'X<68U&7;.X56`1^<=L<6G
-M/YZUV\DZG>\:CV<ZZI:4R\ND^9,KE-[@H*ZQV7&^'HF'7(GV?F(+@E=VP!UL
-M0*Z\,\$K<X9:U7R?K4"VF;'J^-V)LP9_9G=58#92/B\<>6ZJ7BT2>41Z+X=R
-M%>M=:_SP+>Q<VA8G7%3GTM#6Y<`X.S.'5>;KP\Y-`C]`=>Z!_!'(&2A.W^$K
-M4/BG0G5NC&0G>WBD]#\='K&>P%(O\@J/P1U\0S132`UN`S5H5`?.^Q`H'DGW
-MT#]8=8'Y4RPZOC?.2WGUWEA+P@CAK*<!HUMTHET#%AU))4B,.H=`\!=*1U@F
-M!RSJAS'IIZ^//!<:)'@QMX'CE"&4RH1C=;S-#$4,UC$229B`&4NG2R13!<PX
-MJR[4/IC!'HSIL81R9C%3P8/NI=L*I?0JHG""!#1$5VCVY'R9)]@^V."5.1)=
-M_I'D/HA;Y)Q9@[\IS]ZBZV%^(L[^CO;=]X63W;+(L[]NN[6=T=_(M&A5PBTB
-M_4^9_J,=^N/(SQ'NQ?4G_G">*\=_GFN+++\1?!PO[3]UP?KZ=\Y@L.-]PXH4
-M>V<^91^\0:^F@/K;S4!0"'<BGL2]\DTUX`\6:P1&G?T]Y&R7>+HL].QO^>H<
-MK;@#QT^1Q!,B0RRNK[C9<M_"2AAD\=8C&RW+SCQWJN[H6`/!`>`DW#I>))I\
-M=!=U^W9,%K@J$7?=IG!D%&K_X#CEJ&N/++L(8[Z_3'V\[9@$*N"R%:1\_JF=
-MH4_;1!9RXT!0*^FPO1$T5LZZ4X%3R&%?:JX>6BF=="CM[9PH_7S6EV)MC5")
-MFLKY@_UY_^)^`UU/IQ'LLNO17",4W3WLUX'G5)W'4\F1S6+C_FO-U_N9*I:P
-M>QRJ'#N3#[Z><,C7VVUG]NZW^G.=MM%IPDF*QKJ@?:1HVEB]3T#W"EG?[<A[
-M0P-RY^B8*T_D7^)EX_YKKAIX&#5UP=_4$=9N\.CDR+-OC#C[^H%5>AO78!/H
-M=<32]?(##<NWP,@5GTYFE\!9*6Q,27P*`(&A30F@D")^MZI%1K4"`)-@'T?,
-M"*GK.J-.(1@06'X$M7A\&/!R.I(/?SP,^?@LY`,;-H3Y^N_LGW+0)J)0,BV%
-M*89*Z_:)1%.A-D?=%RL^7D4WDA5H:8>H07Y<Z]\L-L'RWC!KF[+E]IWRV$U$
-MHW]U!J#LO/1N_Y;@O*(3?ASC!Z$6M<BD#A$/"*V].J!\9ZOIG`Z`:4>RX_,=
-M0*25)9(AK#<0+KWFQZ619PUVQH6D?S_C)^OH1RL^1@3YMS67'T;`]E_W$<D&
-MT(#HBT4@O(65`?\ZZ,*U+QUY=FZ)UK]KB?H1AN@63&M)]ZLPHFQX68-N/*WF
-M/H##2!VN'5K+XBKUU;(3U2O7"8S$;5$YQ[A!1L\PJ17T-^)6W*0#L[BQ74+?
-MW:3F3+QSUD#`'8>GS.#3HY*QV*_0RNNB_$6=">(%,Y*X^[ZK;MF&K$3&^M75
-M/-Y4,!2GDQW5+70RA8Y6^D]('LE>-/),/WM&\G-C`WON!3LX\DQ?Q)E>8X/7
-M.AUWU'T$BH?LDFV[#"@5,&HR!T.8T?6;ZDPGO3K\S"EPQ==\6%8W=$BROM*E
-M.G,<?*H^;TF1N5-I[O>FS'AQSSOT>I!;DI5;1]UCJC-?1YYI0^L4DU5U3Z`-
-M#1<Z%DD,KV^P3_YKV)G/_:AUBU.;GDE7XY-%VJS,87MR1YND?%YK9^I6VZ"7
-M=F8DPM8:GO+,-?8@!#?RS-:#0%:M\LRVH2.HZ>@(JI#!K5E#9L-TG#0?#UIQ
-MBA]YICJOVW2"/'B-:KT%BC'L3`7`1W>%,0MC<;L;<9!616EX$6=*H\Y\9VK$
-ME_X^"=2R\DP)?0S0/M0MZ1ZJF#P[*N+,5]LN%]"%32M_Y18<J*2M&IRZ?,M-
-MEZ>A7*C&1]LE4#SJ3`9];.=`U)G54(?^1KKP%*[_::@.9T]Y6F%/=A_8M'XL
-MU<-U]KI[$'^=8I>[!@/8-4X.\F&Y+X6=>?.>\;IGM':72<%7Y.X%W^!V.WM.
-M)9;`CCY]9^]S%C-_F&=1_GO$]VC]NQ]?&I;>.VNPR58;UT+\;`;=$8-;=420
-MCV/6*0#8)7$6VIE-0Z+"^J0:'(_%@=\.I[4F&>8O1@W.&ESDEW+PT>5G'B7W
-MRVJ.@)NNG\Y]MWP%..FJ,X\[7&]6NO:LJY]F+.6D)#:<LIU>9&)/V_*_]I^V
-M_4O$F4G*,Y.HYF$;XE?1D0I@HE-_4-)TM=4FL"[&K,GD/:C^,X3J_7I["-1O
-MMS,?1I[1*,^HZ?5@U"VS5=N/`LI`5E6;/G1*.G;8JM:!5;USTHU74(\.NOV#
-M/>B6`IZ5`O@$^MJYR)<`KD!=$OYKKO3?$,&>OU`K0.?5>_0ZQ=Q56KK>H,&-
-MND"">*1E@XG`8.SIMN%U;4[HL`2@<C9NTRY0^`:;C"*BEZX?O7R][>@,T$P+
-MUSH<B8_/+7ET6'7,8BK0')/36II8773,?[:(C:/@`I.@[.L!DX`\6=88>'2;
-M!\`4V)D=H(-H5-$LYEN@U$`($*!&VJF:OG!7@8?</0=U="9@`Z,V2GF&;]"J
-M-E.`#$C`[[%1AEC5TJV1+0THJYY(VZ+7QZKTL9&T2Q\;==SEI\6P_1?(9F=.
-M^O4<]":.P%Y;ET!O1,,$&DP7*!`\$LB2T+(J#@R:5F741BZK%[?4^ND$^)2$
-MM3H2YY@T.$E..WP@&?L6)F7>6M!Q#68-+A9/2VG[/+QOD[6FTD((4B\]I:_Q
-M.ER/1_0=6>=2]:T#Q4:O]JLU.K.RM*JH:AW,O+G&2^D"S9TVHP8W;_22[#DQ
-M_WE[&S8W>\F03N>\;V>R(OOR#]8I^_*&CI[Y%Z"!XN$%Z$)?Y;4\=*RVU71"
-MO,(CS>Z"*??X1'?6P.'Q[D/KBT9H86_L'1[(0:G'%PV-EVFQ?[]YUFV/G1'Y
-M]U38M=K;:_U\$DB[3J@-R8%:0OW:!S`&WX[HFZOJFP/NIF;>!G@^1_T#"2E[
-MR#;9WXDW_#)J`H[]4K;IM+4FJ^'Q5'144HG6T8KD)47*OEE[*MRNE!E/[)E`
-MKP>'E]P^7BR>[&A[*:KO.57?7RT__5G'#^.N>W0\76V&%GRR33[3\4QRNLAT
-M(E.?'#BW*-22''*DGTX'L:(<@3B#)`OQ#`MFH"TAVU9*]QH[XVF7&!VLQK'.
-M5EEF1Z9>Y-#7_-WP)3;V2"P39C'^<P"HJ4X9_X@`>K/P)^AWM17Z<JTLLB]%
-MV6>B#Y@<@177W=>H9*+\!W3B^D9>,C+#/_&H9,4RM!R^QW@3^2&FFDST'<#&
-M3/HZ(N7V^)2N3^V#33M\RCXIUL@SSE9A!E9SO#&L.=X>GO:V\FO9;<[CX"BV
-MO9,=H#_.T9_`C/_`15MQ(ZB.P96@-^AZ'XS_92/ZSJ)W1ZNR%R%__7"=5K9.
-MI&KNU$E[KCG!RNQRNNFEOP;HFSCZ9LST#YPN(K?A)J20_MHNT;*$FVLRD6'>
-MF-GR/%+&"4EX+#NH=4-R&VA@/_=9ELVAJ\&9O-AXO/$@CY\0UA="-]`W)4]Q
-M1-,XY5*A3N"H?G:!8!K*NFJ:L1I;49_Z[EZTPK9L1LQ*%,F>NS=L[B>A>D+T
-M3KV4+EQ:+VHL?Z<^L/&SQ@)J`[:R?IZQFD^`C?D$7_PA;OCTEY8-=F8[.A:C
-MP;_Z&FRL&4#9L8`W]_*3,<WA2?X5U]X]_W+%-1E4>;4T6SKW/?2A1TH5."JO
-MI3!E<&V7.%*+Z7\T?F;<@-D9)_*Y'3.VQ\5C?/Y4RK28=;4SD;[6\,)ZSRP#
-M!L<WJ7HK#U9']7K#>JO\F`$Y_-=QPGG7X3?UD9:^H!47^:K>-7E73?WDP31]
-MZRTP\.&]A:`T/-N,I1A8^*^>R[8-?[WRCR'U@)73MI:)+#H;]9X-?;W"G^I+
-M=AQ3L.C,/(3.#A;:PGM3)0B=[374^+]@>3Z\=UG==$.-MXMV['RR0H'.?O:^
-M71Y,[I.5RS?O0YO%TP-8V#-7WY!YTN4.<13-H9M">U^G5X_L?<VLX:U[O[Q:
-MX),)?+BR=ZYW/5K22_<VGD2;W%G>U)]$V2&EKHHB<XE`7R%-F9&^Y_X.5XS_
-M*Y>7_':W(*HW6=F;3"'1CBA4I/X\Y%))_)M>]SA4`#-S;58Y+W5W]*Y!(2,*
-MZYUFOBFHN%YZ[5Z,TC>,4<)ZI_S3=*2_LFUQ!&=E)8C'=+J1;@-@#NIN%O.L
-M?7`B?8UXR;]UE6)G7D4?M\S\%Q^W//!//FX)G77KR:&/6[ZF>U:S'[?TF@SW
-ML1^WV/3WL1^WV-#'+4\.3Y[)_VF+C?VXQ3XXAG;9!TN`?RP`"GN?67ET:8$\
-MK%="7W<&1_1*L%4\9>^3P$.;!]`^>U,ZQH3KBW#B-]S0/'1H/J^'ZL-79'/S
-MSE0@7&=HO5768]R("7_U;V=^6CG"(Z/K<T([70CC8?W9LH(1C2=-!/KTPJMD
-M-P,XC^0K[;?7>)5HWYZ;Q'D(/6;0-OOM=:Q,JWJE43T_@#T>T:L#,VG01IVH
-MP_?ZG?4H?47:D+-^7PR1MO'()O.R]A=/)1\=9V"_:0O<S+K#>88KMZT;_^BO
-M#R_BWN.O@WL&#OLI&,Y3!K#IC:9=W.-U0_N-F_TPZR,[L^>T+=!,;O(Y;._J
-M_8T,^>OI>FBE=))XG)SZ[=H2\-E7#/OLR7_PV9/S_-</#'0R]Y2`^BU-0)'1
-M!$<P=GQ@X&1'\C0*ZLF:Q/\/\I7>\-3S0^`PZ,Y>Z#`T%+>0FZD/G!20JM$.
-MD4JG#3ORKX,F0>OFP/SC_2F;[$PM(*&B#PS0.STJ,.33CU$TM@7X2/&38_6?
-M"N@9PB36IW?ZR7CE6'CJ=T,^O1A]$_('GSY6&VD?S(!6D^[UZ=%'#,/VF&6\
-M64S!T+F%GF7ZFDI5S]OL9M=^@"UTO<.UJWP-_8.RYRT0<:H4`PF7^'!S*8<U
-M55ZC3<!:*^_A.E#[['D*;/.P;)EM4KU-9K0%8YYX;'^\H^TO!ILBLN=]K#9^
-MZ><!XG*A:1<VLF?]G.H`<870<)`3T5,5V5.UM5RT%W^M/D#?APGWDF1%Q*ZM
-MXE:!X6"N\6!>$N<+.[/6;)./["G"3L<O[0X058H,9[$Y=("H2F2ZR0&L"K7;
-MF6\C>Z8<K+NSS6_JQ47#V_S@^&3[W*Y"7U[W+J;*EWJ8Z^QR^T`^1/YM_L'^
-M>[Y?/:&>]PPY/$SL?MC<IV=`/_<\D*VSJB464`6,52?9,%`W8-$%F5W<NNGU
-M/M`&YA+0!E0>`YI@UN_3YLT80Z>E.TS)DO`>HTG'-28'9:N-.CX@78_:[?![
-M/NS^M[',H7,$T6KZF-DA\8\BBWFY+Y+B)%EHSQCQ@[)";9Y&_'?)1B,Y483.
-MNFC)([@IEN-H>S.X!Z31M.TD/0,T)._Y\00Q>>F'=O(P?G2SZ?;M:'!H[O!L
-MPCT\FY#GO^9HB-."9<C$MI9IK%K\\'4TD^`C"%\83Y*34[[>:V?VTZ[]9J_&
-MJ_9HA<5HP67Y@>^2L0V\QW'22`;N$XC&R@,'2$?U*Q0TF#4I\!7\E7^$I[X<
-M@-'LT4*_*F?C_NM^_89/0/&F$4-;.Y/_3.@_$R[1:;+6L+^V3`/P`WU<G48.
-M<7BVG<D#*4H3#CE>]79F5[MD/\@4Q\Z8#%_^@HK$P7B*)\IRM<KNOAP-^`_W
-M(_^A7%NF6;HUV.\]T&W[]1Z-1^W5HK4U\!E0N3-(WW7OQ$;QZ/7*[IWD0^"$
-MJ"*[MZ&E>Y_?]4?0:=CUSVLKI^_"L:#L8R!WGC;_>C'XP1H6EZ$HS*^\T[9G
-M7,J,]^FBDRXJ5)J,V;YZ_K2Z(JR#SK>QZRZSF+]W5A_>T%Z]9Y-_[<52@X%Y
-M#PJ::@F5GDYVK'^:M?!T-6O@&_-M8M:Z*[M;5=WI1K6H4!VT3VBIUQGKM711
-MT#Z2[A%5CL]]?3-3'B5R)KI52]"72::.!&7WVV'=M.`7D>`"41#ECJ32YPL'
-M."O1L;?1I^J4W:];U:0GO&HD>)I5$0)&0-W(TN_G+448A-+?R%1VSW,415'I
-ME5'=+R_,@D2[]897'RIS7'_>()>><.G5(;4>(;NA^5H9O,[+4XD+IZ8TUN^9
-M+Q:^)'XLD>>1"A_'/?\8WI:SSL%2GA[[)Q_@567WS*CNYY#^^Z,/$(GT^.D_
-M^0!YD6:YE&J:KU?S@YSD=G_S_$(;U3Q_V4_H.ZG([HDF@`>MLNVM^B8`!L*]
-M(GUS)GN^\(_^P'MV)K\=$`/48!^<6?>XLMLH*9<)PQ0>55CW8O^@4:%B&#-5
-M]R+`2O;!HQ5A]">&T&#V7-ZBO#"#/-@^&$W7AW5'H:V'[LC\B#M;#R.'OEOM
-M#AWZ;O4_;SVPWZU:CW.&MA[VL%L/M]L/MBF[A2.[B2%_L`&!>'3FHIM[]]MK
-M<`GO?FD)OD&0_H08G%7VE`;Z#.@V](Q^/Z+K=TK#J[A&TQ[TH3N@TO"N']W7
-M_2<!3;H0_U%`^^!4M'!(9^2KHKK'N6554D?;?_B2]\PWS%<6JO0K!`M^?:B[
-M[:1_)Y'=1^RF3:WJDXM0@@(2J->Y<2ND52'=+L""[F_,G>H=!2>K#=O4V#5G
-M52C:21R1DOA"CM(^^##=I.SJC.I6Y8:;U43@9Z*&?>B3U[[(KJ_=/9XS%;TT
-M;=+Q[YD^H@:_,W^64#FH:E^",51!U\\:W&&4*RQRN?WV982IV'?PIB-AUN"M
-MX3?'[_W;!;FCZ6H3P4G&<,,V#K:>A[6$"QHX2^NN^75RX#!6_#&RJW9DU\^'
-MJIQUPBU<80ZGK,YX#'\G;41$U\;(KAL`S<2U0Z!,='84T-78$_09'A3TE.5;
-M'*:776LQO.)2=O5'=9V/Z+J@ZG*'=:TU]Z5K*R(D/HZQB/T,<A]')'K*N!:'
-M*IQI99[PKFYW69E[R+<B0KLZ([K>&]'UGL0LXW<1E:&D2=3@X_L(K]P<7K+]
-M2V^(Z4N.@789Z2(!^JP?-]+%)GJ-8)^,W(='[Q>(:B.,A",I\.]EP=;756ND
-M5;)O%@5WM>2$Y`8;JK&8B=VB6BI7FA0X,U<FVDKEA1I#><;F".14V;`W#H?D
-M*0R):N/]:K*62@J<3A\C?./,?Z%V36F8V3#Z[0FG&Y84R@M"G2&[!NJ=[I#*
-MT-2+U4-V#>U8HK$,[TJ"=I(X.>PJ]BSFUY%=,^F#^GJ\91M9@9/D4Z:/<!*-
-ME:IK1E17.0P.0B'#7X?ZYRNBZ[&178^SAT[3]8WXFSL#X16:3'E72617J;*K
-M5+R=8]Z=+G!S!(*GJ"]PD(OBK[2M]PW-)WV63@SMFM">H%<'*KK&L,<Z?IB'
-MC@=G1W0YR0>!P8Q-/QJ:;IH?QI>O?VA7K:7I9T/SS95;`@Q-/T%D^1;CH2JP
-M#O!$$1QB*XXYPX5.KJ'Y1WB)Q'QVNH#A6-D/!,5G1\7HGE^V+]3:]).^Z6?1
-M#E+B(8,\I%"O:"E+QGXD]I`"2I&2=IDN%I["A<*G]'_!V8[F4$9MX+)Z\-A>
-M,6FC4KYV^'D_L%5@;LI:^!T0>PRD(++K08>K1=D55%GD=EG5Q-HU8G2\PZE&
-M*P\E5C6_O-10RK>N)6+8LQ?F)G#=U>;F3/_ZHK_*C:V&IBRZ#+FMF-O0E.FH
-M+J9_4791D5W42-^-,-\/E>L]U=GJM9N\'ZS=X'Z?78#"P;>FFC+10G:>FFK.
-MM.H"8V+PY:?P@%FXX[,](WQ=_VP?!(8J9><Y^Z`;2%%V<=AQPN^,$PC,2-_O
-M^H=Q-+.ST]'"U9RA>4<?:OM^-+&OS+/3D2J;,P3QAN8TPO>%WSN*]#4NWBG4
-M'L-Q/T\H?8.D'AS"L*[@W#3G*N$6CKXY??DJ;G9=:S%Z']$5!$(\)'7?(JG+
-M<6D[32`\99W^NHF0+DSNJXWH"J"=H5U<780TV+?Y5()AXB*L.JM,BKER/$K]
-M;&Q!SE.2*EE`I1"_35AZ,"XCE`S(>`.$X?A\XW6*:"%%SK&Y/?4>N-7F"/:1
-MU'5]>8_Q^`+#B?FB(Z2@=JRS5RB<#'?"2;I[M]8:3BRH+P-@5Y8\O*ZB\/5#
-M5T)\YX)]W<[$+:./%,QB3M*T(?ZF,?['BD1@,BK^)TO\SZ*=I&"`E`R0019%
-M,@:FDOC,'^47)/@STS,B?4L.+30?PZ-\2V#HEZ]_F(K_V52#&;;Q#&-O+LL.
-M,,3_!)'E6YZ$"*;A(29/"@\$)A_[(Z0CZW,C7>#A^+<8H`90GH`?EV^)'-I$
-MOI$.I;#GPP-KN<0]V>HNE2>T[FXY2#8A2`EIVD\8RXUT?(!SG+8,9_I/?T/&
-MKZ>A_T_0HWB4D%H5:?V->2UC1:3O/=(BV^'+/9;3IO+]9?GZ!YSM>=6[:LO:
-MEF5S<XZ7M2W?\FS.<2"DHQJ;$"[Q<,N.&4ZP?[Z@+UWHY`"K4<.:99A^G9]^
-M8Q^B_SAM>!C''@R7^+CB?1PCFY=`]!VGAR$[HJ_#IO!IZ32PT<#T>L3T/`^A
-M+T9K2R[_VI*??I4O@C3*=GRBK\FBB,GLV8A,4TTF/<I!OQOI>U;ADV__%'7E
-M$+-\_8/^G@"YR[)Y.<?A_K^D+X'(0:';8FQ\RH:%=5X1/"87.@DJ?4IGHB@-
-M&]EYF7Q"MK567Y,A_)M(OS'#WR]_F;#.7B@#)>\I$-'934Z3;=MG:,@@GA<9
-M=F>P-I!>11ID$9VG1G:>V`9U96TU&NL2N!X!.@;A#']G%5];DX''BX;W)P*-
-M!.90)X?ZJ$QI<&>+#ES83P3&[8/&!HMA^Z`H[.&Y:QZ=6_S4O**D9.PIM+OV
-M(/)9#34&<UT103QIJG,9MMT0L-]EO77X05-=L;ENC?]QV6&+T8#M&:V;SGGC
-M\2W`D*F?3PWQ2>W,/J@FYOX+=J8AAG#8F6UF@A!^.][.O+_H)5%`@<+Z("?F
-M9I'EIFO13A'A5.@?Y!A*UE`EQ;PG\%F#(^S,EN'B;[+\H>R\%=[Y._ZX0K]1
-M-O3G,]+EN/`1B4>&SAV-#J>CP9YHPX5:+I[.479>XVIQ;9;<O^:NINOHQ"SI
-MB,[\0_]1(E-TYB5CHWS5KZWG1W9FY;>)MY.=R2,[SX5W'E%UKB).4T&O@;J]
-M;VMM!UK7/&YSV+).)!IM2/<;WDC/DRUK>26R<XGX[X3YN"[@>5S4AK57.ZPG
-M#%H.D:/@U7(<#]68XCEDGH+7RB&/XLL:UR1CC[=+4JLD,2]P``"G5/U`)YZJ
-M3MUT-;)S#EWGK^AT(EO/(0:;P:-[L8%PR0"W4F9G/H`R6"*/$(8A=[+.SBQ]
-MK9$_LO-ON76BHR10%-'I577N)O=3D9V[=[16'+,S,>QX174FJCIG!'?6RSL;
-MZ#:Z,1D3MTL,-Q.LMSB6R](W>E\R]F6MC`\'U_>UAO/@"`B(^EH_;%N>^YV=
-M&6B7Z/LRQ9_("*/"\?EAPO#PX0UUM5[7+D_+MKK-[#W#7(KI*W@B`]KJVT)Z
-M7=XB<REN+N4"3+4SI2,[XTV[T]#"Q^Y5P_CE87FG01_>1!'F\,ZXD9VNX,XB
-MR!`=;T82!IQ8C8E$"2+W!"I&-:\&)#MK%C,CI#,CO#/1>/\%XGY.$@\S:E3$
-M/JJ]NCPQB=O;69V;2%>3^P1)W)Z0SN46#1[9^3IO`!<_2%EB</-S6!+W))MG
-M/9OG.T7GF_0--M=BR7`N;T(2]VO(E$#7;-N7Q/W*`([A+K";[(>P>!*W#U@Z
-MK',V_:VR\^6HSKFJSKD1G7-'=CZ4J=:58+H2GJY$()I)Z4K(@(#`;2_L>''G
-M2YMGZI[=:GYVF^[F)?/-R[JS1O-9D_G@?-W!5^V,&8V#@;`9">XLY@EYYU\.
-MK*<_I.]7=DZ)Z)QRP*5O#D4#DC5B%O,(/3VRH]MBOG7@NK4?I9K;E+K^$8ZV
-M+P[4`$!G'O#?)C3MI.LIR%6LST*Y=*CL?<AZ$.L/?4B?;.JC!TWF6TV%%%NU
-MM7E$5,<5"QLW-X\X<*(Q/;IY2*`,37)1+8?MO*%9WO@^_:&?'*H9[5@8A[-9
-MFN3HK]@TR]DJ4`9#\P@#43.+"0WKC*8_;CK:^*W!?,M"U%@VLLUL9'=JV+B1
-MC>LW2H])#M2P8R"T,V/0F,@[O@_N5$1V*L([0U2=(1&=(70"_>S(CO[0CDJ*
-M$,0B;#"Z6_W&43Q02X[HZ.''45N7[GAG^QNU2ZRQ:=:U&=$9.=$3.3$9>;J,
-MW+C8RKA8KRZV2GN+$]7!!'=RH8H%.:..7TN%\@P9UM$F9*BM/^_X9?NOM8RV
-M-"TZ,Z-^=,SB/-WB7.WB'%UIE;6TTEKJK;?2ORH[?@SK^%S5<3.BHRF\XR8Y
-MGQK9\0,I#MQ\LO;TUH[*.OT'&=:,G*B.JZJ.JW21/B.7_L``1.R.(@=(R^Y(
-MRV[5R([O=W:3^TAEQ\7PCHNJCN]K3^_P41M;=#]B,=]LTWVS5?=-K7%COW'C
-M.=W&\\,V1-G1R^JXX+".SU(+@Q<(1&B@O8.&FN#4G3P[<Z5=(N\X%=[QG+)C
-M-YOQ0;I>L&<"M4$)3^DQ#O4BNFY$1UU4!ZWJH!4=;;2-?C:O.K*CN$(:T?'9
-M`OVTTW4?[@Y\%7_CU1!E1][;1WFY4M&KI&`/I7]R<).3*N5T5(=U9"UCT[>2
-MPKU4_=;MI4%N@<0CH$J]%/K31FG1I571CMP81UY8Q]KPCOM,WMNF)C$Z8A*A
-M:/D:Z93`^GTH?L#.W``?N,GBO5U>`P:*7@4FJL[I?A](+;P"EP*T*I_O"A(^
-MM?*[\)$=:F&DPMQYP?R!SOQ!C/D#K?F#:-,NM.9JK;A@61]C_4!G_4!K^2!Z
-M>*SD'6\J.S)9(MX:V;$XHN/-R(XWZ,28$Q14&].L1]?=!G3=:!R"5L4!P1T"
-MH9.DQF*SF`V*CFPD.I.CHSJR>,\J2I#\6&_$J#I65Z&3W`57%!TO!+VHL(P-
-MF,7,G,5(D-[M>+>QS@QL_AMC.?$`FIM1N.G$_4.*8PR>A'\S:_#`K$$OJNK)
-M6S$_F6<-_GWHK$!PQ\(,6\SDIUN?BPZ?_OY?8AY].F-&XT.+[^<>LAZ3!#Q"
-M%,?7/[)FQEULI.RP.]-BTI\^DOC>C+HE<Q:%!"V5[7$&9`F<R7$K&(`(L?-O
-MO9QZ/3,QY26?LB,I)XVJD;2L@O33:C"BLRY]*>UXM@@KYJS!2[BR#ENZE/.]
-MK4;&N3:*3N"=#<5P3-;Q9+HT^@D,;&:Q5-:AHC7%4M[941G<U6!+5Z'O3CG1
-MZ&\B2CNFW*TG:KB>Z_?4\T"Z-/AT!UO/O16TVSBCV?)CBK!5G!3IXZOP%.F4
-M5=ROHX9K(X=KNW%/;7&HMDM_K(V6%G&+\")4ZS<VSB.02^,">_.SM$-]ES95
-MNA0Z<MJW6CK4I9'R#EFQ]&[-,E3SB?]$Y[<V#OI[H>F*U2$9H9DC-!&+.`IL
-MZ*^`EH2N'8%?L"7#^V*EO(//K;?A_:'1H9@VE`,9Y1T\#HYQ=3A/)YPO#2*Y
-M-G$@%GF:*516@*:T!6&VBC"28ZL,KQ@IOD7DT1S5_U/9\<<T<87?O7=7M+WV
-M6J"-Y>?UKMM0?O0=12M$+5!TD&WJ$/`/3:C6JJ1*45C4N>D$=<,)(J`3E<TL
-MF5F6F=B8+?MO11)UD2QE+L:[L"AJ2)R)`;=LR>+2O6NA_AC@UC^:][[W_7SW
-MW?O>NUZ_#UX;X,*@P]J9=BQ=#R4#D#A*ZDQF+<"`I$QEW*A,Z(FRD;DQ/VA]
-MNVTU')-::P[6J7)"4EOMH;4`S98W,I@CI2NC:<HHFV=BOV+G?YXQY,X]GV$_
-MGZGK9\.\OKN8W%/B<X#$^RPC9#^J\.NBC^)YP#3!?'>&$DE7KAL6F'2YVNM%
-MK1??*[;T7&0=;/B.5;F>J0QQ=Q=?N-`7(3P3X"N9RI5)<)PS.T@.XX.$?SO_
-M4>ZEOCY^3[NN??Z1!==Z3_,7SYR9?]1^]?:UP7X[8:)F!`4_3-H"X5VLZ@'A
-MO=@S()BJA)(LH*WT<!E<"$^4:FHIYKZ4%$L0JOY+.IZ_4_GR*0ZL1=.AJ7AH
-M#%\MA="#*BA8`>DQ"4$/08C)28PQ'N85-H[!%)4\@S2I7XQG;"\/;_"I2CN1
-MW%IVJ+2G##TC<YA+ED=3%&T/'S913].;@G$)3$C@L21HSQ$#3<K>%&4O&I-2
-ME;UD7,U*JNS1JEE);V*3/$P_PG8+\D6?4#X"2E;\<4_L,7:;5#]4-C[KAUG*
-M%NXN9N_CCE$V2A&O[$_9-+[G;'+W/.&O*!NEL^5;($QSG)43$'>/N)WWZR']
-MD*[C\K$[_:/Z*,7=5U7D-$`/,0=POU5/X<_2^M,[PK>-G0-<Y$7_S5+>X"R@
-MX\[1%%7L+Q1AX1]/:YUW=C0O&9)SJ5%9DJD4LTB:<FU]E,Y2/!=&#$.ZSD$8
-MI0Q1*DLI\4<W9LLA$*$YO?78H/Z>Q`E0+Q"C_;`2AP3`TZ@*(V@E&_\M^'N$
-MZLFM#)$&.BGDIH%$0VB%51+!%?*RD<BBV$3#*KR)?W>_8\X^A_5]1XD7'!'/
-MCO?B$]+)PD^<T))*S2&!=40<2<#$];^W87')G5.X3SI=>,8)%Z1"%><[@ID_
-M,MX5.3[<_5//#3&#H.6/&,4ED2G*4T5]"Q<LTN0N2N+FT'!9*E+)#A`RHA(Y
-M2(9MY*A"%%2O/A_APK8(QPDF(8]"E;C)H1.71$FWZ;4_$/(08X!H0L(\"%<1
-M"H3P93YA45B(3/J?1?Z-&<,_`TTU%1+BSK@F^DVDE'G&+\WR!7(4PE\X:;=:
-M;XH53#3MH07H=S\4M<BNG0,9#SEK(,:ZOUX'RU,O5OA7/8R]DV8;YLSRIV&U
-M9-=TU&%GN')ZVKAM,=F=,\E6>7\X(^](_%XVR_LFZ5W3T>^:HO_7:(*^<29Z
-M49OV4MOK9^0_4#*[[9.YA,WR2HO\<:+LF.VY_,?_I0:965Y&-)BI`EEL&4I\
-MS++3(N_X?S7.S/*KL_"?O(:9*L^9%3#+YEEY/,WW3'AI+7)50L7L:>;C!G>#
-M>U[;L82V+]A[ZT^+[$HP2WXYO6J/)D7.[3&V&@4!;.7-!XWV<J`K!8>-9#=U
-MTGC(>&AUP^H'L5@8$Q;+%6[+R`%J+NXG@$1@3"-\J1"&I)`3P3+H9,5"$D[5
-M9Q%H<`V-),H,`XL]@2(^4&@(2`R@R+2TV-8W>4%CP,G8JFDO\-NJ&2^H#RS2
-M!Q82B,8+UAQ8ZP4K`RY&LX&@+T_:0;[=@9*L0+%^OYL>_L`+I+G'"2Q7[9WS
-M`E$7(KW,?6[#?C?##I"V2:^^1J,C7<,H:4!N`E+(\^-287V37=O$I+`MS@*4
-MUT7G=Z&,7CJS%Q5TT8XNE-5+9_>VUK35'JR+[2L`#9")]46OJM>CEA6K>7NU
-MK:>FMU:L%NS58D]=[UI?]-MX[/LU'IN'[&A<\@)#4&#0!&DP09%!CR4PM?X,
-MV>$X)I&=C,.)6$.DX6,\M>>`@G:R)F".JS3'59'CJLQQO1FO[Q>/_?'??V!C
-M8?%-G@G2M)MN66=G*EA0ILZZ0&BK],T^&FUF0P)90%%*:K,/DE55E=#LH\(V
-M(O-:0IZ:<WS=`^TPIP6>K?YMS0U!?L5:OF)Y>>WK2S&?4_Y.P[86?L7.!OZM
-M#7MXOHB77"6XN,2YB%]=4<,78NSB@XW\9O^VAMT%&YH;?)O\S0U;&OT[FPM\
-MP>TECJW![7Y';-2QR[%Y5WU1`:YO\N_</#^/KR-(#82VQKE[-X\Q&9$*,.;S
-6>8ET,/DRTA1`S>E__P.PN$K4G'$`````
-`
-end
diff --git a/sys/dev/cxgb/t3fw-4.5.0.bin.gz.uu b/sys/dev/cxgb/t3fw-4.5.0.bin.gz.uu
new file mode 100644
index 0000000..0b24037
--- /dev/null
+++ b/sys/dev/cxgb/t3fw-4.5.0.bin.gz.uu
@@ -0,0 +1,442 @@
+/**************************************************************************
+
+Copyright (c) 2007, Chelsio Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Neither the name of the Chelsio Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$FreeBSD$
+
+***************************************************************************/
+
+begin 644 t3fw-4.5.0.bin.gz
+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
+*%P!M0DW?O%L`````
+`
+end
diff --git a/sys/modules/cxgb/Makefile b/sys/modules/cxgb/Makefile
index cd2081e..843f652 100644
--- a/sys/modules/cxgb/Makefile
+++ b/sys/modules/cxgb/Makefile
@@ -15,12 +15,28 @@ CFLAGS+= -DCONFIG_CHELSIO_T3_CORE -g -DCONFIG_DEFINED -DDEFAULT_JUMBO -I${CXGB}
.if ${MACHINE_ARCH} != "ia64"
# ld is broken on ia64
-t3fw-4.1.0.bin: ${CXGB}/t3fw-4.1.0.bin.gz.uu
- uudecode -p < ${CXGB}/t3fw-4.1.0.bin.gz.uu \
+t3fw-4.5.0.bin: ${CXGB}/t3fw-4.5.0.bin.gz.uu
+ uudecode -p < ${CXGB}/t3fw-4.5.0.bin.gz.uu \
| gzip -dc > ${.TARGET}
-FIRMWS= t3fw-4.1.0.bin:t3fw410
-CLEANFILES+= t3fw-4.1.0.bin
+FIRMWS= t3fw-4.5.0.bin:t3fw450
+CLEANFILES+= t3fw-4.5.0.bin
+
+t3b_protocol_sram-1.1.0.bin: ${CXGB}/t3b_protocol_sram-1.1.0.bin.gz.uu
+ uudecode -p < ${CXGB}/t3b_protocol_sram-1.1.0.bin.gz.uu \
+ | gzip -dc > ${.TARGET}
+
+FIRMWS+= t3b_protocol_sram-1.1.0.bin:t3bps110
+CLEANFILES+= t3b_protocol_sram-1.1.0.bin
+
+t3b_tp_eeprom-1.1.0.bin: ${CXGB}/t3b_tp_eeprom-1.1.0.bin.gz.uu
+ uudecode -p < ${CXGB}/t3b_tp_eeprom-1.1.0.bin.gz.uu \
+ | gzip -dc > ${.TARGET}
+
+FIRMWS+= t3b_tp_eeprom-1.1.0.bin:t3btpe110
+CLEANFILES+= t3b_tp_eeprom-1.1.0.bin
+
+
.endif
OpenPOWER on IntegriCloud