diff options
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/dev/cxgb/common/cxgb_ael1002.c | 10 | ||||
-rw-r--r-- | sys/dev/cxgb/common/cxgb_common.h | 71 | ||||
-rw-r--r-- | sys/dev/cxgb/common/cxgb_mc5.c | 10 | ||||
-rw-r--r-- | sys/dev/cxgb/common/cxgb_t3_hw.c | 304 | ||||
-rw-r--r-- | sys/dev/cxgb/common/cxgb_vsc7323.c | 340 | ||||
-rw-r--r-- | sys/dev/cxgb/common/cxgb_xgmac.c | 117 | ||||
-rw-r--r-- | sys/dev/cxgb/cxgb_adapter.h | 16 | ||||
-rw-r--r-- | sys/dev/cxgb/cxgb_config.h | 1 | ||||
-rw-r--r-- | sys/dev/cxgb/cxgb_lro.c | 24 | ||||
-rw-r--r-- | sys/dev/cxgb/cxgb_main.c | 281 | ||||
-rw-r--r-- | sys/dev/cxgb/cxgb_offload.c | 10 | ||||
-rw-r--r-- | sys/dev/cxgb/cxgb_offload.h | 2 | ||||
-rw-r--r-- | sys/dev/cxgb/cxgb_sge.c | 88 | ||||
-rw-r--r-- | sys/dev/cxgb/t3fw-4.0.0.bin.gz.uu | 483 | ||||
-rw-r--r-- | sys/dev/cxgb/t3fw-4.1.0.bin.gz.uu | 482 | ||||
-rw-r--r-- | sys/modules/cxgb/Makefile | 16 |
17 files changed, 1489 insertions, 767 deletions
diff --git a/sys/conf/files b/sys/conf/files index 44301a7..9db5573 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -519,6 +519,7 @@ dev/cxgb/cxgb_l2t.c optional cxgb pci dev/cxgb/cxgb_lro.c optional cxgb pci dev/cxgb/cxgb_sge.c optional cxgb pci dev/cxgb/common/cxgb_mc5.c optional cxgb pci +dev/cxgb/common/cxgb_vsc7323.c optional cxgb pci dev/cxgb/common/cxgb_vsc8211.c optional cxgb pci dev/cxgb/common/cxgb_ael1002.c optional cxgb pci dev/cxgb/common/cxgb_mv88e1xxx.c optional cxgb pci diff --git a/sys/dev/cxgb/common/cxgb_ael1002.c b/sys/dev/cxgb/common/cxgb_ael1002.c index 3d67b06..c570ed3 100644 --- a/sys/dev/cxgb/common/cxgb_ael1002.c +++ b/sys/dev/cxgb/common/cxgb_ael1002.c @@ -277,7 +277,13 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, unsigned int status; status = t3_read_reg(phy->adapter, - XGM_REG(A_XGM_SERDES_STAT0, phy->addr)); + XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | + t3_read_reg(phy->adapter, + XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | + t3_read_reg(phy->adapter, + XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | + t3_read_reg(phy->adapter, + XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); *link_ok = !(status & F_LOWSIG0); } if (speed) @@ -323,5 +329,5 @@ static struct cphy_ops xaui_direct_ops = { void t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { - cphy_init(phy, adapter, 1, &xaui_direct_ops, mdio_ops); + cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops); } diff --git a/sys/dev/cxgb/common/cxgb_common.h b/sys/dev/cxgb/common/cxgb_common.h index 1a04772..0a60a56 100644 --- a/sys/dev/cxgb/common/cxgb_common.h +++ b/sys/dev/cxgb/common/cxgb_common.h @@ -38,18 +38,19 @@ $FreeBSD$ #endif enum { - MAX_NPORTS = 2, /* max # of ports */ - MAX_FRAME_SIZE = 10240, /* max MAC frame size, including header + FCS */ + 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 */ TCB_SIZE = 128, /* TCB size */ NMTUS = 16, /* size of MTU table */ NCCTRL_WIN = 32, /* # of congestion control windows */ NTX_SCHED = 8, /* # of HW Tx scheduling queues */ - TP_TMR_RES = 200, /* TP timer resolution in usec */ + PROTO_SRAM_LINES = 128, /* size of protocol sram */ }; -#define MAX_RX_COALESCING_LEN 16224U +#define MAX_RX_COALESCING_LEN 12288U enum { PAUSE_RX = 1 << 0, @@ -58,7 +59,7 @@ enum { }; enum { - SUPPORTED_IRQ = 1 << 25 + SUPPORTED_IRQ = 1 << 24 }; enum { /* adapter interrupt-maintained statistics */ @@ -70,8 +71,32 @@ enum { /* adapter interrupt-maintained statistics */ }; enum { + TP_VERSION_MAJOR = 1, + TP_VERSION_MINOR = 0, + TP_VERSION_MICRO = 44 +}; + +#define S_TP_VERSION_MAJOR 16 +#define M_TP_VERSION_MAJOR 0xFF +#define V_TP_VERSION_MAJOR(x) ((x) << S_TP_VERSION_MAJOR) +#define G_TP_VERSION_MAJOR(x) \ + (((x) >> S_TP_VERSION_MAJOR) & M_TP_VERSION_MAJOR) + +#define S_TP_VERSION_MINOR 8 +#define M_TP_VERSION_MINOR 0xFF +#define V_TP_VERSION_MINOR(x) ((x) << S_TP_VERSION_MINOR) +#define G_TP_VERSION_MINOR(x) \ + (((x) >> S_TP_VERSION_MINOR) & M_TP_VERSION_MINOR) + +#define S_TP_VERSION_MICRO 0 +#define M_TP_VERSION_MICRO 0xFF +#define V_TP_VERSION_MICRO(x) ((x) << S_TP_VERSION_MICRO) +#define G_TP_VERSION_MICRO(x) \ + (((x) >> S_TP_VERSION_MICRO) & M_TP_VERSION_MICRO) + +enum { FW_VERSION_MAJOR = 4, - FW_VERSION_MINOR = 0, + FW_VERSION_MINOR = 1, FW_VERSION_MICRO = 0 }; @@ -116,10 +141,11 @@ struct mdio_ops { }; struct adapter_info { - unsigned char nports; /* # of ports */ + unsigned char nports0; /* # of ports on channel 0 */ + unsigned char nports1; /* # of ports on channel 1 */ unsigned char phy_base_addr; /* MDIO PHY base address */ - unsigned char mdien; - unsigned char mdiinv; + unsigned char mdien:1; + unsigned char mdiinv:1; unsigned int gpio_out; /* GPIO output settings */ unsigned int gpio_intr; /* GPIO IRQ enable mask */ unsigned long caps; /* adapter capabilities */ @@ -271,11 +297,13 @@ struct tp_params { unsigned int rx_num_pgs; /* # of Rx pages */ unsigned int tx_num_pgs; /* # of Tx pages */ unsigned int ntimer_qs; /* # of timer queues */ + unsigned int tre; /* log2 of core clocks per TP tick */ unsigned int dack_re; /* DACK timer resolution */ }; struct qset_params { /* SGE queue set parameters */ unsigned int polling; /* polling/interrupt service for rspq */ + unsigned int lro; /* large receive offload */ unsigned int coalesce_nsecs; /* irq coalescing timer */ unsigned int rspq_size; /* # of entries in response queue */ unsigned int fl_size; /* # of entries in regular free list */ @@ -354,6 +382,7 @@ struct adapter_params { unsigned short b_wnd[NCCTRL_WIN]; #endif unsigned int nports; /* # of ethernet ports */ + unsigned int chan_map; /* bitmap of in-use Tx channels */ unsigned int stats_update_period; /* MAC stats accumulation period */ unsigned int linkpoll_period; /* link poll period in 0.1s */ unsigned int rev; /* chip revision */ @@ -430,7 +459,10 @@ static inline unsigned int t3_mc7_size(const struct mc7 *p) struct cmac { adapter_t *adapter; unsigned int offset; - unsigned int nucast; /* # of address filters for unicast MACs */ + unsigned char nucast; /* # of address filters for unicast MACs */ + unsigned char multiport; /* multiple ports connected to this MAC */ + unsigned char ext_port; /* external MAC port */ + unsigned char promisc_map; /* which external ports are promiscuous */ unsigned int tx_tcnt; unsigned int tx_xcnt; u64 tx_mcnt; @@ -589,9 +621,6 @@ static inline unsigned int is_pcie(const adapter_t *adap) } void t3_set_reg_field(adapter_t *adap, unsigned int addr, u32 mask, u32 val); -void t3_read_indirect(adapter_t *adap, unsigned int addr_reg, - unsigned int data_reg, u32 *vals, unsigned int nregs, - unsigned int start_idx); void t3_write_regs(adapter_t *adapter, const struct addr_val_pair *p, int n, unsigned int offset); int t3_wait_op_done_val(adapter_t *adapter, int reg, u32 mask, int polarity, @@ -627,13 +656,14 @@ 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_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_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); void mac_prep(struct cmac *mac, adapter_t *adapter, int index); void early_hw_init(adapter_t *adapter, const struct adapter_info *ai); -int t3_reset_adapter(adapter_t *adapter); 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); @@ -641,6 +671,7 @@ void t3_set_vlan_accel(adapter_t *adapter, unsigned int ports, int on); 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_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); @@ -657,7 +688,7 @@ int t3_mac_disable(struct cmac *mac, int which); int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu); int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm); int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]); -int t3_mac_set_num_ucast(struct cmac *mac, int n); +int t3_mac_set_num_ucast(struct cmac *mac, unsigned char n); const struct mac_stats *t3_mac_update_stats(struct cmac *mac); int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc); @@ -718,6 +749,16 @@ int t3_sge_read_rspq(adapter_t *adapter, unsigned int id, u32 data[4]); int t3_sge_cqcntxt_op(adapter_t *adapter, unsigned int id, unsigned int op, unsigned int credits); +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_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); + void t3_mv88e1xxx_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, const struct mdio_ops *mdio_ops); void t3_vsc8211_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, diff --git a/sys/dev/cxgb/common/cxgb_mc5.c b/sys/dev/cxgb/common/cxgb_mc5.c index 9d3b94f..07a4d39 100644 --- a/sys/dev/cxgb/common/cxgb_mc5.c +++ b/sys/dev/cxgb/common/cxgb_mc5.c @@ -31,9 +31,11 @@ POSSIBILITY OF SUCH DAMAGE. __FBSDID("$FreeBSD$"); #ifdef CONFIG_DEFINED -#include <cxgb_include.h> +#include <common/cxgb_common.h> +#include <common/cxgb_regs.h> #else -#include <dev/cxgb/cxgb_include.h> +#include <dev/cxgb/common/cxgb_common.h> +#include <dev/cxgb/common/cxgb_regs.h> #endif enum { @@ -328,9 +330,9 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, unsigned int tcam_size = mc5->tcam_size; adapter_t *adap = mc5->adapter; - if (tcam_size == 0) + if (!tcam_size) return 0; - + if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size) return -EINVAL; diff --git a/sys/dev/cxgb/common/cxgb_t3_hw.c b/sys/dev/cxgb/common/cxgb_t3_hw.c index ac4a630..2e92187 100644 --- a/sys/dev/cxgb/common/cxgb_t3_hw.c +++ b/sys/dev/cxgb/common/cxgb_t3_hw.c @@ -30,12 +30,17 @@ POSSIBILITY OF SUCH DAMAGE. #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); + #ifdef CONFIG_DEFINED #include <cxgb_include.h> #else #include <dev/cxgb/cxgb_include.h> #endif +#define DENTER() printf("entered %s\n", __FUNCTION__); +#define DEXIT() printf("exiting %s\n", __FUNCTION__); + + /** * t3_wait_op_done_val - wait until an operation is completed * @adapter: the adapter performing the operation @@ -119,7 +124,7 @@ void t3_set_reg_field(adapter_t *adapter, unsigned int addr, u32 mask, u32 val) * Reads registers that are accessed indirectly through an address/data * register pair. */ -void t3_read_indirect(adapter_t *adap, unsigned int addr_reg, +static void t3_read_indirect(adapter_t *adap, unsigned int addr_reg, unsigned int data_reg, u32 *vals, unsigned int nregs, unsigned int start_idx) { @@ -202,7 +207,7 @@ static void mi1_init(adapter_t *adap, const struct adapter_info *ai) t3_write_reg(adap, A_MI1_CFG, val); } -#define MDIO_ATTEMPTS 10 +#define MDIO_ATTEMPTS 20 /* * MI1 read/write operations for direct-addressed PHYs. @@ -219,7 +224,7 @@ static int mi1_read(adapter_t *adapter, int phy_addr, int mmd_addr, MDIO_LOCK(adapter); t3_write_reg(adapter, A_MI1_ADDR, addr); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); + ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) *valp = t3_read_reg(adapter, A_MI1_DATA); MDIO_UNLOCK(adapter); @@ -239,7 +244,7 @@ static int mi1_write(adapter_t *adapter, int phy_addr, int mmd_addr, t3_write_reg(adapter, A_MI1_ADDR, addr); t3_write_reg(adapter, A_MI1_DATA, val); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); + ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); MDIO_UNLOCK(adapter); return ret; } @@ -262,11 +267,11 @@ static int mi1_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, t3_write_reg(adapter, A_MI1_ADDR, addr); t3_write_reg(adapter, A_MI1_DATA, reg_addr); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); + ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) { t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3)); ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, - MDIO_ATTEMPTS, 20); + MDIO_ATTEMPTS, 10); if (!ret) *valp = t3_read_reg(adapter, A_MI1_DATA); } @@ -284,12 +289,12 @@ static int mi1_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, t3_write_reg(adapter, A_MI1_ADDR, addr); t3_write_reg(adapter, A_MI1_DATA, reg_addr); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0)); - ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20); + ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) { t3_write_reg(adapter, A_MI1_DATA, val); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, - MDIO_ATTEMPTS, 20); + MDIO_ATTEMPTS, 10); } MDIO_UNLOCK(adapter); return ret; @@ -435,27 +440,32 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) } static struct adapter_info t3_adap_info[] = { - { 2, 0, 0, 0, + { 1, 1, 0, 0, 0, F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, 0, &mi1_mdio_ops, "Chelsio PE9000" }, - { 2, 0, 0, 0, + { 1, 1, 0, 0, 0, F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, 0, &mi1_mdio_ops, "Chelsio T302" }, - { 1, 0, 0, 0, + { 1, 0, 0, 0, 0, F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, &mi1_mdio_ext_ops, "Chelsio T310" }, - { 2, 0, 0, 0, + { 1, 1, 0, 0, 0, F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, &mi1_mdio_ext_ops, "Chelsio T320" }, + { 4, 0, 0, 0, 0, + F_GPIO5_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO5_OUT_VAL | + F_GPIO6_OUT_VAL | F_GPIO7_OUT_VAL, + F_GPIO1 | F_GPIO2 | F_GPIO3 | F_GPIO4, SUPPORTED_AUI, + &mi1_mdio_ops, "Chelsio T304" }, }; /* @@ -472,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 }, + { NULL, 0, NULL }, { t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE, "10GBASE-XR" }, { t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ, @@ -656,6 +666,8 @@ static int get_vpd_params(adapter_t *adapter, struct vpd_params *p) } else { p->port_type[0] = (u8)hex2int(vpd.port0_data[0]); p->port_type[1] = (u8)hex2int(vpd.port1_data[0]); + p->port_type[2] = (u8)hex2int(vpd.port2_data[0]); + p->port_type[3] = (u8)hex2int(vpd.port3_data[0]); p->xauicfg[0] = simple_strtoul(vpd.xaui0cfg_data, NULL, 16); p->xauicfg[1] = simple_strtoul(vpd.xaui1cfg_data, NULL, 16); } @@ -847,6 +859,64 @@ static int t3_write_flash(adapter_t *adapter, unsigned int addr, 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) +{ + int ret; + u32 vers; + unsigned int major, minor; + + /* 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); + + major = G_TP_VERSION_MAJOR(vers); + minor = G_TP_VERSION_MINOR(vers); + + if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) + return 0; + + return -EINVAL; +} + +/** + * t3_check_tpsram - check if provided protocol SRAM + * is compatible with this driver + * @adapter: the adapter + * @tp_sram: the firmware image to write + * @size: image size + * + * 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) +{ + u32 csum; + unsigned int i; + const u32 *p = (const u32 *)tp_sram; + + /* Verify checksum */ + for (csum = 0, i = 0; i < size / sizeof(csum); i++) + csum += ntohl(p[i]); + if (csum != 0xffffffff) { + CH_ERR(adapter, "corrupted protocol SRAM image, checksum %u\n", + csum); + return -EINVAL; + } + + return 0; +} + enum fw_version_type { FW_VERSION_N3, FW_VERSION_T3 @@ -889,9 +959,9 @@ int t3_check_fw_version(adapter_t *adapter) minor == FW_VERSION_MINOR) 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); + CH_ERR(adapter, "found wrong FW version (%u.%u), " + "driver needs version %d.%d\n", major, minor, + FW_VERSION_MAJOR, FW_VERSION_MINOR); return -EINVAL; } @@ -921,7 +991,7 @@ static int t3_flash_erase_sectors(adapter_t *adapter, int start, int end) /* * t3_load_fw - download firmware * @adapter: the adapter - * @fw_data: the firrware image to write + * @fw_data: the firmware image to write * @size: image size * * Write the supplied firmware image to the card's serial flash. @@ -936,7 +1006,7 @@ int t3_load_fw(adapter_t *adapter, const u8 *fw_data, unsigned int size) const u32 *p = (const u32 *)fw_data; int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16; - if ((size & 3) || (size < FW_MIN_SIZE)) + if ((size & 3) || size < FW_MIN_SIZE) return -EINVAL; if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR) return -EFBIG; @@ -1015,9 +1085,10 @@ int t3_cim_ctl_blk_read(adapter_t *adap, unsigned int addr, unsigned int n, void t3_link_changed(adapter_t *adapter, int port_id) { int link_ok, speed, duplex, fc; - struct cphy *phy = &adapter->port[port_id].phy; - struct cmac *mac = &adapter->port[port_id].mac; - struct link_config *lc = &adapter->port[port_id].link_config; + struct port_info *pi = adap2pinfo(adapter, port_id); + struct cphy *phy = &pi->phy; + struct cmac *mac = &pi->mac; + struct link_config *lc = &pi->link_config; phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); @@ -1487,8 +1558,12 @@ static void mc7_intr_handler(struct mc7 *mc7) */ static int mac_intr_handler(adapter_t *adap, unsigned int idx) { - struct cmac *mac = &adap->port[idx].mac; - u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset); + u32 cause; + struct cmac *mac; + + idx = idx == 0 ? 0 : adapter_info(adap)->nports0; /* MAC idx -> port */ + mac = &adap2pinfo(adap, idx)->mac; + cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset); if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) { mac->stats.tx_fifo_parity_err++; @@ -1524,7 +1599,7 @@ int t3_phy_intr_handler(adapter_t *adapter) u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE); for_each_port(adapter, i) { - struct port_info *p = &adapter->port[i]; + struct port_info *p = adap2pinfo(adapter, i); mask = gpi - (gpi & (gpi - 1)); gpi -= mask; @@ -1556,7 +1631,6 @@ int t3_slow_intr_handler(adapter_t *adapter) cause &= adapter->slow_intr_mask; if (!cause) return 0; - if (cause & F_PCIM0) { if (is_pcie(adapter)) pcie_intr_handler(adapter); @@ -1647,11 +1721,10 @@ void t3_intr_enable(adapter_t *adapter) adapter_info(adapter)->gpio_intr); t3_write_reg(adapter, A_T3DBG_INT_ENABLE, adapter_info(adapter)->gpio_intr); - if (is_pcie(adapter)) { + if (is_pcie(adapter)) t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK); - } else { + else t3_write_reg(adapter, A_PCIX_INT_ENABLE, PCIX_INTR_MASK); - } t3_write_reg(adapter, A_PL_INT_ENABLE0, adapter->slow_intr_mask); (void) t3_read_reg(adapter, A_PL_INT_ENABLE0); /* flush */ } @@ -1719,8 +1792,10 @@ void t3_intr_clear(adapter_t *adapter) */ void t3_port_intr_enable(adapter_t *adapter, int idx) { - t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), XGM_INTR_MASK); - adapter->port[idx].phy.ops->intr_enable(&adapter->port[idx].phy); + struct port_info *pi = adap2pinfo(adapter, idx); + + t3_write_reg(adapter, A_XGM_INT_ENABLE + pi->mac.offset, XGM_INTR_MASK); + pi->phy.ops->intr_enable(&pi->phy); } /** @@ -1733,8 +1808,10 @@ void t3_port_intr_enable(adapter_t *adapter, int idx) */ void t3_port_intr_disable(adapter_t *adapter, int idx) { - t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), 0); - adapter->port[idx].phy.ops->intr_disable(&adapter->port[idx].phy); + struct port_info *pi = adap2pinfo(adapter, idx); + + t3_write_reg(adapter, A_XGM_INT_ENABLE + pi->mac.offset, 0); + pi->phy.ops->intr_disable(&pi->phy); } /** @@ -1747,10 +1824,11 @@ void t3_port_intr_disable(adapter_t *adapter, int idx) */ void t3_port_intr_clear(adapter_t *adapter, int idx) { - t3_write_reg(adapter, XGM_REG(A_XGM_INT_CAUSE, idx), 0xffffffff); - adapter->port[idx].phy.ops->intr_clear(&adapter->port[idx].phy); -} + struct port_info *pi = adap2pinfo(adapter, idx); + t3_write_reg(adapter, A_XGM_INT_CAUSE + pi->mac.offset, 0xffffffff); + pi->phy.ops->intr_clear(&pi->phy); +} /** * t3_sge_write_context - write an SGE context @@ -2344,6 +2422,14 @@ 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 | @@ -2360,14 +2446,16 @@ static void tp_config(adapter_t *adap, const struct tp_params *p) F_IPV6ENABLE | F_NICMODE); t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814); t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105); - t3_set_reg_field(adap, A_TP_PARA_REG6, - adap->params.rev > 0 ? F_ENABLEESND : F_T3A_ENABLEESND, - 0); + t3_set_reg_field(adap, A_TP_PARA_REG6, 0, + adap->params.rev > 0 ? F_ENABLEESND : + F_T3A_ENABLEESND); t3_set_reg_field(adap, A_TP_PC_CONFIG, - F_ENABLEEPCMDAFULL | F_ENABLEOCSPIFULL, - F_TXDEFERENABLE | F_HEARBEATDACK | F_TXCONGESTIONMODE | - F_RXCONGESTIONMODE); + F_ENABLEEPCMDAFULL, + F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK | + F_TXCONGESTIONMODE | F_RXCONGESTIONMODE); t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0); + t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080); + t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000); if (adap->params.rev > 0) { tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE); @@ -2381,7 +2469,21 @@ static void tp_config(adapter_t *adap, const struct tp_params *p) t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0); t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0); t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0); - t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0); + t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0xf2200000); + + if (adap->params.nports > 2) { + t3_set_reg_field(adap, A_TP_PC_CONFIG2, 0, + F_ENABLETXPORTFROMDA | F_ENABLERXPORTFROMADDR); + tp_wr_bits_indirect(adap, A_TP_QOS_RX_MAP_MODE, + V_RXMAPMODE(M_RXMAPMODE), 0); + tp_wr_indirect(adap, A_TP_INGRESS_CONFIG, V_BITPOS0(48) | + V_BITPOS1(49) | V_BITPOS2(50) | V_BITPOS3(51) | + F_ENABLEEXTRACT | F_ENABLEEXTRACTIONSFD | + F_ENABLEINSERTION | F_ENABLEINSERTIONSFD); + tp_wr_indirect(adap, A_TP_PREAMBLE_MSB, 0xfb000000); + tp_wr_indirect(adap, A_TP_PREAMBLE_LSB, 0xd5); + tp_wr_indirect(adap, A_TP_INTF_FROM_TX_PKT, F_INTFFROMTXPKT); + } } /* TCP timer values in ms */ @@ -2398,7 +2500,7 @@ static void tp_config(adapter_t *adap, const struct tp_params *p) */ static void tp_set_timers(adapter_t *adap, unsigned int core_clk) { - unsigned int tre = fls(core_clk / (1000000 / TP_TMR_RES)) - 1; + unsigned int tre = adap->params.tp.tre; unsigned int dack_re = adap->params.tp.dack_re; unsigned int tstamp_re = fls(core_clk / 1000); /* 1ms, at least */ unsigned int tps = core_clk >> tre; @@ -2456,6 +2558,7 @@ int t3_tp_set_coalescing_size(adapter_t *adap, unsigned int size, int psh) val |= F_RXCOALESCEENABLE; if (psh) val |= F_RXCOALESCEPSHEN; + size = min(MAX_RX_COALESCING_LEN, size); t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) | V_MAXRXDATA(MAX_RX_COALESCING_LEN)); } @@ -2485,11 +2588,10 @@ static void __devinit init_mtus(unsigned short mtus[]) * are enabled and still have at least 8 bytes of payload. */ mtus[0] = 88; - mtus[1] = 88; /* workaround for silicon starting at 1 */ + mtus[1] = 88; mtus[2] = 256; mtus[3] = 512; mtus[4] = 576; - /* mtus[4] = 808; */ mtus[5] = 1024; mtus[6] = 1280; mtus[7] = 1492; @@ -2705,6 +2807,33 @@ static void ulp_config(adapter_t *adap, const struct tp_params *p) ulp_region(adap, PBL, m, p->chan_rx_size / 4); t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff); } + + +/** + * t3_set_proto_sram - set the contents of the protocol sram + * @adapter: the adapter + * @data: the protocol image + * + * Write the contents of the protocol SRAM. + */ +int t3_set_proto_sram(adapter_t *adap, u8 *data) +{ + int i; + u32 *buf = (u32 *)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_FIELD0, i << 1 | 1 << 31); + if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1)) + return -EIO; + } + return 0; +} #endif void t3_config_trace_filter(adapter_t *adapter, const struct trace_params *tp, @@ -2883,20 +3012,22 @@ int t3_mps_set_active_ports(adapter_t *adap, unsigned int port_mask) } /* - * Perform the bits of HW initialization that are dependent on the number - * of available ports. + * Perform the bits of HW initialization that are dependent on the Tx + * channels being used. */ -static void init_hw_for_avail_ports(adapter_t *adap, int nports) +static void chan_init_hw(adapter_t *adap, unsigned int chan_map) { int i; - if (nports == 1) { + if (chan_map != 3) { /* one channel */ t3_set_reg_field(adap, A_ULPRX_CTL, F_ROUND_ROBIN, 0); t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0); - t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN | - F_PORT0ACTIVE | F_ENFORCEPKT); - t3_write_reg(adap, A_PM1_TX_CFG, 0xc000c000); - } else { + t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_ENFORCEPKT | + (chan_map == 1 ? F_TPTXPORT0EN | F_PORT0ACTIVE : + F_TPTXPORT1EN | F_PORT1ACTIVE)); + t3_write_reg(adap, A_PM1_TX_CFG, + chan_map == 1 ? 0xffffffff : 0); + } else { /* two channels */ t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN); t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB); t3_write_reg(adap, A_ULPTX_DMA_WEIGHT, @@ -2999,9 +3130,9 @@ static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type) adapter_t *adapter = mc7->adapter; const struct mc7_timing_params *p = &mc7_timings[mem_type]; - if (mc7->size == 0) + if (!mc7->size) return 0; - + val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); slow = val & F_SLOW; width = G_WIDTH(val); @@ -3166,6 +3297,12 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params) else if (calibrate_xgm(adapter)) goto out_err; + 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); @@ -3194,8 +3331,8 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params) else t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN); - t3_write_reg(adapter, A_PM1_RX_CFG, 0xf000f000); - init_hw_for_avail_ports(adapter, adapter->params.nports); + t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff); + chan_init_hw(adapter, adapter->params.chan_map); t3_sge_init(adapter, &adapter->params.sge); t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params); @@ -3210,6 +3347,7 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params) CH_ERR(adapter, "uP initialization timed out\n"); goto out_err; } + err = 0; out_err: return err; @@ -3314,8 +3452,16 @@ static void __devinit mc7_prep(adapter_t *adapter, struct mc7 *mc7, 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; + index = 0; + } else + mac->nucast = 1; + mac->offset = (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR) * index; - mac->nucast = 1; if (adapter->params.rev == 0 && uses_xaui(adapter)) { t3_write_reg(adapter, A_XGM_SERDES_CTRL + mac->offset, @@ -3327,7 +3473,8 @@ void mac_prep(struct cmac *mac, adapter_t *adapter, int index) void early_hw_init(adapter_t *adapter, const struct adapter_info *ai) { - u32 val = V_PORTSPEED(is_10G(adapter) ? 3 : 2); + u32 val = V_PORTSPEED(is_10G(adapter) || adapter->params.nports > 2 ? + 3 : 2); mi1_init(adapter, ai); t3_write_reg(adapter, A_I2C_CFG, /* set for 80KHz */ @@ -3335,7 +3482,7 @@ void early_hw_init(adapter_t *adapter, const struct adapter_info *ai) t3_write_reg(adapter, A_T3DBG_GPIO_EN, ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL); t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0); - + if (adapter->params.rev == 0 || !uses_xaui(adapter)) val |= F_ENRGMII; @@ -3354,9 +3501,9 @@ void early_hw_init(adapter_t *adapter, const struct adapter_info *ai) * Reset the adapter. PCIe cards lose their config space during reset, PCI-X * ones don't. */ -int t3_reset_adapter(adapter_t *adapter) +static int t3_reset_adapter(adapter_t *adapter) { - int i, save_and_restore_pcie = + int i, save_and_restore_pcie = adapter->params.rev < T3_REV_B2 && is_pcie(adapter); uint16_t devid = 0; @@ -3397,7 +3544,8 @@ int __devinit t3_prep_adapter(adapter_t *adapter, get_pci_mode(adapter, &adapter->params.pci); adapter->params.info = ai; - adapter->params.nports = ai->nports; + adapter->params.nports = ai->nports0 + ai->nports1; + 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) ? @@ -3406,9 +3554,10 @@ int __devinit t3_prep_adapter(adapter_t *adapter, t3_os_find_pci_capability(adapter, PCI_CAP_ID_VPD); ret = get_vpd_params(adapter, &adapter->params.vpd); - if (ret < 0) + if (ret < 0) { + printf("failed to get VPD params\n"); return ret; - + } if (reset && t3_reset_adapter(adapter)) return -1; @@ -3421,7 +3570,7 @@ int __devinit t3_prep_adapter(adapter_t *adapter, mc7_prep(adapter, &adapter->pmtx, MC7_PMTX_BASE_ADDR, "PMTX"); mc7_prep(adapter, &adapter->cm, MC7_CM_BASE_ADDR, "CM"); - p->nchan = ai->nports; + p->nchan = adapter->params.chan_map == 3 ? 2 : 1; p->pmrx_size = t3_mc7_size(&adapter->pmrx); p->pmtx_size = t3_mc7_size(&adapter->pmtx); p->cm_size = t3_mc7_size(&adapter->cm); @@ -3433,11 +3582,14 @@ int __devinit t3_prep_adapter(adapter_t *adapter, p->tx_num_pgs = pm_num_pages(p->chan_tx_size, p->tx_pg_size); p->ntimer_qs = p->cm_size >= (128 << 20) || adapter->params.rev > 0 ? 12 : 6; + p->tre = fls(adapter->params.vpd.cclk / (1000 / TP_TMR_RES)) - + 1; p->dack_re = fls(adapter->params.vpd.cclk / 10) - 1; /* 100us */ } + adapter->params.offload = t3_mc7_size(&adapter->pmrx) && - t3_mc7_size(&adapter->pmtx) && - t3_mc7_size(&adapter->cm); + t3_mc7_size(&adapter->pmtx) && + t3_mc7_size(&adapter->cm); if (is_offload(adapter)) { adapter->params.mc5.nservers = DEFAULT_NSERVERS; @@ -3456,12 +3608,22 @@ int __devinit t3_prep_adapter(adapter_t *adapter, for_each_port(adapter, i) { u8 hw_addr[6]; - struct port_info *p = &adapter->port[i]; + struct port_info *p = adap2pinfo(adapter, i); - while (!adapter->params.vpd.port_type[j]) + while (adapter->params.vpd.port_type[j] == 0) { ++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 new file mode 100644 index 0000000..51e254e --- /dev/null +++ b/sys/dev/cxgb/common/cxgb_vsc7323.c @@ -0,0 +1,340 @@ + +/************************************************************************** + +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. + +***************************************************************************/ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#ifdef CONFIG_DEFINED +#include <common/cxgb_common.h> +#else +#include <dev/cxgb/common/cxgb_common.h> +#endif + +enum { + ELMR_ADDR = 0, + ELMR_STAT = 1, + ELMR_DATA_LO = 2, + ELMR_DATA_HI = 3, + + ELMR_MDIO_ADDR = 10 +}; + +#define VSC_REG(block, subblock, reg) \ + ((reg) | ((subblock) << 8) | ((block) << 12)) + +int t3_elmr_blk_write(adapter_t *adap, int start, const u32 *vals, int n) +{ + int ret; + const struct mdio_ops *mo = adapter_info(adap)->mdio_ops; + + ELMR_LOCK(adap); + ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_ADDR, start); + for ( ; !ret && n; n--, vals++) { + ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_LO, + *vals & 0xffff); + if (!ret) + ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_HI, + *vals >> 16); + } + ELMR_UNLOCK(adap); + return ret; +} + +static int elmr_write(adapter_t *adap, int addr, u32 val) +{ + return t3_elmr_blk_write(adap, addr, &val, 1); +} + +int t3_elmr_blk_read(adapter_t *adap, int start, u32 *vals, int n) +{ + int ret; + unsigned int v; + const struct mdio_ops *mo = adapter_info(adap)->mdio_ops; + + ELMR_LOCK(adap); + + ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_ADDR, start); + if (ret) + goto out; + ret = mo->read(adap, ELMR_MDIO_ADDR, 0, ELMR_STAT, &v); + if (ret) + goto out; + if (v != 1) { + ret = -ETIMEDOUT; + goto out; + } + + for ( ; !ret && n; n--, vals++) { + ret = mo->read(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_LO, vals); + if (!ret) { + ret = mo->read(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_HI, + &v); + *vals |= v << 16; + } + } +out: ELMR_UNLOCK(adap); + return ret; +} + +int t3_vsc7323_init(adapter_t *adap, int nports) +{ + static struct addr_val_pair sys_avp[] = { + { VSC_REG(7, 15, 0xf), 2 }, + { VSC_REG(7, 15, 0x19), 0xd6 }, + { VSC_REG(7, 15, 7), 0xc }, + { VSC_REG(7, 1, 0), 0x220 }, + }; + static struct addr_val_pair fifo_avp[] = { + { VSC_REG(2, 0, 0x2f), 0 }, + { VSC_REG(2, 0, 0xf), 0xa0010291 }, + { VSC_REG(2, 1, 0x2f), 1 }, + { VSC_REG(2, 1, 0xf), 0xa0026301 } + }; + static struct addr_val_pair xg_avp[] = { + { VSC_REG(1, 10, 0), 0x600b }, + { VSC_REG(1, 10, 2), 0x4000 }, + { VSC_REG(1, 10, 5), 0x65 }, + { VSC_REG(1, 10, 7), 3 }, + { VSC_REG(1, 10, 0x23), 0x800007bf }, + { VSC_REG(1, 10, 0x24), 4 } + }; + + int i, ret, ing_step, egr_step, ing_bot, egr_bot; + + 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))) + return ret; + + + ing_step = 0xc0 / nports; + egr_step = 0x40 / nports; + ing_bot = egr_bot = 0; +// ing_wm = ing_step * 64; +// 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), + ((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, 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; + + + 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; + + for (i = 0; i < ARRAY_SIZE(xg_avp); i++) + if ((ret = t3_elmr_blk_write(adap, xg_avp[i].reg_addr, + &xg_avp[i].val, 1))) + return ret; + + for (i = 0; i < nports; i++) + if ((ret = elmr_write(adap, VSC_REG(1, i, 0), 0xa59c)) || + (ret = elmr_write(adap, VSC_REG(1, i, 5), + (i << 12) | 0x63)) || + (ret = elmr_write(adap, VSC_REG(1, i, 0xb), 0x96)) || + (ret = elmr_write(adap, VSC_REG(1, i, 0x15), 0x21))) + return ret; + return ret; +} + +int t3_vsc7323_set_speed_fc(adapter_t *adap, int speed, int fc, int port) +{ + int mode, clk, r; + + if (speed >= 0) { + if (speed == SPEED_10) + mode = clk = 1; + else if (speed == SPEED_100) + mode = 1, clk = 2; + else if (speed == SPEED_1000) + mode = clk = 3; + else + return -EINVAL; + + if ((r = elmr_write(adap, VSC_REG(1, port, 0), + 0xa590 | (mode << 2))) || + (r = elmr_write(adap, VSC_REG(1, port, 0xb), + 0x91 | (clk << 1))) || + (r = elmr_write(adap, VSC_REG(1, port, 0xb), + 0x90 | (clk << 1))) || + (r = elmr_write(adap, VSC_REG(1, port, 0), + 0xa593 | (mode << 2)))) + return r; + } + + r = (fc & PAUSE_RX) ? 0x6ffff : 0x2ffff; + if (fc & PAUSE_TX) + r |= (1 << 19); + return elmr_write(adap, VSC_REG(1, port, 1), r); +} + +int t3_vsc7323_set_mtu(adapter_t *adap, unsigned int mtu, int port) +{ + return elmr_write(adap, VSC_REG(1, port, 2), mtu); +} + +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]); + if (!ret) + ret = elmr_write(adap, VSC_REG(1, port, 4), + (addr[3] << 16) | (addr[4] << 8) | addr[5]); + return ret; +} + +int t3_vsc7323_enable(adapter_t *adap, int port, int which) +{ + int ret; + unsigned int v, orig; + + ret = t3_elmr_blk_read(adap, VSC_REG(1, port, 0), &v, 1); + if (!ret) { + orig = v; + if (which & MAC_DIRECTION_TX) + v |= 1; + if (which & MAC_DIRECTION_RX) + v |= 2; + if (v != orig) + ret = elmr_write(adap, VSC_REG(1, port, 0), v); + } + return ret; +} + +int t3_vsc7323_disable(adapter_t *adap, int port, int which) +{ + int ret; + unsigned int v, orig; + + ret = t3_elmr_blk_read(adap, VSC_REG(1, port, 0), &v, 1); + if (!ret) { + orig = v; + if (which & MAC_DIRECTION_TX) + v &= ~1; + if (which & MAC_DIRECTION_RX) + v &= ~2; + if (v != orig) + ret = elmr_write(adap, VSC_REG(1, port, 0), v); + } + return ret; +} + +#define STATS0_START 1 +#define STATS1_START 0x24 +#define NSTATS0 (0x1d - STATS0_START + 1) +#define NSTATS1 (0x2a - STATS1_START + 1) + +const struct mac_stats *t3_vsc7323_update_stats(struct cmac *mac) +{ + int ret; + u64 rx_ucast, tx_ucast; + u32 stats0[NSTATS0], stats1[NSTATS1]; + + ret = t3_elmr_blk_read(mac->adapter, + VSC_REG(4, mac->ext_port, STATS0_START), + stats0, NSTATS0); + if (!ret) + ret = t3_elmr_blk_read(mac->adapter, + VSC_REG(4, mac->ext_port, STATS1_START), + stats1, NSTATS1); + if (ret) + goto out; + + /* + * HW counts Rx/Tx unicast frames but we want all the frames. + */ + rx_ucast = mac->stats.rx_frames - mac->stats.rx_mcast_frames - + mac->stats.rx_bcast_frames; + rx_ucast += (u64)(stats0[6 - STATS0_START] - (u32)rx_ucast); + tx_ucast = mac->stats.tx_frames - mac->stats.tx_mcast_frames - + mac->stats.tx_bcast_frames; + tx_ucast += (u64)(stats0[27 - STATS0_START] - (u32)tx_ucast); + +#define RMON_UPDATE(mac, name, hw_stat) \ + mac->stats.name += (u64)((hw_stat) - (u32)(mac->stats.name)) + + RMON_UPDATE(mac, rx_octets, stats0[4 - STATS0_START]); + RMON_UPDATE(mac, rx_frames, stats0[6 - STATS0_START]); + RMON_UPDATE(mac, rx_frames, stats0[7 - STATS0_START]); + RMON_UPDATE(mac, rx_frames, stats0[8 - STATS0_START]); + RMON_UPDATE(mac, rx_mcast_frames, stats0[7 - STATS0_START]); + RMON_UPDATE(mac, rx_bcast_frames, stats0[8 - STATS0_START]); + RMON_UPDATE(mac, rx_fcs_errs, stats0[9 - STATS0_START]); + RMON_UPDATE(mac, rx_pause, stats0[2 - STATS0_START]); + RMON_UPDATE(mac, rx_jabber, stats0[16 - STATS0_START]); + RMON_UPDATE(mac, rx_short, stats0[11 - STATS0_START]); + RMON_UPDATE(mac, rx_symbol_errs, stats0[1 - STATS0_START]); + RMON_UPDATE(mac, rx_too_long, stats0[15 - STATS0_START]); + + RMON_UPDATE(mac, rx_frames_64, stats0[17 - STATS0_START]); + RMON_UPDATE(mac, rx_frames_65_127, stats0[18 - STATS0_START]); + RMON_UPDATE(mac, rx_frames_128_255, stats0[19 - STATS0_START]); + RMON_UPDATE(mac, rx_frames_256_511, stats0[20 - STATS0_START]); + RMON_UPDATE(mac, rx_frames_512_1023, stats0[21 - STATS0_START]); + RMON_UPDATE(mac, rx_frames_1024_1518, stats0[22 - STATS0_START]); + RMON_UPDATE(mac, rx_frames_1519_max, stats0[23 - STATS0_START]); + + RMON_UPDATE(mac, tx_octets, stats0[26 - STATS0_START]); + RMON_UPDATE(mac, tx_frames, stats0[27 - STATS0_START]); + RMON_UPDATE(mac, tx_frames, stats0[28 - STATS0_START]); + RMON_UPDATE(mac, tx_frames, stats0[29 - STATS0_START]); + RMON_UPDATE(mac, tx_mcast_frames, stats0[28 - STATS0_START]); + RMON_UPDATE(mac, tx_bcast_frames, stats0[29 - STATS0_START]); + RMON_UPDATE(mac, tx_pause, stats0[25 - STATS0_START]); + + RMON_UPDATE(mac, tx_underrun, 0); + + RMON_UPDATE(mac, tx_frames_64, stats1[36 - STATS1_START]); + RMON_UPDATE(mac, tx_frames_65_127, stats1[37 - STATS1_START]); + RMON_UPDATE(mac, tx_frames_128_255, stats1[38 - STATS1_START]); + RMON_UPDATE(mac, tx_frames_256_511, stats1[39 - STATS1_START]); + RMON_UPDATE(mac, tx_frames_512_1023, stats1[40 - STATS1_START]); + RMON_UPDATE(mac, tx_frames_1024_1518, stats1[41 - STATS1_START]); + RMON_UPDATE(mac, tx_frames_1519_max, stats1[42 - STATS1_START]); + +#undef RMON_UPDATE + + mac->stats.rx_frames = rx_ucast + mac->stats.rx_mcast_frames + + mac->stats.rx_bcast_frames; + mac->stats.tx_frames = tx_ucast + mac->stats.tx_mcast_frames + + mac->stats.tx_bcast_frames; +out: return &mac->stats; +} diff --git a/sys/dev/cxgb/common/cxgb_xgmac.c b/sys/dev/cxgb/common/cxgb_xgmac.c index 22cd22e..34b05cd 100644 --- a/sys/dev/cxgb/common/cxgb_xgmac.c +++ b/sys/dev/cxgb/common/cxgb_xgmac.c @@ -1,3 +1,4 @@ + /************************************************************************** Copyright (c) 2007, Chelsio Inc. @@ -128,8 +129,23 @@ int t3_mac_reset(struct cmac *mac) xaui_serdes_reset(mac); } + + if (mac->multiport) { + t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + oft, + MAX_FRAME_SIZE - 4); + t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft, 0, + F_DISPREAMBLE); + t3_set_reg_field(adap, A_XGM_RX_CFG + oft, 0, F_COPYPREAMBLE | + F_ENNON802_3PREAMBLE); + t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft, + V_TXFIFOTHRESH(M_TXFIFOTHRESH), + V_TXFIFOTHRESH(64)); + t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN); + t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN); + } + val = F_MAC_RESET_; - if (is_10G(adap)) + if (is_10G(adap) || mac->multiport) val |= F_PCS_RESET_; else if (uses_xaui(adap)) val |= F_PCS_RESET_ | F_XG2G_RESET_; @@ -220,9 +236,14 @@ static void set_addr_filter(struct cmac *mac, int idx, const u8 *addr) /* Set one of the station's unicast MAC addresses. */ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]) { + if (mac->multiport) + idx = mac->ext_port + idx * mac->adapter->params.nports; if (idx >= mac->nucast) return -EINVAL; set_addr_filter(mac, idx, addr); + if (mac->multiport && idx < mac->adapter->params.nports) + t3_vsc7323_set_addr(mac->adapter, addr, idx); + return 0; } @@ -231,7 +252,7 @@ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]) * unicast addresses. Caller should reload the unicast and multicast addresses * after calling this. */ -int t3_mac_set_num_ucast(struct cmac *mac, int n) +int t3_mac_set_num_ucast(struct cmac *mac, unsigned char n) { if (n > EXACT_ADDR_FILTERS) return -EINVAL; @@ -239,6 +260,28 @@ int t3_mac_set_num_ucast(struct cmac *mac, int n) return 0; } +static void disable_exact_filters(struct cmac *mac) +{ + unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_LOW_1; + + for (i = 0; i < EXACT_ADDR_FILTERS; i++, reg += 8) { + u32 v = t3_read_reg(mac->adapter, reg); + t3_write_reg(mac->adapter, reg, v); + } + t3_read_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1); /* flush */ +} + +static void enable_exact_filters(struct cmac *mac) +{ + unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_HIGH_1; + + for (i = 0; i < EXACT_ADDR_FILTERS; i++, reg += 8) { + u32 v = t3_read_reg(mac->adapter, reg); + t3_write_reg(mac->adapter, reg, v); + } + t3_read_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1); /* flush */ +} + /* Calculate the RX hash filter index of an Ethernet address */ static int hash_hw_addr(const u8 *addr) { @@ -255,16 +298,18 @@ static int hash_hw_addr(const u8 *addr) int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm) { - u32 val, hash_lo, hash_hi; + u32 hash_lo, hash_hi; adapter_t *adap = mac->adapter; unsigned int oft = mac->offset; - val = t3_read_reg(adap, A_XGM_RX_CFG + oft) & ~F_COPYALLFRAMES; if (promisc_rx_mode(rm)) - val |= F_COPYALLFRAMES; - t3_write_reg(adap, A_XGM_RX_CFG + oft, val); + mac->promisc_map |= 1 << mac->ext_port; + else + mac->promisc_map &= ~(1 << mac->ext_port); + t3_set_reg_field(adap, A_XGM_RX_CFG + oft, F_COPYALLFRAMES, + mac->promisc_map ? F_COPYALLFRAMES : 0); - if (allmulti_rx_mode(rm)) + if (allmulti_rx_mode(rm) || mac->multiport) hash_lo = hash_hi = 0xffffffff; else { u8 *addr; @@ -289,7 +334,15 @@ int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm) return 0; } -int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) +static int rx_fifo_hwm(int mtu) +{ + int hwm; + + hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, (MAC_RXFIFO_SIZE * 38) / 100); + return min(hwm, MAC_RXFIFO_SIZE - 8192); +} + +int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) { int hwm, lwm; unsigned int thres, v; @@ -300,17 +353,39 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) * packet size register includes header, but not FCS. */ mtu += 14; + if (mac->multiport) + mtu += 8; /* for preamble */ if (mtu > MAX_FRAME_SIZE - 4) return -EINVAL; - t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu); + if (mac->multiport) + return t3_vsc7323_set_mtu(adap, mtu - 4, mac->ext_port); + + if (adap->params.rev == T3_REV_B2 && + (t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) { + disable_exact_filters(mac); + v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset); + t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset, + F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST); + + /* drain rx FIFO */ + if (t3_wait_op_done(adap, + A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + mac->offset, + 1 << 31, 1, 20, 5)) { + t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v); + enable_exact_filters(mac); + return -EIO; + } + t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu); + t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v); + enable_exact_filters(mac); + } else + t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu); /* * Adjust the PAUSE frame watermarks. We always set the LWM, and the * HWM only if flow-control is enabled. */ - hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu, - MAC_RXFIFO_SIZE * 38 / 100); - hwm = min(hwm, MAC_RXFIFO_SIZE - 8192); + hwm = rx_fifo_hwm(mtu); lwm = min(3 * (int) mtu, MAC_RXFIFO_SIZE /4); v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset); v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM); @@ -318,6 +393,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) if (G_RXFIFOPAUSEHWM(v)) v = (v & ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM)) | V_RXFIFOPAUSEHWM(hwm / 8); + t3_write_reg(adap, A_XGM_RXFIFO_CFG + mac->offset, v); /* Adjust the TX FIFO threshold based on the MTU */ @@ -335,7 +411,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) */ if (adap->params.rev > 0) t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset, - (hwm-lwm) * 4 / 8); + (hwm - lwm) * 4 / 8); t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset, MAC_RXFIFO_SIZE * 4 * 8 / 512); return 0; @@ -349,6 +425,8 @@ 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) + return t3_vsc7323_set_speed_fc(adap, speed, fc, mac->ext_port); if (speed >= 0) { if (speed == SPEED_10) val = V_PORTSPEED(0); @@ -364,13 +442,14 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc) t3_set_reg_field(adap, A_XGM_PORT_CFG + oft, V_PORTSPEED(M_PORTSPEED), val); } -#if 0 + val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft); val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM); if (fc & PAUSE_TX) - val |= V_RXFIFOPAUSEHWM(G_RXFIFOPAUSELWM(val) + 128); /* +1KB */ + 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); -#endif + t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, (fc & PAUSE_RX) ? F_TXPAUSEEN : 0); return 0; @@ -383,6 +462,9 @@ int t3_mac_enable(struct cmac *mac, int which) unsigned int oft = mac->offset; struct mac_stats *s = &mac->stats; + if (mac->multiport) + 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); @@ -415,6 +497,9 @@ int t3_mac_disable(struct cmac *mac, int which) adapter_t *adap = mac->adapter; int val; + if (mac->multiport) + return t3_vsc7323_disable(adap, mac->ext_port, which); + if (which & MAC_DIRECTION_TX) { 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); diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h index e678003..9c3a8dd 100644 --- a/sys/dev/cxgb/cxgb_adapter.h +++ b/sys/dev/cxgb/cxgb_adapter.h @@ -56,9 +56,13 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcivar.h> #ifdef CONFIG_DEFINED -#include <cxgb_include.h> +#include <cxgb_osdep.h> +#include <ulp/toecore/toedev.h> +#include <sys/mbufq.h> #else -#include <dev/cxgb/cxgb_include.h> +#include <dev/cxgb/cxgb_osdep.h> +#include <dev/cxgb/sys/mbufq.h> +#include <dev/cxgb/ulp/toecore/toedev.h> #endif struct adapter; @@ -82,6 +86,7 @@ struct port_info { uint8_t first_qset; struct taskqueue *tq; struct task start_task; + struct task timer_reclaim_task; struct cdev *port_cdev; }; @@ -277,7 +282,6 @@ struct adapter { /* Tasks */ struct task ext_intr_task; - struct task timer_reclaim_task; struct task slow_intr_task; struct task process_responses_task; struct task mr_refresh_task; @@ -287,6 +291,7 @@ struct adapter { /* Register lock for use by the hardware layer */ struct mtx mdio_lock; + struct mtx elmer_lock; /* Bookkeeping for the hardware layer */ struct adapter_params params; @@ -319,6 +324,8 @@ struct t3_rx_mode { #define MDIO_LOCK(adapter) mtx_lock(&(adapter)->mdio_lock) #define MDIO_UNLOCK(adapter) mtx_unlock(&(adapter)->mdio_lock) +#define ELMR_LOCK(adapter) mtx_lock(&(adapter)->elmer_lock) +#define ELMR_UNLOCK(adapter) mtx_unlock(&(adapter)->elmer_lock) #define PORT_LOCK(port) mtx_lock(&(port)->lock); #define PORT_UNLOCK(port) mtx_unlock(&(port)->lock); @@ -413,7 +420,8 @@ void t3_intr_msi(void *data); void t3_intr_msix(void *data); int t3_encap(struct port_info *, struct mbuf **); -int t3_sge_init_sw(adapter_t *); +int t3_sge_init_adapter(adapter_t *); +int t3_sge_init_port(struct port_info *); void t3_sge_deinit_sw(adapter_t *); void t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m, diff --git a/sys/dev/cxgb/cxgb_config.h b/sys/dev/cxgb/cxgb_config.h index 446c743..6b072c3 100644 --- a/sys/dev/cxgb/cxgb_config.h +++ b/sys/dev/cxgb/cxgb_config.h @@ -34,7 +34,6 @@ $FreeBSD$ #ifndef CONFIG_DEFINED #define CONFIG_CHELSIO_T3_CORE -#define DEFAULT_JUMBO #endif #endif diff --git a/sys/dev/cxgb/cxgb_lro.c b/sys/dev/cxgb/cxgb_lro.c index 9745cdf..9f64a0d 100644 --- a/sys/dev/cxgb/cxgb_lro.c +++ b/sys/dev/cxgb/cxgb_lro.c @@ -87,14 +87,12 @@ __FBSDID("$FreeBSD$"); static __inline int lro_match(struct mbuf *m, struct ip *ih, struct tcphdr *th) { - struct ip *sih = (struct ip *)(m->m_data + IPH_OFFSET); + struct ip *sih = (struct ip *)(mtod(m, uint8_t *) + IPH_OFFSET); struct tcphdr *sth = (struct tcphdr *) (sih + 1); - /* - * Why don't we check dest ports? - */ - return (*(uint32_t *)&th->th_sport == *(uint32_t *)&sth->th_sport && - ih->ip_src.s_addr == ih->ip_src.s_addr && + return (th->th_sport == sth->th_sport && + th->th_dport == sth->th_dport && + ih->ip_src.s_addr == sih->ip_src.s_addr && ih->ip_dst.s_addr == sih->ip_dst.s_addr); } @@ -164,7 +162,7 @@ can_lro_tcpsegment(struct tcphdr *th) static __inline void lro_new_session_init(struct t3_lro_session *s, struct mbuf *m) { - struct ip *ih = (struct ip *)(m->m_data + IPH_OFFSET); + struct ip *ih = (struct ip *)(mtod(m, uint8_t *) + IPH_OFFSET); struct tcphdr *th = (struct tcphdr *) (ih + 1); int ip_len = ntohs(ih->ip_len); @@ -183,7 +181,7 @@ lro_flush_session(struct sge_qset *qs, struct t3_lro_session *s, struct mbuf *m) { struct lro_state *l = &qs->lro; struct mbuf *sm = s->head; - struct ip *ih = (struct ip *)(sm->m_data + IPH_OFFSET); + struct ip *ih = (struct ip *)(mtod(sm, uint8_t *) + IPH_OFFSET); DPRINTF("%s(qs=%p, s=%p, ", __FUNCTION__, @@ -253,9 +251,9 @@ static __inline int lro_update_session(struct t3_lro_session *s, struct mbuf *m) { struct mbuf *sm = s->head; - struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(sm->m_data + 2); - struct cpl_rx_pkt *ncpl = (struct cpl_rx_pkt *)(m->m_data + 2); - struct ip *nih = (struct ip *)(m->m_data + IPH_OFFSET); + struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(sm, uint8_t *) + 2); + struct cpl_rx_pkt *ncpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + 2); + struct ip *nih = (struct ip *)(mtod(m, uint8_t *) + IPH_OFFSET); struct tcphdr *th, *nth = (struct tcphdr *)(nih + 1); uint32_t seq = ntohl(nth->th_seq); int plen, tcpiphlen, olen = (nth->th_off << 2) - sizeof (*nth); @@ -271,7 +269,7 @@ lro_update_session(struct t3_lro_session *s, struct mbuf *m) } MBUF_HEADER_CHECK(sm); - th = (struct tcphdr *)(sm->m_data + IPH_OFFSET + sizeof (struct ip)); + th = (struct tcphdr *)(mtod(sm, uint8_t *) + IPH_OFFSET + sizeof (struct ip)); if (olen) { uint32_t *ptr = (uint32_t *)(th + 1); @@ -338,7 +336,7 @@ t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad, uint32_t rss_hash, uint32_t rss_csum, int lro) { struct sge_qset *qs = rspq_to_qset(rq); - struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(m->m_data + ethpad); + struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad); struct ether_header *eh = (struct ether_header *)(cpl + 1); struct ip *ih; struct tcphdr *th; diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index fb3725b..def180d 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -83,6 +83,7 @@ __FBSDID("$FreeBSD$"); #endif static int cxgb_setup_msix(adapter_t *, int); +static void cxgb_teardown_msix(adapter_t *); static void cxgb_init(void *); static void cxgb_init_locked(struct port_info *); static void cxgb_stop_locked(struct port_info *); @@ -158,6 +159,17 @@ static driver_t cxgb_port_driver = { }; static d_ioctl_t cxgb_extension_ioctl; +static d_open_t cxgb_extension_open; +static d_close_t cxgb_extension_close; + +static struct cdevsw cxgb_cdevsw = { + .d_version = D_VERSION, + .d_flags = 0, + .d_open = cxgb_extension_open, + .d_close = cxgb_extension_close, + .d_ioctl = cxgb_extension_ioctl, + .d_name = "cxgb", +}; static devclass_t cxgb_port_devclass; DRIVER_MODULE(cxgb, cxgbc, cxgb_port_driver, cxgb_port_devclass, 0, 0); @@ -230,6 +242,7 @@ struct cxgb_ident { {PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"}, {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"}, {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"}, + {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"}, {0, 0, 0, NULL} }; @@ -267,17 +280,19 @@ cxgb_controller_probe(device_t dev) { const struct adapter_info *ai; char *ports, buf[80]; - + int nports; + ai = cxgb_get_adapter_info(dev); if (ai == NULL) return (ENXIO); - if (ai->nports == 1) + nports = ai->nports0 + ai->nports1; + if (nports == 1) ports = "port"; else ports = "ports"; - snprintf(buf, sizeof(buf), "%s RNIC, %d %s", ai->desc, ai->nports, ports); + snprintf(buf, sizeof(buf), "%s RNIC, %d %s", ai->desc, nports, ports); device_set_desc_copy(dev, buf); return (BUS_PROBE_DEFAULT); } @@ -341,7 +356,6 @@ cxgb_controller_attach(device_t dev) } pci_enable_busmaster(dev); - /* * Allocate the registers and make them available to the driver. * The registers that we care about for NIC mode are in BAR 0 @@ -356,6 +370,7 @@ cxgb_controller_attach(device_t dev) mtx_init(&sc->sge.reg_lock, "SGE reg lock", NULL, MTX_DEF); mtx_init(&sc->lock, "cxgb controller lock", NULL, MTX_DEF); mtx_init(&sc->mdio_lock, "cxgb mdio", NULL, MTX_DEF); + mtx_init(&sc->elmer_lock, "cxgb elmer", NULL, MTX_DEF); sc->bt = rman_get_bustag(sc->regs_res); sc->bh = rman_get_bushandle(sc->regs_res); @@ -363,10 +378,10 @@ cxgb_controller_attach(device_t dev) ai = cxgb_get_adapter_info(dev); if (t3_prep_adapter(sc, ai, 1) < 0) { + printf("prep adapter failed\n"); error = ENODEV; goto out; } - /* Allocate the BAR for doing MSI-X. If it succeeds, try to allocate * enough messages for the queue sets. If that fails, try falling * back to MSI. If that fails, then try falling back to the legacy @@ -478,7 +493,7 @@ cxgb_controller_attach(device_t dev) sc->params.stats_update_period = 1; /* initialize sge private state */ - t3_sge_init_sw(sc); + t3_sge_init_adapter(sc); t3_led_ready(sc); @@ -554,12 +569,13 @@ cxgb_free(struct adapter *sc) } bus_generic_detach(sc->dev); - +#ifdef notyet if (is_offload(sc)) { cxgb_adapter_unofld(sc); if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT)) offload_close(&sc->tdev); } +#endif t3_free_sge_resources(sc); t3_sge_free(sc); @@ -616,6 +632,28 @@ setup_sge_qsets(adapter_t *sc) return (0); } +static void +cxgb_teardown_msix(adapter_t *sc) +{ + int i, nqsets; + + for (nqsets = i = 0; i < (sc)->params.nports; i++) + nqsets += sc->port[i].nqsets; + + for (i = 0; i < nqsets; i++) { + if (sc->msix_intr_tag[i] != NULL) { + bus_teardown_intr(sc->dev, sc->msix_irq_res[i], + sc->msix_intr_tag[i]); + sc->msix_intr_tag[i] = NULL; + } + if (sc->msix_irq_res[i] != NULL) { + bus_release_resource(sc->dev, SYS_RES_IRQ, + sc->msix_irq_rid[i], sc->msix_irq_res[i]); + sc->msix_irq_res[i] = NULL; + } + } +} + static int cxgb_setup_msix(adapter_t *sc, int msix_count) { @@ -637,9 +675,9 @@ cxgb_setup_msix(adapter_t *sc, int msix_count) device_printf(sc->dev, "Cannot set up interrupt\n"); return (EINVAL); } - for (i = 0, k = 0; i < (sc)->params.nports; ++i) { + for (i = k = 0; i < (sc)->params.nports; i++) { nqsets = sc->port[i].nqsets; - for (j = 0; j < nqsets; ++j, k++) { + for (j = 0; j < nqsets; j++, k++) { struct sge_qset *qs = &sc->sge.qs[k]; rid = k + 2; @@ -653,7 +691,7 @@ cxgb_setup_msix(adapter_t *sc, int msix_count) return (EINVAL); } sc->msix_irq_rid[k] = rid; - if (bus_setup_intr(sc->dev, sc->msix_irq_res[j], + if (bus_setup_intr(sc->dev, sc->msix_irq_res[k], INTR_MPSAFE|INTR_TYPE_NET, #ifdef INTR_FILTERS NULL, @@ -687,17 +725,9 @@ cxgb_port_probe(device_t dev) static int cxgb_makedev(struct port_info *pi) { - struct cdevsw *cxgb_cdevsw; - - if ((cxgb_cdevsw = malloc(sizeof(struct cdevsw), M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) - return (ENOMEM); - - cxgb_cdevsw->d_version = D_VERSION; - cxgb_cdevsw->d_name = strdup(pi->ifp->if_xname, M_DEVBUF); - cxgb_cdevsw->d_ioctl = cxgb_extension_ioctl; - pi->port_cdev = make_dev(cxgb_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, - pi->ifp->if_xname); + pi->port_cdev = make_dev(&cxgb_cdevsw, pi->ifp->if_dunit, + UID_ROOT, GID_WHEEL, 0600, if_name(pi->ifp)); if (pi->port_cdev == NULL) return (ENOMEM); @@ -726,8 +756,7 @@ cxgb_port_attach(device_t dev) { struct port_info *p; struct ifnet *ifp; - int media_flags; - int err; + int err, media_flags; char buf[64]; p = device_get_softc(dev); @@ -762,7 +791,6 @@ 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); - ifp->if_baudrate = 100000000; ether_ifattach(ifp, p->hw_addr); #ifdef DEFAULT_JUMBO @@ -774,21 +802,36 @@ cxgb_port_attach(device_t dev) } ifmedia_init(&p->media, IFM_IMASK, cxgb_media_change, cxgb_media_status); - - if (!strcmp(p->port_type->desc, "10GBASE-CX4")) - media_flags = IFM_ETHER | IFM_10G_CX4; - else if (!strcmp(p->port_type->desc, "10GBASE-SR")) - media_flags = IFM_ETHER | IFM_10G_SR; - else if (!strcmp(p->port_type->desc, "10GBASE-XR")) - media_flags = IFM_ETHER | IFM_10G_LR; - else { + + if (!strcmp(p->port_type->desc, "10GBASE-CX4")) { + media_flags = IFM_ETHER | IFM_10G_CX4 | IFM_FDX; + } else if (!strcmp(p->port_type->desc, "10GBASE-SR")) { + media_flags = IFM_ETHER | IFM_10G_SR | IFM_FDX; + } else if (!strcmp(p->port_type->desc, "10GBASE-XR")) { + media_flags = IFM_ETHER | IFM_10G_LR | IFM_FDX; + } else if (!strcmp(p->port_type->desc, "10/100/1000BASE-T")) { + ifmedia_add(&p->media, IFM_ETHER | IFM_10_T, 0, NULL); + ifmedia_add(&p->media, IFM_ETHER | IFM_10_T | IFM_FDX, + 0, NULL); + ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX, + 0, NULL); + ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX | IFM_FDX, + 0, NULL); + ifmedia_add(&p->media, IFM_ETHER | IFM_1000_T | IFM_FDX, + 0, NULL); + media_flags = 0; + } else { printf("unsupported media type %s\n", p->port_type->desc); return (ENXIO); } - - ifmedia_add(&p->media, media_flags, 0, NULL); - ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL); - ifmedia_set(&p->media, media_flags); + if (media_flags) { + ifmedia_add(&p->media, media_flags, 0, NULL); + ifmedia_set(&p->media, media_flags); + } else { + ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&p->media, IFM_ETHER | IFM_AUTO); + } + snprintf(buf, sizeof(buf), "cxgb_port_taskq%d", p->port); #ifdef TASKQUEUE_CURRENT @@ -800,8 +843,7 @@ cxgb_port_attach(device_t dev) p->tq = taskqueue_create_fast(buf, M_NOWAIT, taskqueue_thread_enqueue, &p->tq); #endif - - + if (p->tq == NULL) { device_printf(dev, "failed to allocate port task queue\n"); return (ENOMEM); @@ -810,7 +852,8 @@ cxgb_port_attach(device_t dev) device_get_nameunit(dev)); TASK_INIT(&p->start_task, 0, cxgb_start_proc, ifp); - + t3_sge_init_port(p); + return (0); } @@ -822,7 +865,8 @@ cxgb_port_detach(device_t dev) p = device_get_softc(dev); PORT_LOCK(p); - cxgb_stop_locked(p); + if (p->ifp->if_drv_flags & IFF_DRV_RUNNING) + cxgb_stop_locked(p); PORT_UNLOCK(p); mtx_destroy(&p->lock); @@ -835,9 +879,9 @@ cxgb_port_detach(device_t dev) ether_ifdetach(p->ifp); if_free(p->ifp); - destroy_dev(p->port_cdev); - - + if (p->port_cdev != NULL) + destroy_dev(p->port_cdev); + return (0); } @@ -1007,7 +1051,7 @@ cxgb_link_start(struct port_info *p) t3_init_rx_mode(&rm, p); t3_mac_reset(mac); - t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN); + t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); t3_mac_set_address(mac, 0, p->hw_addr); t3_mac_set_rx_mode(mac, &rm); t3_link_start(&p->phy, mac, &p->link_config); @@ -1060,7 +1104,7 @@ offload_tx(struct toedev *tdev, struct mbuf *m) critical_enter(); ret = t3_offload_tx(tdev, m); critical_exit(); - return ret; + return (ret); } static int @@ -1135,9 +1179,6 @@ bind_qsets(adapter_t *sc) { int i, j; - if (singleq) - return; - for (i = 0; i < (sc)->params.nports; ++i) { const struct port_info *pi = adap2pinfo(sc, i); @@ -1229,23 +1270,13 @@ static void cxgb_down(struct adapter *sc) { int i; - + t3_sge_stop(sc); + ADAPTER_LOCK(sc); t3_intr_disable(sc); + ADAPTER_UNLOCK(sc); - for (i = 0; i < SGE_QSETS; i++) { - if (sc->msix_intr_tag[i] != NULL) { - bus_teardown_intr(sc->dev, sc->msix_irq_res[i], - sc->msix_intr_tag[i]); - sc->msix_intr_tag[i] = NULL; - } - if (sc->msix_irq_res[i] != NULL) { - bus_release_resource(sc->dev, SYS_RES_IRQ, - sc->msix_irq_rid[i], sc->msix_irq_res[i]); - sc->msix_irq_res[i] = NULL; - } - } - + if (sc->intr_tag != NULL) { bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag); sc->intr_tag = NULL; @@ -1257,10 +1288,17 @@ cxgb_down(struct adapter *sc) sc->irq_res); sc->irq_res = NULL; } + + if (sc->flags & USING_MSIX) + cxgb_teardown_msix(sc); callout_drain(&sc->sge_timer_ch); - taskqueue_drain(sc->tq, &sc->slow_intr_task); - taskqueue_drain(sc->tq, &sc->timer_reclaim_task); + if (sc->tq != NULL) + taskqueue_drain(sc->tq, &sc->slow_intr_task); + for (i = 0; i < sc->params.nports; i++) + if (sc->port[i].tq != NULL) + taskqueue_drain(sc->port[i].tq, &sc->port[i].timer_reclaim_task); + } static int @@ -1315,7 +1353,7 @@ offload_close(struct toedev *tdev) struct adapter *adapter = tdev2adap(tdev); if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT)) - return 0; + return (0); /* Call back all registered clients */ cxgb_remove_clients(tdev); @@ -1330,7 +1368,7 @@ offload_close(struct toedev *tdev) ADAPTER_UNLOCK(adapter); cxgb_offload_deactivate(adapter); - return 0; + return (0); } static void @@ -1363,8 +1401,8 @@ cxgb_init_locked(struct port_info *p) t3_intr_clear(sc); setbit(&p->adapter->open_device_map, p->port); - ADAPTER_UNLOCK(p->adapter); + if (is_offload(sc) && !ofld_disable) { err = offload_open(p); if (err) @@ -1372,6 +1410,9 @@ cxgb_init_locked(struct port_info *p) "Could not initialize offload capabilities\n"); } cxgb_link_start(p); + t3_link_changed(sc, p->port); + ifp->if_baudrate = p->link_config.speed * 1000000; + t3_port_intr_enable(sc, p->port); callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz, @@ -1388,7 +1429,7 @@ cxgb_set_rxmode(struct port_info *p) struct cmac *mac = &p->mac; mtx_assert(&p->lock, MA_OWNED); - + t3_init_rx_mode(&rm, p); t3_mac_set_rx_mode(mac, &rm); } @@ -1400,13 +1441,11 @@ cxgb_stop_locked(struct port_info *p) mtx_assert(&p->lock, MA_OWNED); mtx_assert(&p->adapter->lock, MA_NOTOWNED); - + ifp = p->ifp; t3_port_intr_disable(p->adapter, p->port); - PORT_LOCK(p); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - PORT_UNLOCK(p); p->phy.ops->power_down(&p->phy, 1); t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); @@ -1421,6 +1460,27 @@ cxgb_stop_locked(struct port_info *p) } static int +cxgb_set_mtu(struct port_info *p, int mtu) +{ + struct ifnet *ifp = p->ifp; + int error = 0; + + if ((mtu < ETHERMIN) || (mtu > ETHER_MAX_LEN_JUMBO)) + error = EINVAL; + else if (ifp->if_mtu != mtu) { + PORT_LOCK(p); + ifp->if_mtu = mtu; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + callout_stop(&p->adapter->cxgb_tick_ch); + cxgb_stop_locked(p); + cxgb_init_locked(p); + } + PORT_UNLOCK(p); + } + return (error); +} + +static int cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) { struct port_info *p = ifp->if_softc; @@ -1434,30 +1494,23 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) */ switch (command) { case SIOCSIFMTU: - if ((ifr->ifr_mtu < ETHERMIN) || - (ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO)) - error = EINVAL; - else if (ifp->if_mtu != ifr->ifr_mtu) { - PORT_LOCK(p); - ifp->if_mtu = ifr->ifr_mtu; - t3_mac_set_mtu(&p->mac, ifp->if_mtu + ETHER_HDR_LEN); - PORT_UNLOCK(p); - } + error = cxgb_set_mtu(p, ifr->ifr_mtu); break; case SIOCSIFADDR: case SIOCGIFADDR: + PORT_LOCK(p); if (ifa->ifa_addr->sa_family == AF_INET) { ifp->if_flags |= IFF_UP; - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - cxgb_init(p); - } + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + cxgb_init_locked(p); arp_ifinit(ifp, ifa); } else error = ether_ioctl(ifp, command, data); + PORT_UNLOCK(p); break; case SIOCSIFFLAGS: + PORT_LOCK(p); if (ifp->if_flags & IFF_UP) { - PORT_LOCK(p); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { flags = p->if_flags; if (((ifp->if_flags ^ flags) & IFF_PROMISC) || @@ -1467,10 +1520,8 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) } else cxgb_init_locked(p); p->if_flags = ifp->if_flags; - PORT_UNLOCK(p); } else { - callout_drain(&p->adapter->cxgb_tick_ch); - PORT_LOCK(p); + callout_stop(&p->adapter->cxgb_tick_ch); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { cxgb_stop_locked(p); } else { @@ -1479,10 +1530,8 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) sc->params.stats_update_period * hz, cxgb_tick, sc); } - PORT_UNLOCK(p); } - - + PORT_UNLOCK(p); break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: @@ -1527,7 +1576,6 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) error = ether_ioctl(ifp, command, data); break; } - return (error); } @@ -1539,7 +1587,7 @@ cxgb_start_tx(struct ifnet *ifp, uint32_t txmax) struct port_info *p = ifp->if_softc; struct mbuf *m0, *m = NULL; int err, in_use_init; - + if (!p->link_config.link_ok) return (ENXIO); @@ -1598,13 +1646,12 @@ cxgb_start_tx(struct ifnet *ifp, uint32_t txmax) IFQ_UNLOCK(&ifp->if_snd); } } - if (err == 0 && m == NULL) { - return (ENOBUFS); - } - if ((err == 0) && (txq->size <= txq->in_use + TX_MAX_DESC) && + if (err == 0 && m == NULL) + err = ENOBUFS; + else if ((err == 0) && (txq->size <= txq->in_use + TX_MAX_DESC) && (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return (ENOSPC); + err = ENOSPC; } return (err); } @@ -1616,18 +1663,18 @@ cxgb_start_proc(void *arg, int ncount) struct port_info *pi = ifp->if_softc; struct sge_qset *qs; struct sge_txq *txq; - int error = 0; + int error; qs = &pi->adapter->sge.qs[pi->first_qset]; txq = &qs->txq[TXQ_ETH]; - while (error == 0) { + do { if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC) taskqueue_enqueue(pi->adapter->tq, - &pi->adapter->timer_reclaim_task); + &pi->timer_reclaim_task); error = cxgb_start_tx(ifp, TX_START_MAX_DESC); - } + } while (error == 0); } static void @@ -1643,7 +1690,7 @@ cxgb_start(struct ifnet *ifp) if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC) taskqueue_enqueue(pi->adapter->tq, - &pi->adapter->timer_reclaim_task); + &pi->timer_reclaim_task); err = cxgb_start_tx(ifp, TX_START_MAX_DESC); @@ -1672,6 +1719,18 @@ cxgb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) ifmr->ifm_status |= IFM_ACTIVE; + switch (p->link_config.speed) { + case 10: + ifmr->ifm_active |= IFM_10_T; + break; + case 100: + ifmr->ifm_active |= IFM_100_TX; + break; + case 1000: + ifmr->ifm_active |= IFM_1000_T; + break; + } + if (p->link_config.duplex) ifmr->ifm_active |= IFM_FDX; else @@ -1718,8 +1777,9 @@ check_link_status(adapter_t *sc) for (i = 0; i < (sc)->params.nports; ++i) { struct port_info *p = &sc->port[i]; - if (!(p->port_type->caps & SUPPORTED_IRQ)) + if (!(p->port_type->caps & SUPPORTED_IRQ)) t3_link_changed(sc, i); + p->ifp->if_baudrate = p->link_config.speed * 1000000; } } @@ -1745,7 +1805,8 @@ check_t3b2_mac(struct adapter *adapter) else if (status == 2) { struct cmac *mac = &p->mac; - t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN); + t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN + + ETHER_VLAN_ENCAP_LEN); t3_mac_set_address(mac, 0, p->hw_addr); cxgb_set_rxmode(p); t3_link_start(&p->phy, mac, &p->link_config); @@ -1773,9 +1834,9 @@ cxgb_tick(void *arg) * port lock */ ADAPTER_UNLOCK(sc); + if (p->rev == T3_REV_B2) check_t3b2_mac(sc); - } static int @@ -1785,6 +1846,18 @@ in_range(int val, int lo, int hi) } static int +cxgb_extension_open(struct cdev *dev, int flags, int fmp, d_thread_t *td) +{ + return (0); +} + +static int +cxgb_extension_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +{ + return (0); +} + +static int cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data, int fflag, struct thread *td) { diff --git a/sys/dev/cxgb/cxgb_offload.c b/sys/dev/cxgb/cxgb_offload.c index a6d7a99..35e7fb6 100644 --- a/sys/dev/cxgb/cxgb_offload.c +++ b/sys/dev/cxgb/cxgb_offload.c @@ -720,8 +720,14 @@ static int do_hwtid_rpl(struct toedev *dev, struct mbuf *m) { union opcode_tid *p = cplhdr(m); - unsigned int hwtid = G_TID(ntohl(p->opcode_tid)); + unsigned int hwtid; struct toe_tid_entry *toe_tid; + + printf("do_hwtid_rpl m=%p\n", m); + return (0); + + + hwtid = G_TID(ntohl(p->opcode_tid)); toe_tid = lookup_tid(&(TOE_DATA(dev))->tid_maps, hwtid); if (toe_tid->ctx && toe_tid->client->handlers && @@ -1115,7 +1121,7 @@ process_rx(struct toedev *dev, struct mbuf **m, int n) { while (n--) { struct mbuf *m0 = *m++; - unsigned int opcode = G_OPCODE(ntohl(m0->m_pkthdr.csum_data)); + unsigned int opcode = G_OPCODE(ntohl(m0->m_pkthdr.csum_data)); int ret = cpl_handlers[opcode] (dev, m0); #if VALIDATE_TID diff --git a/sys/dev/cxgb/cxgb_offload.h b/sys/dev/cxgb/cxgb_offload.h index 2e4b44b..fdfea35 100644 --- a/sys/dev/cxgb/cxgb_offload.h +++ b/sys/dev/cxgb/cxgb_offload.h @@ -130,7 +130,7 @@ typedef int (*cpl_handler_func)(struct toedev *dev, struct mbuf *m); */ static inline void *cplhdr(struct mbuf *m) { - return m->m_data; + return mtod(m, uint8_t *); } void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h); diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index 4bd2a91..676ab09 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -307,7 +307,7 @@ get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void switch (sopeop) { case RSPQ_SOP_EOP: m->m_len = m->m_pkthdr.len = len; - memcpy(m->m_data, resp->imm_data, len); + memcpy(mtod(m, uint8_t *), resp->imm_data, len); break; case RSPQ_EOP: memcpy(cl, resp->imm_data, len); @@ -666,6 +666,7 @@ static void sge_timer_cb(void *arg) { adapter_t *sc = arg; + struct port_info *p; struct sge_qset *qs; struct sge_txq *txq; int i, j; @@ -680,11 +681,11 @@ sge_timer_cb(void *arg) refill_rx = ((qs->fl[0].credits < qs->fl[0].size) || (qs->fl[1].credits < qs->fl[1].size)); if (reclaim_eth || reclaim_ofl || refill_rx) { - taskqueue_enqueue(sc->tq, &sc->timer_reclaim_task); - goto done; + p = &sc->port[i]; + taskqueue_enqueue(p->tq, &p->timer_reclaim_task); + break; } } -done: callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc); } @@ -694,24 +695,31 @@ done: * */ int -t3_sge_init_sw(adapter_t *sc) +t3_sge_init_adapter(adapter_t *sc) { - callout_init(&sc->sge_timer_ch, CALLOUT_MPSAFE); callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc); - TASK_INIT(&sc->timer_reclaim_task, 0, sge_timer_reclaim, sc); TASK_INIT(&sc->slow_intr_task, 0, sge_slow_intr_handler, sc); return (0); } +int +t3_sge_init_port(struct port_info *p) +{ + TASK_INIT(&p->timer_reclaim_task, 0, sge_timer_reclaim, p); +} + void t3_sge_deinit_sw(adapter_t *sc) { + int i; + callout_drain(&sc->sge_timer_ch); - if (sc->tq) { - taskqueue_drain(sc->tq, &sc->timer_reclaim_task); + if (sc->tq) taskqueue_drain(sc->tq, &sc->slow_intr_task); - } + for (i = 0; i < sc->params.nports; i++) + if (sc->port[i].tq != NULL) + taskqueue_drain(sc->port[i].tq, &sc->port[i].timer_reclaim_task); } /** @@ -736,38 +744,34 @@ refill_rspq(adapter_t *sc, const struct sge_rspq *q, u_int credits) static void sge_timer_reclaim(void *arg, int ncount) { - adapter_t *sc = arg; - int i, nqsets = 0; + struct port_info *p = arg; + int i, nqsets = p->nqsets; + adapter_t *sc = p->adapter; struct sge_qset *qs; struct sge_txq *txq; struct mtx *lock; struct mbuf *m_vec[TX_CLEAN_MAX_DESC]; int n, reclaimable; - /* - * XXX assuming these quantities are allowed to change during operation - */ - for (i = 0; i < sc->params.nports; i++) - nqsets += sc->port[i].nqsets; for (i = 0; i < nqsets; i++) { qs = &sc->sge.qs[i]; txq = &qs->txq[TXQ_ETH]; reclaimable = desc_reclaimable(txq); if (reclaimable > 0) { - mtx_lock(&txq->lock); + mtx_lock(&txq->lock); n = reclaim_completed_tx(sc, txq, TX_CLEAN_MAX_DESC, m_vec); mtx_unlock(&txq->lock); - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) m_freem_vec(m_vec[i]); - } - if (qs->port->ifp->if_drv_flags & IFF_DRV_OACTIVE && + + if (p->ifp->if_drv_flags & IFF_DRV_OACTIVE && txq->size - txq->in_use >= TX_START_MAX_DESC) { - qs->port->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - taskqueue_enqueue(qs->port->tq, &qs->port->start_task); + p->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + taskqueue_enqueue(p->tq, &p->start_task); } - } - + } + txq = &qs->txq[TXQ_OFLD]; reclaimable = desc_reclaimable(txq); if (reclaimable > 0) { @@ -775,9 +779,8 @@ sge_timer_reclaim(void *arg, int ncount) n = reclaim_completed_tx(sc, txq, TX_CLEAN_MAX_DESC, m_vec); mtx_unlock(&txq->lock); - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) m_freem_vec(m_vec[i]); - } } lock = (sc->flags & USING_MSIX) ? &qs->rspq.lock : @@ -1149,7 +1152,7 @@ t3_encap(struct port_info *p, struct mbuf **m) pkthdr = &tmp[0]; m_copydata(m0, 0, TCPPKTHDRSIZE, pkthdr); } else { - pkthdr = m0->m_data; + pkthdr = mtod(m0, uint8_t *); } if (__predict_false(m0->m_flags & M_VLANTAG)) { @@ -1178,7 +1181,7 @@ t3_encap(struct port_info *p, struct mbuf **m) m_set_priority(m0, txqs.pidx); if (m0->m_len == m0->m_pkthdr.len) - memcpy(&txd->flit[2], m0->m_data, mlen); + memcpy(&txd->flit[2], mtod(m0, uint8_t *), mlen); else m_copydata(m0, 0, mlen, (caddr_t)&txd->flit[2]); @@ -1343,7 +1346,7 @@ static int ctrl_xmit(adapter_t *adap, struct sge_txq *q, struct mbuf *m) { int ret; - struct work_request_hdr *wrp = (struct work_request_hdr *)m->m_data; + struct work_request_hdr *wrp = mtod(m, struct work_request_hdr *); if (__predict_false(!immediate(m))) { m_freem(m); @@ -1547,6 +1550,9 @@ t3_sge_stop(adapter_t *sc) int i; t3_set_reg_field(sc, A_SG_CONTROL, F_GLOBALENABLE, 0); + if (sc->tq == NULL) + return; + for (i = 0; i < SGE_QSETS; ++i) { struct sge_qset *qs = &sc->sge.qs[i]; @@ -2105,12 +2111,12 @@ err: void t3_rx_eth(struct port_info *pi, struct sge_rspq *rq, struct mbuf *m, int ethpad) { - struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(m->m_data + ethpad); + struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad); struct ifnet *ifp = pi->ifp; - DPRINTF("rx_eth m=%p m->m_data=%p p->iff=%d\n", m, m->m_data, cpl->iff); + DPRINTF("rx_eth m=%p m->m_data=%p p->iff=%d\n", m, mtod(m, uint8_t *), cpl->iff); if (&pi->adapter->port[cpl->iff] != pi) - panic("bad port index %d m->m_data=%p\n", cpl->iff, m->m_data); + panic("bad port index %d m->m_data=%p\n", cpl->iff, mtod(m, uint8_t *)); if ((ifp->if_capenable & IFCAP_RXCSUM) && !cpl->fragment && cpl->csum_valid && cpl->csum == 0xffff) { @@ -2130,7 +2136,7 @@ t3_rx_eth(struct port_info *pi, struct sge_rspq *rq, struct mbuf *m, int ethpad) #endif m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.header = m->m_data + sizeof(*cpl) + ethpad; + m->m_pkthdr.header = mtod(m, uint8_t *) + sizeof(*cpl) + ethpad; m_explode(m); /* * adjust after conversion to mbuf chain @@ -2215,7 +2221,6 @@ done: return (ret); } - /** * handle_rsp_cntrl_info - handles control information in a response * @qs: the queue set corresponding to the response @@ -2239,7 +2244,7 @@ handle_rsp_cntrl_info(struct sge_qset *qs, uint32_t flags) qs->txq[TXQ_ETH].processed += credits; if (desc_reclaimable(&qs->txq[TXQ_ETH]) > TX_START_MAX_DESC) taskqueue_enqueue(qs->port->adapter->tq, - &qs->port->adapter->timer_reclaim_task); + &qs->port->timer_reclaim_task); } credits = G_RSPD_TXQ2_CR(flags); @@ -2361,8 +2366,8 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget) } if (eop) { - prefetch(rspq->m->m_data); - prefetch(rspq->m->m_data + L1_CACHE_BYTES); + prefetch(mtod(rspq->m, uint8_t *)); + prefetch(mtod(rspq->m, uint8_t *) + L1_CACHE_BYTES); if (eth) { t3_rx_eth_lro(adap, rspq, rspq->m, ethpad, @@ -2388,7 +2393,6 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget) } --budget_left; } - deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered); t3_lro_flush(adap, qs, &qs->lro); @@ -2520,9 +2524,8 @@ t3_lro_enable(SYSCTL_HANDLER_ARGS) enabled = sc->sge.qs[0].lro.enabled; err = sysctl_handle_int(oidp, &enabled, arg2, req); - if (err != 0) { + if (err != 0) return (err); - } if (enabled == sc->sge.qs[0].lro.enabled) return (0); @@ -2530,9 +2533,8 @@ t3_lro_enable(SYSCTL_HANDLER_ARGS) for (j = 0; j < sc->port[i].nqsets; j++) nqsets++; - for (i = 0; i < nqsets; i++) { + for (i = 0; i < nqsets; i++) sc->sge.qs[i].lro.enabled = enabled; - } return (0); } diff --git a/sys/dev/cxgb/t3fw-4.0.0.bin.gz.uu b/sys/dev/cxgb/t3fw-4.0.0.bin.gz.uu deleted file mode 100644 index fae25c0..0000000 --- a/sys/dev/cxgb/t3fw-4.0.0.bin.gz.uu +++ /dev/null @@ -1,483 +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.0.0.bin.gz -M'XL("'+5*D8``W0S9G<M-"XP+C`N8FEN`.R\"UQ35]HOO+,32+*S0RX$#,@E -M"0%V[E%;+ZVU:)W:5N<5V]IA:J=E3+#J:+4=6ZU:000:[A$1$R"`U"O>B&6L -M%MMNT"(J;1%:JX9P4>NE"EYJ;S/*_IZU`];VG9G?>[[?^9WO?.>\T;7WVFNO -MR[/6>B[_9ZVU2<5XV`4,D\H9AE!A&):*/87U87@6QL?0W8%Q,*P78T,-1+&I -M4Z<FH><+&"?LES@O2<7IO9\/A[L*2ZFF,>SB*.S;45C_**QF%+9Y%(9CM!J_ -M-(J#8\VJ.`);3(68QEE-XQXRC1MO&C<Q[C$.Y&A2T59X81F'6<9)+>-4EG'6 -MP`L-(0V421R')8Z3)HY3);*ON#@F9SI#F4X2QS:HY$S'`U%ZU`95)D3:0YE3 -M**$]C#D5SIRBK5^K@N9Q4C$%;VP05,V1X?#_S5$*_C1%T!B2SWOBK5$7X=6; -M$_HQ5'M+&--"6_%$/!4+NI^%-PG>WV1;IT^HUJFRU-F:96."VQYO^U,J)LM) -M;IA=9HV;R%LVYCN-D;0Q?CGS01R1L7@"'YK:H-(8D]BJWZ='<\U!;"W>4,:[ -M025CO(04^^_??__^5_Q`3KO^;8;3HZ3,C\2_?!U[-Q`N8,%;_F6<H3$4_GF\ -M^4P@WGPF$!>NAGMO+'.B#>)9*I9&3L8%3+8"W2%D7<#D/ZE`>"!$0?PNND-0 -M7<!"E>@.82+$4=I$"$D0'X_N$&9`'*7-@)`,\:?0'<)+$$=I+T%(A7@*ND-8 -M!'&4M@C"4HC/1W<(!1!':05#<0?<G1!V#\5W#\6WP+U=A7'K`W%N?2"NR/K? -M,YYJ"<13+8'XZ[S_K^*_YM&7M;',%S28*A7P13O$5P3H?;X&\FM[P>:@`K', -MT8LJ[+F;D`YC_DH#Y/TRP$O--R&.[D=C[PYBF(1AD(T*@I`$(0/#(KH9!NO> -M\_&-R?#\,&J4!J,(6:SH?2J&+67IP(09+-/_A,K$0.!@`@S]Q\00E($\;$$2 -M*HZ"P$MB'S$2`I=MBX<%L[VR8CT8HD)`,I\P#-,#H9?/H-I^POA,1BP0I&+M -M*9\+KQB4>)//,(-<)AT>CT`8+A;+'+E9$^A';"I;MR`C&9I#.=C.,C>QK8'Q -MR8+@#%`M4JDL3`8S"#5##@PS8E`&1]3&,JU*U!-4.X8Q-SB8#)7=#&$]P]Q` -M:?^(93Z&,6VF&>9']'P/QO<,QOD'S,V)KECF6%<?AG1&HK0/>JNR!C`$C+T5 -MPE*H9P/D`7D_!G6T\OJ`G#[4-+?=:4BV91B2WX;@A+`M`]J6(`RBL@RB>C*` -M9J@)Z.4P/QF2O=!EYD=X+X4X9DC>#^$C"NY0]J,:2)<9DC^$M,,9?3#N?0!J -M>J&=/G;F,Z!/QX`_CO7&WL,$<+\#M`C\\(-[%-#MA'`=LJII=NQ:C2KLA3,0 -M$"^!/GD!=-`+4R'88YGC1DBS`E^F0C-J%?8'&#WN82ASD/D'`_SXTJ<J[$_Q -M$#J!ET,A[V$5QGO^O@YE3K0^R.^<W^A8E11+NA\4,`;`3/?#<-IP4&*T*HJ# -MW0\J3A*;-AQ0VF^?49Y?0NJO@I8#,C;CXJ_#]*X'0M104*BP9^#^-(S--*T* -M^UWO+_([HP%"QM`=PO1_%LC`?9I=A3W9"^5+?RG/.ZK"K)5PA_>3X1T/QF_" -M=;B#GGT<]+&J586-A?2'#D(^H,$,NE9O56':U2IL-(Q_]#(5%@ETAP*-<L@C -M%4"`>L5`DPAL`+(SOUL4"$%`!Q]TT22P!P^#;>"U(1I&VP.TH+O]-__^9_Q` -M)GH#]Y8VX$70=\=6_T^I^+]___W[W_`'_'XE8!G_V>^?I#\1E_%?J3>@E_^P -M94@___3K]/\K`FN3ANX04D#_O?S`\__987B^$61"MGHH_CC<,AYX_@1N20\\ -M(U"A^LVS]#?/@M\\\W[SC/_FF8/PP%!\..V7WTNEG#^5XB^7<E\IQ9[XKW#V -M;WXO.3E_<N(O.[FO.+'G_E^4KRS%HIT<3RE>5<JM+N4)2H.$I<%$*5_T7R2G -M$@H[\2HG/]K)K7;R5CB#WG8&KW3R5_T7R>EBV_>7XMVEW)Y2'J\T**@T.+B4 -MSR\5"$J%PE*"*!7].UJZH+`3[W:*H/T>)Z_!&?0W9_`!)_\#I^"@4WC(27SH -M%#7^:UI`)OZHCCI3*8]BN@GZ/[]'F$X=Y2Q1;`@+9>[A5ZREX=PX8IUUXPC" -M&B@_6X%U@&\\2`S5-_LEK/-7SY78E[]Z_@G[ZI?G_Y%?D`*S,3__#Q?[_\UO -MD32((\-3PBM.2=!*'(W1:@P?A3\]"GL*+172F.P&&7I#S&47#I4W1"-OD+13 -M\"'YSG:!+@>C"GCZW7=7;R?<&;H<#E4@T._^B7A&L7BGR)WA7NO.U.5PJ0*I -MX@;&3\(4`TSX``,1^0`3.L!L4-&I]%+EP*!B8)#*#&2X!U>6)EPQ\`\4Y[&# -MOTC*HZWR@1\S57]5XZG8HW12Z,#WZZSKK,M&)88/?!<V<#L[N6'VQE3%P,VL -M).WO&>V4QT5)&+TT?.!ZPEP,_B]?\+5RX`K]>F(.!MU$]:$;6Z\*8@\\__9. -MU^@(GD$30VFB==I@?3R^*A<G=N''&T,'3G=*C/5\<SU&G^(.$.;S4\^I1+V8 -MKR9MWV6V5E1>H%?C"03VYG:IXR'=Z*#T=P7IU4'!"W&HB!!-;_VH[0_G5#YK -M5U**^`PJ,W+@B'E_%7UF32>>RBDW[??TM-M/N1)5)$UODI++9;O6Z,[G4`3Q -M]CIX;]*=SXX9.&A?KZ5&<P0.18B#LV2MENZC.RDUK^H[@4,F=N#1`U[7+<]- -M$L>H_1[37255H*0.>-Y]B+Z8OOPAY<"NXH>[>F,&ZBK75SF+5&6E@@&\JH0^ -MKQS85K71M4$B2)(X9%09/_U'@>493+(/M\3C:Y8'4:/$5+SFG>5!^E$2?;QZ -M]?+Q^HDJ"\&A"$S\TWB!8(H]8ZUR8%/LP"9+SB2LQH&U%SQX!6+T^SWZW4K] -M`4^>=?GV"18UKW!,T6@Z2WA,U-#F>ETYD,=C9*ZE#D/56Y[ET0/OEKT)77&] -M0;B2@ATR`8-31!1<+6_QCM-Z%4G6R41U`EUMMO"X2+<M.RWY#5H%;CY00[#4 -MI!6_;F.61PW\13FPD-Y<*#5K8G:O!B)T^S.Q4SRL+I):BPMWXKH#F9`HN#BJ -MF*ZZ64CG-C?X/?0[[B!S,\?<@EG4>*#_ML&G.R4F`K,-_ME`!.-Z/"5DJVWP -M8;UQF2\I):2TH^:49)&4.&V-,R[;$!HZ,#,56Q@Y,/UH1LS`,\!'T()E=*:Y -M#T?TCT4-AEP<5;BGHCUWCV-?@UNW3?QV+K=X;_4>G1K7$TF$&]?%XY\_GYLJ -M7#!K_@:8]2G`,*F(86;0]:?K6S^@9V5YZ==YO&G\U;B]248OI=2XD<`$@NEI -MQ2VZN1B46[#A(_WHJB7;<!NSS#S:T_"4_<8B&#;#C,%R.8S=>_MTMW/\]2Q/ -M_5%W.]N^_CFZB5X7.:"!>:F\4-XK8-"85_<!L<;1'OTBJ;%-:1SK29OU5I?3 -M3'`L!":\,5XBF6*_618S$*$<B*`N35KHC4S_(`C--UT@BE4L_ED4B`>N>@(K -M2`T;D"T_-MUA,ZEY[\X5?BRBI\8.D*5]U;U9ADV77)=Y?EG05+ST/'VS^ANR -M.BF8D4G\>-,]N'@NZE1D1PWIEKWGIDJR&SX2G!%19=FG))`\G-A1,YR(Y`I( -M)%@2TYB7;,Q<MW1^R1]RM4:5Q*`*\;89M9+Z&5L:ZQL-VI"#?Z&<?+V3N\7A -MK=.7<NL=5"D_+S1%*"V4SC\%NL=#]^9K]2J)LO^"OH&K4X44U^L:^&AXZJNT -MML%%G9*A^2$OEFNUVA#::]!*Z'K;X+/1_2=I+Z6)*9+OV1/@`JR/AS5&QO0? -ME7R"`T?<9X?<=I>SN+VHHX&I;D^_&F3NX)A/L_SW"<M_]V[DA7H4;EE%&+V_ -M0.8'5G@O/ZQ0D2NS#>Z$ENY=`;T33*F"@8,6.!1"X?3CZ^^K&?)C5C3@?V3_ -M3D-M54S_UB4'8-XQ4ZV'?MW>_I,%=$T+^8.L[B^Z_3ET$<L4<;K]V<K^:OOZ -M2%`NMD10+IVN=D&Z+!AZ?2IGK+*_-+A8$1P\+;J_VI'E61_=7[7/$=M?A436 -M6:@7SI,&^W$T;24)5KG%:J2LH20CY3FDP?.D@GFX)!U'%6TH?,13ZACGVI@S -M/KK?65:64.LIGI"P2%F]R?%P587+!0H.55A>:$W8YEG^]3AE?V9,?T;!F+S1 -M])UJ3U5ECL%8%DJ?T)?)Z1JHM:Q*7R83LVS#6R.3#"#.&<#-95(88E899@M: -M1=0!4!:Y&@*-1W3_W*.TA1500VVFK@\G&W'#-C0CPHNC'/[JC'Q_;D]#8X5_ -ME9M7U&T^+88)(9F`0J@&PQG5_SQVBV<"U;((6Q6)FF!K$1S$J?NUT)Z,7-K1 -MW.!VTV_G!IF:.:86S*S&0S[&S:B:E(`.$:\+Z!"!7A5L4./S=_#F;^><DH@$ -MTUN+T41V)?FL*>2,`-DQ_>-TYZN6E,$T)5O.>VB__=938"]8:['W+=W<G*9L -M=@X?-\[-YDX`#3&6?EW9;RR5:]4\U\U-W]%_%3PEX\/`WGK79%%'*_LM_!^% -M@N7X)GI$OX4Z[]G4E&B5@M$@ETOY4_$1_0;JD@<BI<WO/IPEMR]]JMOJD?GI -M].5A#1.*)E"CPZN.N5H*QYDG2DTM`E,;R5<J%N>J35W*@^ZX$H7CZH9VURG' -MY77]K@ZJ)&S#EZ[.==?,UU4;OBJ4T0_1O5Y&(IGYEV7CZ(?X;PM)-\$?1_*Y -MDX^/KG(==M>/:7V$O8]OS41WR$/)%^>)JJK,9;(J5U6%KM*J[`^*:PD=<?T' -MG3HJL45NB8].U&#I[B`0?W-\M+EE!-42'G']7A`CL[0H8Z]?T[6$`?=96A3S -MM[^*9FQN-E(:\X`IMK!B,J3?Q2;;8/;(ZUT1U\_1FX%%"J6[5@4,A^E\IFX] -M+MZ#FRX-SW%]=49A?>Y^L!WUR';LYY@//&@['LNE*$WPVVMG-G5:6J+,+3'F -M%C5=$GG].)VE:XF+N'Y:WZ+1MT1&7O]*UQ*M;XFE6D8JKW?2FZF6>.7U#N)# -M7+`"IUJT@!]LS/0`OY`_(GZA78!/;,PXX!N=*AB,P'P7;_XFX!NP!*V%]Q6` -MZ&.D#PTJ,OSZ3O)#V;8Z8VV.CB!7(]-RW%B;;6\Z8IA;Q>J$3PUS/4T%=N]' -M.K5*F)%J4DT\QF#\21QBDG<O_]L)1)U0O%=FOAX5$C)9,L#U#L`]I$ZDWQWU -M=<V:KZ-,ZGA+Y-V5OE#Q7E+2EXH))W'XD[PKA.].()83N0F4AB]TD,OSH9U* -M^HQ>'6=6J[UU!#%3'Q^W\IJ\?C=POC$^3@Q"B+HZJ5-"M],WZ9)2.=VGO+YZ -M8R@]-1X4T?NN>GJ=8+9,D(*[O)1J8IZ5E\7AW1@O8*1"!T?0/Y[OEX+J(8J3 -MB/(D?IV4LDIII[9@D'=UO.3&!!$C)=Q2B1L7N_%B@PFZR>`Z=;S8I!#J%(KK -MRP6S<1ZH)CI+!=I*,%4FF(K3>7`I;2K6\]RRZJ/0(A05C$\*<D@)!RX$.6K1 -MJB;R'DHBIK+6ZUCQ&#JC^DCA:%=KU7%/LTZC:'K)6ZY/4&S\U'72?2)K?&E; -M\2/5GQ4]6O5YX03/%WD/Q\_UZ%NDN6/C7U+J6F2.<?'S/%2+7`N&;:ILVU3+ -ME.SL4,O=9,N3V5GRXTOS$G)UV^OT"<&$FQ0*G]+%QZ<E+V$Y%[$MF6X;#.Z4 -M1%TW'*U17C>86=VFFYL):`?!BGG#:.<S0#N?Y7\!'/O9.X>XN9^[/X.Q)P(# -M?^_32MDY5864OPI/"?YC@2Q?2K>#R2=@^OO'IW5/M=W;,L2$+R`F_!6F)KEC -M<1AOX,8%[\(TEPPS)-@E>JF0F'Y\VV?)R%CR9N`I(F7B%BY+.<N>H[%E'TB- -MZC@3P6L])O;@)L0#[1'7[II+JI9<@LI>TI=X[)M?T(<3].UC^X"=E=>^)P_+ -M=K3IF@$?2UF5]X2Q&=CY,8/:4C1/=&TL\*_=N\.B5DGJ66Z43/+^)"R>(&&$ -M(D8D$4PF'%RO0R"8O(.1_!T`)KZB'?%PNB^<BKPK_CLIV,R6`N;?(<R;(*DC -M"A-T&K[83:ZL@+:R"FV>([ESW<V.-%>K)56ZX$?`"B<W':<T2HLFM`(FN_K$ -MFD:45A[165.AH-?&7CM)7RB,K`PS@B+NK&X7M,E"VO#*4U'7CNA2I89FCWXN -MWW!8:6CQG-P7<ZT3#51!6+'"E,IU2TF_3+Q88.I2I7!^-FM"$Q.4W@%S0FCK -MXXZ$8MU[#E>"@"$EDJ<LP`^S@M&`FA:I8JXUNZ7#M:1PMMB8HYV2)1M!);UV -MM#>@'/S)*8*`+CF`^$=TPS;X$AOIMPT^5_$IO1Y$\';U<0\P[IKW84+&5(95 -M*,HC[,E[Z=Y`S=!S(+!:6JSP*('(/8M9&MMS%47*PHB]>\UV;D%"OFY/&]E( -MBD1/52;DS3/$QPOKR/)Y,%#T;:%#0"4H;8-&L*?48:4K'*:#R.,BO3!9'\X' -MD`].0_H9H'DM3,W*3HBL<(07C]C!@/&$,@%ZSJD,<F%*T-ZT/55Y$?F*@K"B -M>;;!EP-L*MJ-^C>D"XE5IVOH6<!X-N8QQ+<(<JOC`##I=S,!332_]+$%KH<- -M:O6J71;`K(#?C9IHY`0>Y_AJP`>\-OO?^8#`S6G[/H:!7B15G+::"5XB@8$T -M1%][9KXK:/XF/!4OTZNU]F>YE%JS$C0A_AI0`,VW>EAUC5`D\2PK#YJPO-&K -M-D..E07CZ=OVYE7`\;0K;QR=0[@FN&+W%XC!30L/`84NKA.8:W/6'(&\4\V@ -MSL]/,JC->:^*=HT%796HCJ7"Q?;]4_GU#RKD8]7\Y81H.<$73!8."\%R1W1B -M.#\]PT*IXUW*Y?F)FG#%NTK'"$WD7?Z[)/YZ:EQX&,9%56A6<[B)$P3+"8U< -M$2</RTUP)`YI=CR&=KJO..RNJ[GS'&D5W^@NB:A+Q$H0`]P(7$^O7Z=WI`+? -M"_)`.T\0U4D!XTE`:[LF@!+>,#).'0MJF!NGX#ND&Z+6J5P1CEC!&)E@#*Z\ -M)@?U"Y$-D7$:D;W^\\1PI38\/#Y\1/9\>MG&Z_2LBG['PJP%KANE`Z".Z0S^ -M-(YD*H>7,IY.XC\_?L0U;O9(_FS\W8B-%[.C^$BU`QS%%=\."G:`,L<AGA7I -MZBWM@R$+VCBDW@$309%$N7+C):@R7CXBH.1Y1W$)Z/G+6GEX00S,BDZM)1ME -M>QKU^[/KW;OK]`>R*4V8+E[K=5`)8<>7%B84Z+;[30G!XC:2))\R@H0^F\)R -MBGXWA^4Y+>![>BWTAFY(`-*31'_A2.9Q@K/&TZFBG/'Y(RLNYD<Y(D45N*N/ -M/Q7PLS1X*A[^[2G>%ISW$`[QTEXHEA41/#8IB'W':\0K+D%'@$#H"`'N<RLN -M`3MUV<;\ONDS8[S13&0$Y"'H3W@*'^0?B%E0"CKML_EEYY&LI!#]MGO@V#2= -M,<4;;<SG=)\9W5N.%2<>5FR2\_F3!<NYCFCO<HAMDNU:GKA:D>X`TW$'6(<* -M%RQ?!_$K#CDP4*9LAT83S@=&L=W;"_)J#)>9P^4@K^&AOJ4IO":#/#3ZVW5F -MN9R^;93+TG;_F/>J[=Z'G1)]N-0^:RN=D3O?%5K1[[Z>N\"QT#W@NN%8H)=+ -M7=+<A:[PG8?<BE450;E2K]L=3F<!*^C4L0&VT(='`-@%?@4+GJB.!Y[B)RIX -MRV7"Y?BZ\#S%A@7TJ/*%\3#6-8(4CF0V)^B1\8`4Z&3!P^.!/6=+@^IP0792 -MT,,3UAE$LZ7$;#QH#![V[9L"5Q)$-O3FJ;)C!74R2(_\=E'HMXL@LK$O3P]L -MQ:W#RR]"Q7IY1-##24&SI8`G@(<V7H(T8"1((V8CE`#,-,Q#Z]**0AWSWAO8 -M<9`*#P)I6I6/FZ]S1+M(1UA5FFL>")=NNQO$2R!XBHJ/=\2X$RI>!:XC#\GV -M>'0=V:``!&Z![G1V]+>C;/^X'=!YQ!)V3@/9Q&Z!OB1GR78P19F6DFS[S=7T -M>Z'?6DQJ))$BOXS7)A.WX:9GY'"MNA7S;:(_J>IFD6'3]YM^W/1#Y1WN`%YU -M&[E()=E=2PV'58:R;%^27AL,+:40'*1;V0F%B84YY3Z*(]LN5+/S*AZ>U],U -MCNWT+"I<:ALT(/-"S`ZLR0E`3D53^(\HO#M%Y1-T,ZRT5W@PL)IT(_I;;M2W -M7./I20LW1Z9O#\*2'9BS@(A1++XJ"L0#5[H]WTJ7T&OI7C2?=R2O<"1%XP4# -M4N%L#GTSJ'@\GY%*EN`ZN524G62L'"0+QP=E3W`8P#-$,^N7!OGQ$#\.?B:8 -MEZBK]P`(D@[\P&Z]6N5*RE;Q7%($-6?CE)H7]"F^<7*Q7N"054\552>951.A -M[I!)24$#4JCMS7D"O3J6T"M2,1RN/+#7>U#-GB<MJHD"%RYY/(D(+*I,,ZO( -MV*LMY(!LWX#I?+;X,Y'I$EJTN!GT26"]@F=CB$52@J;I;08"2UMZFEY*)].E -M@&:*#/3:=5;A68[PW?&"Y5*=7,$M3I(4(U0+)-"W)7[HM#A[/'\V@#;H*L\O -M%2_&Q;-Q4^6@N'@\P4CY#![$X)"96YT$Y%<E%:IX55*!7X8&80_NF0S#0+9* -M81@2-01T`G0@=#WQ21YT%WK^8'>-ZEC2"-T-,JI5$!%_]N^ZFS?<W8YZ\1[4 -M86!/?U+1K!/G]]=YVTQ=TI`58UW0&EF<[#I;?2;WN>)GW?)JJ=M7?6[-.L+; -M&/^2U+[F!QO35BAWR/84"JZ2NA<X*WS<8JF7\3Q7_:QM\"RRYW;K[X.LJ1@Q -MB2.<Y'41N1,,JHG"&=2Q?;O'<%F\1Q5PP-8)Q@C6?!"K5\<;(^_^=5<X\2A) -M>EGSB$_R4L+,"5P-`?1U6&%6UMN8#UF,2X(=!W@[#&GU:AQL.R&8?CSG%TPK -ML#V(:?.M.H*W[`,8G[BTYLC(JT^;:JN6G`8Q'#36>NCO[/0/T5>?=(P'<&U? -MRS&&!X.X1EU-`H'>'7#1I,A%P[I-M=D>I;W]=--1B]I<-/^<2C(PUJ2.]?56 -M1<QACB#C6SX"]`."$YQ'"Y6Y-G>G8^ZF,ZZ.XK3JLT6OYD54^0KFE7]5>2Y_ -M_JI=D"<Q]JJ.[BL,!^EG,6A5)WTA@$.OJI&<(QPJ',*AVV.N/L+B/&5Q!)T! -M0,\E'0)YU!SF#T4C6F\@_+GWU_@S+H`_J9BKAJ&2-?IPY)_,80!W'0>_[@"8 -M&.'SML&C8!&0/A#.L@T>A.Y7*,"2$HT"W?YA2(]=T^W/MCN_25#S/'35$<%\ -M&;)D3>QBBZ?`BM:VMWF6'WM4>>4?>6,*1]-W8J[\6+V^REELV+2Q?!/BOQ*R -M*BEX0.8IXRU&3-[4B[BTE%V0SM;O5NG1@I"3G3.$(ODIW*BTO4;;X-\Z)?;D -MK)@K'8'NTS<#*#?"$_;+`(PH?+4HS!%`N47S]A1V]:[P<;S7'1'Y(RKG>5Y% -MOMJNNH"C5IY0/!^<-1BEZOFV0048.%91"X.0`A7N!L<73.;?SJGR%2G"$-N] -M78'7@GL/8%=^VWWL^BK2G4UO4&BG00#>_HF<SUY&N1`/\INA+.@-(R%/X?8D -M;,$2M_#1A`06CR*O[-#55D5=V<*N'Q4:@!%OV;W9(*-DOZSN+`6&(AM>O&\L -MR>8<Y=F;ZNA.\VBI8U+"*&&I-.OQA'B>8)Y,/`^/OO(W3WV9%[1'CK+L?7I^ -MV=^PHSQ>EE+0^AP&$`EL1D-0MRS$@<=<V15^I1@BKOUTIJLIYLK.,AIF0%OK -M\31K9RBUVSQ']ND_#8;YT)9D:V=(M67910]7Z0O'>@QYX\J-N>-->DSX1X7; -M1(T*-5LI[:@19NW$D)!I/%Y2@E6GC8_6RC$J/BI!^YA^5!B,!B&<+-Q)ZBJO -MZ^)CUUP>(:Y)Q<A)',$D0P&'/#@A!,"0FX17%G6L\LJ[DK6I3306,HDCFN3] -M*,0WP5QYUQRO(AO'TC0U:J1^5(0Q/LX8KP7,!JC)F*`4#42)F"@J7F.)-YOC -M+2:50A^O%HN?,&D5,.B?)].CFIIAZ%.X:^E-@9$'-:'3!@,L`!<"S8(OR9]$ -MTRF",?0F>M1O7\9<>>QH.Q78,:C--#3A8@:WL$N)HHNC<OM=SN+^_!L-3'5_ -M^B&N8\#5#[Z#F-TML-T;!$E27K%@?3R=)F;D%=.N;NQ>I*$6>?XBW]"J)GC^ -M^;WN>D=O_OD&AZMWQ:$@XWF.\1*['MG-KD?>^P!TZ#E5U)7)T5?B\]6Q5Y)$ -M3XOV46^OFT;WB@[A!H(C_'A\2,B4$Y<MG]TS_3!IX>3(]&E!F!498IX2K<T% -MXH%KYF9@.#.!<=DR:3=.V)C/NJTB#4FOIPA,HA'@C\M%KH"YMU%08<ZD8\[T -M\EC=76GZIB"LUX'5%PACY9V2Q7\7!9X"U_=TAW?1?72&Z`HJ>S+'#$4O`2U% -MB!8GRL&+E:,R;#QP96F!5KFNP/90L8TIH6\*AW8(#MO0"060*4H5//]=T#J. -M!((#ZCWMV4HDB$BNYC"'Z/J8R_<*MH1>_JQ811$9U!8QG1G2QJ%[$[>0)G44 -M%Y1-;9SJ,?H6EYO$'1Q/#$B16MV"DGH%8SB0%'MY0`3FLXT3>[D?WL5<OEZY -M!9[8;*]UA"\6@*7#O#QL0>0[%0(;,P"3"F2'7KX8<_FB1<VK_TA7$T75C)1( -M9H(M%CIPM.$G?D+HE^GRTH7'.<`,IAJ%>XM0.$W@EK%/8<.1\$`DQ,V)OMQA -MKHE!C+,E7)BKT&T)8Z\*]AJJJXF.OGPR4#=(;>Y6K@/JY12:8BZWB*,5(7Z. -MV(\J<F_-U4=?;A8*9P:Y$2G4EACPY:@MT>PUJFB[F)&)!S@`%2PUJJKM(+&" -M`1G[I!Z.:`(1[@`GKC:4+3:RV,C][BGH7A"#WA3O-&_1A!0IS%O4[%7EV,'> -M8W,-8@<'FA:S34=<KC75JH4,)^)R3=`8&<`C\9XG73M@/N)J-2W%W)"GN>\I -M8`*"Q\@`S)JW:8XB&R`6/QG,]B3Z<FE<'I?+`!6QQPJA_1#(!W.Y4\!P''70 -MD&Z;.DXU,?IR/C<N2<*^.S:I>B<`(B@3$I,$A%;MU*DFAE[.XKBE:$&P#IY@ -MV(03DG`V(>+RJXA>%'FR<(NKKI@J2N#Z86Q(^E;(X`0<&`5LTI9UD)R[D3M` -M0EKLY3>XP"E^#OLF(2$T(4&1D!"6&(\[$@I-+AV`>EV"./3R0[K1[%8`UJT? -M[;'7G$&0_T/9>W6FVIR#,]XY`B_:=;5@0$^XI:7K@9=I;_1EP\%*4QG&^SW8 -M"IE9'4ULQ^V]3U)0T"'C.@26S&S)3)$E)SLA/OK$VY__P:")T6FB5[E!^K'C -MAT(OA_VKU8^.I<"K#LJB"5YQZRGZIO*RFFZ.ALO%?&G$Y1#1=-&!J>[Z*F^> -MJKK!];?J#V(N*]T'08-5O1_LQBL/>1JC+X^(NLQ%(/1#$MRH_4BO,:_2K4:T -MR/T*BQGXTY":1)'?_;+?#C*K'\U=D@E]O4.GAEZZ/N)R?-2E`;,JK#AAY*5O -MXU4BK1K`OM`T2[M@"F0Z5DZM_!FMRQU++]B?__Z2+K!W45@3K_X*YHC<L0-M -MWR3P`>S-WZ"'ONNA[SLY=/WQ@_]^[Y]2V>D^C.9!]_D?02\XQ,^D^!XI%D<( -MKTZ`V7H[TZM3D2,OM9)NV2ZWN23GM<LUX%+9/RE77OJ9_C+FT@F/MZK>J"+* -MWA>`.MA?I$(;\PTF%;_\@^H#IK\1"5H^VHTMR3:VJ8QEV3;FSU^F:M$065#S -MM#=!&V9)X(><8?<"9FL7E$`7OU^P":YY\S=`MM$Z36Q:M5&G>G'!>GB,8S/T -M1EXZ:QZMUN]A2GI-H]7&T7$-?M,V]3O'@XRC-<9M:H/V1=O@3]`M>CWQ$REP -M3>`?X@IW<H0_`Z:)V.D0"*?IM&&"*^2.,]"DW;D&#:,'\T?NV2/^"/<DIOW' -M`3.!A_Q'8+.K#M198+]V=R75G$/_?<5W0,AJ77.VO?JMD9<.1EXZI+RTCKX8 -M?6E=U7J/LUA5MJE\8UEIQ88`C,,Q<W,V?<9\765NR48V\5NK21N<$(]7H!V^ -M//`M9U8GVIB\3DD"FVP;?!PM*K)\318(+,TY2WZ$]DBVO6"Z(?K2X@IHAH(A -MWX"VPTJ*5>`=59<6)IAAT#=YRLP;AP;=T)R-'-^6[`08CGM7D6_F]#G3EGZG -MGZ$T3%3236!81*T!0_9Y]*7949=F@]_Z=?+"YV.-+]U+/\9NBM<7D#'(EGTK -M"CP%KOE)>BA;-"U$,DU$/B=Z*IG7)B57XY6CHB[-:7"@/0@@R5KXA$/E>1@< -M4]?HXH1MC"4AN#`I]M)?5IZ>QETEHK^,NO2(QUM9#SUQOX_@,3`/4DH-A0E& -M%=]SP$$9_T:X/K"H2)V6+[^42#*R6D9S.[MA#3X@,O^0C3`FO)1?4K-OS+<A -M)60->C-TI*(U8#.U-D;/`M>"I`KYJL_CZ/>-$Y7^Y*^34X*8?#GMK)#2?2;H -M3?]X>\_+^4E%4AN3&%AD[DXMER&<C_%\R5_7Y,E2@J?13MH+>`#\JD08P7KZ -M2.RE1XJ2]EE"BJ;Q^D7GVM,[<;W_)[K]S6O+J\-2L1AW#;5;BF4X7'(Z`[M9 -M4!WJVFQ/?4$'B,3/??/:<P=W%M?PSQ"2)6/W-4KFD=499YPHLY1_1G30@644 -MN&14+;8`;>=G[V_3A?-<X2N^>R5W<[$BK7K+^P.6W<K<L',WW_X.U]_[*6W) -M#A/2$]S"*;[VR$OA,#66J3`CY5;]%*Y%@ZTZ%:2\)!/4<93??%?^,)J?T453 -M1`-DU93"A#T?>1)RIW;0.P^YIYZ29+\GR2&W?E]6DU.[\;W@Q7CZ'(YWL:>V -M<(J-V>9M2URM="MLS#*T=Z]7A>E4X8IO/@9OP>Z<8E2)>)\+#7U:X4=CQ8VD -MX1OMGCJ"F*;7AIVHR7^BF,J=4K\#6\]#^HJ1-.*&!'YQ@N0@N>+1$:S?"5(P -M@+9<:@-G26CU*8FXCH3J`G7L:80*[35+\Y\HI(JGU._%;O&P@<B]?G$C7I%( -M;Q[Y3=4'GT=\4V4"('I#ADXLU$7N:T0>5TFF93(NV(%390A.2BZ.*JKW].;6 -M._8WN-WU;^?*'5YHU56/#M;$XQJ"`^R#EK=W#A.!Q+.*]:5[K`:P1?39I#RI -MPUH95A'NE@GLL\I'T)L%@FE!.\:[%/12$_0@52R>;F]_(VU6@5FE6'T93\5' -M+'@"]/5SU4JDRSF6O/!\99%6IY(4R"A5B->MTTIV.^H=E#;$TLL]V.AE3+U\ -MRT7N;G]]FZF+,5WDIV#E\R?#[-Z@:W*U9I4DZIO%YE*N2162[S25\DD8`F>Y -M-I6#+7@B-_>[=Y"3%)M/Z37!J\N"*-6+]K69HCK27K-NY#<K*D:,_.9YNK=` -M1OO$;>-,*K(JC.R6[;I&[<\QM@6O`-O+66H$Y[5I8=&(PMLAW6//]N:!L^Z6 -M$PYR37YX96BU$GRV7G,X8,OT8F7:/F7A[8+0(GEEZ#O7H&P&.(.AA;(BN4-1 -MK;2H^`7*'8Q%R^])GC/82]0B7"A<."UMWYO1WUB!7<1M(N-G'`-=8J0W"!IE -MT(^H;Q;L;H0+V<BI&&%CGM416"JF@Q9O%LA2>!/*M2"!?<4RLU9BT8:D8I). -M"4O/3:.<D\(;13M[G,=+Z5GTZX[U64Z8%!XQK5S!L\^BPCFGE^:'I7W"27OM -MQ8!/:01;>>0-NIV^8-8&Y]\Q:?D5B164(4%H2`@VWAPA?/%9DIQBU(H:VHQ: -MDKHIT6OM`L'O*"U1]/W2@<?I4Y'?<$($+^?5<APR;#,/K`=6P]OAIXC!>C^8 -M3X%_+)TI%D\3^,>9M.&VP3<Z)72S$=FE9?F4C?'0G6SRG``MV"F>\F+_R(L# -M>DU,U,7K@2-?X`3MO@[6>2!2>/67,U_Y='G]?SJ;`2ZUX`I.(5\HUT=7*S][ -M%OG5:$RXUXOD]*S\T+,U;ABG`J5)SIDSV!YU\4L$N1IENQMU^[.+E<*=(MV! -M;-N]"RPV"8Z]>"/L8H=XABS\XD"A*D\C]N'X69)X1J1/P'65=UH?6E(%4RW> -M=6*;>>6%%\[6GQRK)S@`M(2[QHM$4TXV4/?NQ>>`:Q/UBYL5B8Q(W:\<K3Q5 -MW8F55X&I#Y>K.MI/2:`"+EM!VB<?V1CZG%5D)K<-A+21=NL;(6/EK/L5/)4< -M]KWFZZ"5LDG',M[*B]4M8GTOUC8)E:BIO%_9J_>N'M;37CJ#8)=I3^8;H.B! -M83\0/*V:`EZ,'-DX-AZXUGYQF*EF"7O``<NS,87@&PJ'?,,#-N;084L@USDK -MG2&<I&BJ#VDD1=/'ZOP"ND_(^GHGWAT:D/M'S9P%HL"2,!L/7/-5ML'=J*DK -M@:9.L':&1Z>.N)@6?7'>D;4Z*U=O%>BTQ(K-\B/[5^V$D2LYE\HNF;-[H4UI -MR3,!0.C;E0`B*>(?%I7(H%(`P!(T<L2,D+JE-6@5@@&!^7M0HQW#`)GC2SW^ -MP3!$Y+,0$6S>$$:\='^_E4,@G2B9GL:40*7UC2+1-*C-7O_IZ@_6TDUD)5H* -M"LAWVQ_-5L&JO@A+N[+UWOWRV-\1C0%N!^B[(+,GL(6X8/WI`.X)@%:S2F14 -MA8D'A)8^+5"^K\WXC1:`K"_5_LE>(-+"$LD0EML(Q]X,X-CHBS$VQ@F@R7"8 -M"9!U\F^K/T`$!;9!5QU'0/A?]Q$9'Z`!T9>`0'LK*P.!==,E&U\Y\?S\4DU@ -MEQ/U(P+1+9C>FLGBU\U$^?`R"-UT3L5]%(>1.EXWM/;%%>MJ9*=KUFP2&(A[ -MH@J.88N,GF54*>@OQ6VX40MF=!NHA5\VM3E3[I]-$%#&96FS\A,)#JBN5,SX -M^0NYUJ&3E=C@4/7X][2U=2)HNS]GC7K7BDY6\J?!2-6?H%-!(1B&SE8>S;5& -M7CC#GJX\I*^MBK[PU9)M:,W5U.&)NM!A/S4:0!0Y*".O"]"1A!DX>R0A#<'- -M]:_$7OB<?F_DA1.4FK>ILZ(=G&L"@-JI:F?LA2,'*\VW/=HRCOFZTOR#)VW6 -MRH,3Z,T`I,@]X\7B*?;VIV(OT#$7FLP_3%HX):;^&;09XD1'*HEA^62?`E>Z -M)NK"O@<T4D>-\&FDD0*'(NEV(5MG6L\N&^/ME.C"L?DESQU\M'Y&,3KAJ`,+ -M6J?72K:XZ\&0AE`WN7DRK\-\DT_=X6X9,%]GS'?X<P9/Y$L7>,?2]#HMI9+$ -M7*BB'N):5"&%5LM#?.2L6BNUMD'O\,!6!XY$6NGU8)EM@V[::ALL?=<*XVL; -M?`TX+?+"VJ/.F`L9R@N9QL#"5R8Z*BMD<$O._:.RE4-'9=U[0$];:D,LV\3` -M.T=K`O#&-FCHE$1<6`HPAFZ*OK"4TL1@;>@XGKX#'=4B3N#ZTYG1%Q8(+X[: -MTX\.6N:UYW8TU.E/8RO=W*)35>WHK-87@7.6?;0W#YVOY$Z/NO"G?SJ,@?,N -M"01V\MG[>ZASF'G#O(S8[@&Q/NE]YX-KPU)]?RTWU6+EFHD?3:!3XG&+E@CQ -M<TQ:!0#$%,X2&[-]2(18WE7C>`(.W'<\HRU%OV@9:G#.X,*`]`-]\@L/D8=E -MM2?`W=?-X+Y3L1J<_9@+X^S.OU8Y#V[R3C>4<=*2]Y^UGEMJ9$_M\K\(G-K] -M7=0%H_*"D6H9MBT!U1VM`(8Z^ROE3==8K`++,LR22C[@'7R,O(.`/A]R#O;8 -MF/>C+TB4%T+HS9B79YX;L^<D`$=D@#690Z>M$X;/']57W?SEQ!ROR(L.S/V9 -M/3"7!AZ:`O@"^MJUU)\$+D5]"GXE7_IOB&#/<:@4H`L1_%/,7ZNAO7J06FTP -M03S1NL5(8##V=/OP^C@GG-7Q*G3>D@>6H+D!#('>*J.(N!6;QZS:;#TY"S36 -MDHUV>_+3\TN?'%8I<YA*-,?D]-9F5I).!<XHL7$4G&`JE.<_!U.!/&+62+BU -M.P;`1-B8O:";:%31'.8KH%1/"!#G(JU50U_Y1;&'_7*>ZN1LP`P&3:SR_/<` -M9'90@!A(\`,28O4),2MV1;?N1UEU1,9.G2XA1I<033MU";$=S@`M^CT_038; -M<R:@_Z`WB03VVJ8D>AL:)C6NUP8+!$\$LR2TKDT$0Z>),6BB5WK%K74!.KF/ -M@:_69D^>9U3C)#G]^)%4["N8E`4;06?N!UP.J#RM_9/(\QLMM55F0I!^;::N -MUF-W/AUU_N`F9\SY;(N:1Z\+G"&GLZO*JM=7;X*9-]5Z*&VPJ<MJ4..F;1Z2 -M/6\6.+=OQ>;G+A_2&9P2&Y,3?7[5T7KE^95#1]@""]E`\?!"=K&_ZF8!.I[; -M9CPM7NV6YG;#E+O]HOMKZ?#XRT/;RP9HX5#"?1YX&Z5V+!T:+^.RP+[UG'L; -M;(PHL#?#KOG>*P[P23#M/*W2IP9K"-5K6V$,OAIQ_H68\\^!VZI>L`6>OZ'^ -MC(24/:R;&NC$GX>P,7#L9[+MYRRU.?N?3D='+B/0>MSZT-+URO-/'ZQT.=-F -M/?,;??]*[/FI,>=_]U_4]R9HP2_;[C=V9),S1,;3V;K4X/GKP\VI82<NT9D@ -M5I0]&&>09"&>84$.M#5L!Z##[DZ)P<YJ',O<&//<Z/2K'/IFH!O^Y*9>B7G" -M'.:U0#EHJDO&/R&`WBSY`?I=8X&^W"R//I^L/!])'S':@RMON6Y2J43%=^CD -M]NV"5&2>?^!1J8J5:%G]H.'."+2(59N-OB?8EFTA.(B6>^/3N@_;!INP)EYD -M'V.8RT[Y&YEU?DP?2?6QJN.MX7EOK[B9V^[H:'#K3F-OYW+S3U6T&_^,D[MQ -M(ZB.P36@-V@O*'".SX"^U^A#_D#?M[JY,5#5CC9D7][(A"J1JKE?)>V^Z:"+ -MFQL<+GK%ST&Z9HZN!8,ZZ?5#M3)_Z)1H6,)-M=FF+J5I6W;KBT@9@WUC9;:C -M?DAN@_7L9T,K<SET#9U*7VWJ:#K*XR=%G.?2^^D[DID<T71.A52H%=AKGE\L -MF(ZRKIUNJ,%6>]/?.816ZE;.BE^#(KGS#T7,_S!<1XC>]DKIXA5>45/%V][@ -MIH^;BJ@MV!KO`D,-GP`;\R&^['U<_]%/K5MLS!YTO$:-?_X%@#43@+5307\] -MQ$_%U,<G!59N^[;]RY7;5%#E-=)<Z?QWT0<C:=4U-N:U-*8<KIT2>WH)_>>F -MCPU;,!OC@#X2]EDEB:,QL.``K*AP7BKV5VAX9%_QT9K8OJ*(/F?`CJ/%@ELX -M@)Q?%@L^JNS-^RCWDX:Z\H]6NH.H_2'4`3%2U$120%(?0&:<EX:4`5;\GY&9 -M/]5^2L0B,[J=!6:?%EDC^]X(0<#L0P!F47U+V"]?%AJ;/?4S[5_,]=W4JTAE -MWP+VVY?R4`'Z<@@`6A`+T.:S\O@J;5/VH>]2-AT9T?>*BQ;X9<$`9M!&<\(; -MGH1%RH2W/.%]?VI:D7Y)5.9,+!70YZO6ZRJE:;-6''RDRTF?`E,H/!/PIXIC -M^IZ/[IN-]J2FQ/AOIO\X]%&,^`%_:OBS&+JFP*KL>R*]1=/P#^$]$=1Z*O%+ -M05F[!K"'1K9#8]%D2SX161+813IEW_A_FHZ4E,-*O[ZF"$1@/MU$MP,H!Y4V -MAYEC&TSIE("?170'_"R;C5DPA/O^4#_#H36H)'I`?8T&K>3@HUOJZ@'^A>@R -MN'D*K]N2P==E<;<PEKN,)8L_Y^Z,`NG\)N#-S73[.K3B$ML7JWN(2ZE"BJS4 -M0WRTX&@U)?!L@S.'IT[%(K]R+;U9C[#?.-H)V"^R+XCVQO8%Q_3Q"D(!JNUM -M*Y('OHHQW\[4;V:_C/@!<0QQ<50N[7(6TT7-#4PUG7Z56]Q432/__&#`/_^B -M.LPMRU-T.0$FA-/>%*P[5Y8?7AQF&]P%*/->*Y+'F#Y);.]ML*4C^N+`Q.DU -ML:?K\4,!!SQ65YDQY(`_%$]D;#NQW;2R\^6SJ2?'Z=GOVH)WL"YN@;[_GF7; -MKWWPX87<!WQP<+G`"3\+XW-6#_:XR=C`[:@?VG/<$8!(?[,Q!\]9@TWD=K_= -M^HXNT,B0#YZI@U;*)HG'R:F_WUP.?OCJ83\\]5=^>&I!X+I53Z=RSPJHOV<( -M*#*.X`C&C@\.GF)/G4Y!/3F3^/]!+NR+3+\\!.Q"[N^'#L,Z<2NY@]KJH(!4 -MM6:(5#ICV#E_';0`6CL'GAX?2-EN8^H`Q:S?JH?>Z5"!(3_]8453>Y"?%/]^ -MK.XC`3U+F,+ZZ8X`&0M/1:9_/>2GB]%W(;_RTQ,TT;;!+&@UY4$_'7W(,&Q+ -M64::PQ0-G5WH?5M76Q73^R:[X748(`?MM3L;*C;0WRE[EX'L4F48R*W$CYO* -M.*R9\1BL`M;2>([7@\IFSU1@.X9%QF25ZJPR@S44<X_&#H^VM_].;U5$]U9C -M=:-7?!(DKA`:&["1O9YY-4'B2J'^*">JMR*ZMV)7A>@0_IHW2'<>$QXBR<JH -MAEWB-H'^:+[A:$$*YU,;L]%DE8_L+<3.C5[1$R2J$NDO8O/H(%&UR'B'`S@3 -M:K<Q7T7W/G&T_OY6O[$/%PUO]9/`]W[@>W]!#_"]/_TXU]'M\@/V%`UY.Y<> -M^(;UM&K!<^3P,$U%J?.?G07]//AHKM:BDIA!M!D+.'0#]0-F;8C)R:V?X?53 -M3KZIE+O%014P5"E_SC]>6##K83HCTVY,E43VZHU:KB$U)%=ET/(!I;I5+GO` -M:V'WP`WE=JT]A%;1ITQV26`46;S*?9D4I\C">Q\2/R8KUA2HQ7^2;#.0$T7H -MO(N&/($;$SCV]K^&]H(T&G:?H6?I"8SWXGB"F++B?1MY'#^YPWCO7APX(_=Y -M-ND!GDTJ"%SSU,0YP4ID'MO*U18-?OP6FDG`]\*7QI/DE+0O#MF8P[3SL,FC -M]JC<&F$)6D19=>3K5&P+[VF<-)#!C0+16'GP`&FO64A!@SF3@A?B"_\<F?YJ -M$$:SQPL#9QC8>.!Z6+?E0U"H&<30]LZ4WQ+ZSX1+=(ZLTQ^N*U<#=$`?6&>0 -M0QR>:V,*0(HRA$-.D]?&-'1*#H-,<6R,4?_93ZA((HRG>*(L7Z/LZ<M3`_9_ -M!&'_"DVY>L6NT`#RI]L/Z]QJM\JC0>ME@/=1N0M(W_7LQ4;QZ,W*GKWDX^!` -MQ$3W[$++]_Z`6XU@S[!;7=!>00>0E+O][=R0W%,@=^YVM+H?CX,/"_RV"^%S -MEL_D7=:#X])FO4>O/^.DPJ6IF/7S%\^I*B-\="%PGGCQK#G,G[IJCF_IK#FX -MG;75F\VU&!CKD)!IYG#IN53[YF<#]KJ&M==-A58QNXJB[&F-Z5EK4(F*52&- -M0K-7:_!JZ/4AC23=*ZH:G__Z#J8B5N1(=L4L1U\G&7U)RIXW(WH."WX2":X0 -M1;&N:"ISD7"`LP8=?1MSME[9L]2B(MV1U2/!2ZR.$C`"ZG:.[C!O!4(4E.YV -MMK)GOGU]+)59%=LS;TD.)-HLMSVZ<)G]UHMZN?2T4Z<*JW,+V4W-U\KA=4%! -MC+AX6EJ3]^`BL?`5\5/)/+=4^#3N_O/PUIQE'I;V[-C?X/>_*'N>C^V9C?3? -MK_%[--+CYWZ#WPNB37(IU;Q(I^*'.,@]@>;YQ5:J9='*']"W4M$]CQK!ZK?) -M]K3IFM%*Q"&1KB6;/6/X:RS_KHTI[)0`AA).LPW.KG]:V:.75,B$$0IW3$3/ -MTL"@4>%B&+.8GD6`?6R#)RLCZ`_UX:'LV;RE!1%Z>:AM,([V1O0`C(V)Z8DJ -MC$(*JB1SK[]HY-"WJSUA0]^NEOWS;U<M'1S+:>P!.]UYM%W9(QC9(QSRY=CU -M>'3NHN>![Z_!G?OE:\L@74>([K08'$WVI`;Z%.@>](Q^+ZK[[Y2:5WF3IMW? -M!9;0(KOON&X%3@,:M6&!XX"VP6EH,9#.*HR)[1GCDE5+[>W_X4\]N$B_2%D< -MHULM6/SSXSWM9P*[B>Q>8@]M;%.=68H2%)!`O<Y-7"VM#NMQ`L)S?6GJ4NTM -M.E.CWZW";CJJP]%NXHBTY)?RE+;!R72SLML7VQ.9'VE2$<$?B_8WHL]>ST=W -M?^[J=5^H[*-IHY;_P/01M?C]^3.'RT%5^Y,,X0K:.V=PKT&N,,OEMGO706<$ -MWL$;7]*<P;O#;SH>_/L%^6/H&B/!2<5P_6X.VCAIC13LYZRHOQG0R<'#&/#[ -MZ.Z=([N_.U;MJ!?NY`KS..7UAE/XVQDCHKJW1G</Z)LSQ0"_6X:.F0%=3;T` -MPD)"9IJ_PF%ZV742_4*GLOM\;/>%J.Z+,=V;(KI+3><S-951$C_'L)[]%+*1 -M(Q+--&S$H0I'1KD[LMOG*B]W#?E%1'CWF:CNG!'=.1*3C-]-5(631M%^/]]/ -M>.2FR-(]GWG"C)]Q]+330*\7H$_[\0=WLN(."T1U40;"GA+\4GFHY?68#=)J -MV9=+0[N/YH7EA^IKL/B)/:(Z*E^:$OQ\ODRTBRH(-X3S#"U1R"&R8F\<#RM0 -MZ)-5AD=49!V5$CR=/D7XQYE^1S5,W3][_YBW)IS;O[Q87A3N"&L8\#I<857A -MZ5=KANP:VK5$8QG9_0=H)X63QZY,SV%^'MG]/'U4Y\5;=Y.5.$G.-/X-)]%8 -MQ70GQW9O@L%!*&3X"]'`?$5U3QO9_11[\#13UX3_=5\PO$*3*>]V1G>7*+M+ -MQ'LXI@.9`A='()A)?8J#7)1\KFE[:&@^Z8MT<GCW^,XDG2I8T?T0>[3CNP5H -M&3LWJCN+?`P8S-#\O;[YCFDROFKSXPUUYN8?]2UWUNP,TC?_`)%5.PW'JL$Z -MP!-%<(A=..:(%#JX^I;OX242\[F9`H9C83\2%%\<%:]]<65CN*7Y!UWSCZ*] -MI,1-AKA)H4[16IZ*?4\<)`64(BWC.ETB/(L+A3-UO\/9CN91!DWP2B_K?6EB -MT[ZP!W@_N$U@:LY9\C40>PJD(+I[HMW9JNP65ZUW.2TJ8N,&,3KBX5"A58-2 -MBXI?4:8OXULV$O'L^0M3,[C=*E-+=F!M,%#EMC9]<PY=OA(-@$O?G&VO*:%_ -M4G8G1G<GCO3?BO#?KMKLKLE5;=SNV;IQB^L]=O$(![^8:LY&?]RC0$6U9%NT -MP?'Q^*JS>-`<W/[QP1%^_S_;VX"A2MOWC6W0!:0HNP/CA-\?)Q"8D?Z_ZR;C -M:&;G9B)7=M[0O*./M?UWC.PKT]Q,I,KF#4&\H3F-\A]%Q9HSH_WTLGU"S2D< -M#_"$LEM&ZF0['1'=TOP,QUKA3HZN)7/56FYN?5L)>A_5+0(A'I*ZKY#4Y3DU -M7480GO*N0-U$5#=/[O]'J'\'[0COQK11TC#_]K-)^I>68C4YY5+,F>=6ZN9B -MB_-F2JIE>)60>X\P]V)!C%`R(.,-$/J.189;%-%*BAQC\WN];KC5Y0D:2>J6 -MKJ+7T+%8?WJ1Z`0IJ!OKZ!,*I\"=<)"NOEUU^M.+O>4`[,I3A]=$%/X+T)4P -M__E0O\^1O'/,B:(YS!F:UH^^8QC]?64R,!DU^@?SZ!]%^TC!`"D9($/,BE0, -M3"7Q<2#*+TH*9*9G1?O?.K;$=`J/];\%0[]J\V1J](_&6DR_FZ<?>V=E;I!^ -M]`\06;7S]Q#!U#S$Y"F1P<#D8[^'=&1];F<*W!S=#T.3!\H3\..JG=&!OQ$` -M;Z$4]F)D<!V7>"!;_;6*I+8#K4?)9@0I(4WS(0/N*C[`Z:#-PYG^T]^1">AI -MZ/_3]"@>):361EO^SKR6M3K:7TZ:97O]^:?RVF/\4U=M?M3165#34%?>OC*7 -MF]=1WKYJY_-Y'4"(KP:;$"EQ<\M/Z4^S?\+@?*;0P0%6HX8URS#]V@#]AO.( -M_@Y:/QG''HN4^+GB1H[ATI`W?4K200]#=D2?SZKPJ^D,L-'`]#K$]#PWH2M! -MZT+.P+I0@/X8_TC2(-O[(5HS(::PA_*SC;79]"@[_4ZT_U6%7[;G(]258\RJ -MS8\%>H+V5G)Y>1UP_U_2EV#DH-#M\58^9<4BNJX+GI(+'025.;4K692!C>RZ -M1CXCVU6GJ\T2_E&DVY85Z%>@3$17+Y2!D@\4B.KJ)J?+=C?J]V<1+XKT![)8 -M&TBO)?6RJ*XS([N^V@UUY>PR&.J3N&X!.K#KB'Q[+5]3FX6/%@WO+00;",RN -M2@WWQV=+0[N.:<&%_5!@V#-HV&_6[QD414R>O^')^24S%ZQ/2<5FHCW7QY#/ -MJJ_5F^K7$\3OC?5._>[;`O;;K#>//V:L+S'5;P@\KCQN-NBQ@V.T,SAO/+T3 -M&#+]DVEA?K&-:81JXA^Y8F/VQQ-V&[/;1!#"K\;;F/>6OB(**E)8'N/$WUEO -MON-<ND]$.!2ZQSCZT@U4:0GO&7S.X`@;LW.X^%]9_E!V_1S9]1/^M$*W33;T -M)S0RY;CP"8E;ALX>C8FDX\">:"*%&BZ>R5%V]7,UN"9''E@O5]'U='*.=$17 -MP;'_*)4INO)3L5'^FM<V\Z.[L@O;Q7O(KM217><CNUIBNC*(<U3(:Z!N']I5 -MYT-KDAU6NS7G=++!BG2__HW,`MG*UH7176^)_T28.K1!+^*B=JRSQFXYK==P -MB#P%KXYC?[S6.)I#%BAX;1SR)+ZR:4,J]G2G)+U:$O\2!P!P6O5W=/+9FO3M -M-Z*[TNCZ0$7GDMEZCC'8+!Y[.$0RP*V2V9BM4`9+YA'"".1.UMN8%:\U\4=V -MI>37BTZ20%%4ESNFZWWR,!7=]?[>MLI3-B:>':_8KIDQ7<FA77OE7?OH=KHI -M%1-W2O1WDBQW.>;KTC?Z7C&<SUDS.A)<W]?V7P9'0$!XZP*P;57^US9FH%.B -M.Y\M_E!&&!3V3XX3^LG'M]37>9P-[M;=]3O8>Y:I#--5\D1ZM$VWD_0X/>M- -M9;BIC`LPU<:4C>P:93R0@18^#JP=QB^3Y5TZ760S19@BNQ)&=A6&=A5!AKC1 -M)B1AP(DUF$B4)')-H.)C%M2"9.?,86:%=:V-[)II>.0*\0@GA<L8U#%$(]59 -M4Y&<PNWMJLE/IFO(1D$*MR>L:X59C4=WO<8;P,6/4>9XW/0"EL+]FLVSF<US -M6M&UE+[-YGI=,IS+DY3"_1PR)=&UNQM3N)_IP3%L`+O)?@R+IW#[@*4CNEZA -MOU)VV6.[TF*ZTJ*ZTD9V/9JMTI9BVE*>ME0@FDUI2\F@H.#=+^U]>=\K.V9K -MG]]E>GZW]LXUTYWKVHL&TT6CZ>@B[=&_V!@3&@<]8340W#G,,_*N*4<VT^_3 -MCRB[)D=U33[BU+6$HP')&3&'>8*>$>WK-ION'KEEN8123>U*[:41]O9/C]0" -M0&<>#=PF-.^CO13D*M'EH%Q:5/8A9#V(S<?>I\\TGZ<'C::[S<446[6E942L -M[[J9C9M:1APYW909US(D4/IFN:B.PW9>WR)O>H]^/T`.U8)V&PS#V<S-<O27 -M;%KD;!4H@[YEA)ZHG<.$1W2IZ`^:3S9]I3?=-1.UYFUL,]O8718V;F#CNFW2 -M4Y(CM>P8"&W,PVA,Y+Y+H5VRZ"Y99)<\IDL>U26GD^CG1_K.A_L\%"%(0-A@ -M3(_JC9-XL(8<X>OB)U*[5NQ]>\\;=<LM"1F6C5EQ67EQ$SGQ607:K/S$A*K$ -M!(\VH5ISEQ/KNQO:A4$5B_-&==Q,A_(,&>%K$S+4KA_W_K3GYSI&4Y81EYWE -M'1._K$"[+%^S+$];5FTIJ[*4>;P6^F>E[W:$[W:,[W:4[^-(WVUR$372=XL4 -M!^\X4W=NEZ^J7K<URY*5%^OKC_'UT^MU6?GT5CT0<2"6'"#-!Z+-!V)&^J[L -MZR$;2:7O<J3O<HSO2MVYO7YJ6ZOV>RS^R]W:+W=IOZPS;+MDV/:-=MOE81NB -M]/6P.BXTPM>87ARZ6"!"`^T9U->&IN_CV9C^3HG<]W6D;[;2]SZ;\3':*S@X -M@=JBA*?,>+MJ*5T_PK<GUO=1C.\CA>]SVDH_7U`3[2NJE$;Y&A?KII^K?_]` -M\%_P-_X2IO0YWCK)RY>*_D(*#E*ZWP]N=U!E'%]-A"]S)9N^BQ0>HKR[]I2% -MN`02MX`J\U#HSQMEQ)55Q]GSX^T%$;Z22-\8H^>>L5D,AH:,4K1^@71*L+<1 -MQ8_8F-OHG)S9<Z^B%@P4O19,5+W#]1Z06MP/EZ(!N!0Z0X0SUWP=.=(7*XQ6 -MF+JNF+9J35OC35LUIJUQQ@:TYFJIO&+>'&_9JK5LU9BWQ@V/E=RW5.G+C/!M -MB/2],=+W>I1O:;1O"9T<?YJ":N-;=.AZ0(^NVPQ#T*HD*-2'_@`,-1:;PVQ1 -M^-Y%HC,E+M:7Q7M>48KDQW([/L:WMAJ=YB[J5_C^&/*RPCPV:`XS>PXC07K7 -MMZJIW@1L_G?&?/I1-#>C<./I1X84Q\-X"MXY9_#(G$$/JNKW=^-_,,T9_-/0 -M/G^H;W&6-7[*LVTOQ$7.>.]W\4\^FS6KZ?%ECW"/64Y)@IX@2D9[G]@PZQ=L -MI/3]V9$1G_GLB>1W9]4OG[<T+&2%[*`C*$?@2$U<S0!$2%AT]]7T6]G)::_X -ME;X7\C*H6DGK6D@_IP(C.N=:F]3W['JLA+,!+^7*?*9,*>=;:ZV,<W,4G<2[ -M&([AF,PW/5,:]PP&-K-$*O.-I-4E4M[%45G<=6!+UZ)O3SEQZ.\B2GU3?JDG -M:KB>6P_4,R%3&GKN'%O/@Q5T6CECV/)CUF-K.6G2I]?B:=*I:[E?Q`[7)ARN -M[?8#M<6CVB[_NC9:NIZ['E^/:OW2RGD"<L4ZP=[\*/7%_(HVZ,BYL^ND0UV* -MD/LD)=)?:I:@FCO^$YU?63GH;X9F*M:%985GCU!'+>4HL*&_!%H:OO'_J>SH -M8YJXXN_>NZO8WO5:H!WE\WK79<A7WU$4)+H"Q0T2,QV"_*&9=;4JJ5HF+,H^ -M=(*ZZ401T(G"9I;,/\S,(&;+_EL5$W4CINCB=B>+^!$R9^+`;/MC<>G>M5`_ -M!NJ:IKGW>[_/=[][O_>N=[_?"_!7["7]G2F)UQ@T@.&85;("T4H1Q,1KD((` -M.2#MF+W!9&01YG0@0_WG0$HOF2FQ$>!>&TOA3U-[T[@'^GTA*A->.,.'0+MM -M?^J!-`[*1B#SE+P_D;4"(Y(SU'LF]7>.*!N>'?6#UM?;EL(QN;5VYW)-SH#< -M5K>K'J"GY8X,9LMIZO54]3J;9V9/LG,^3Q]RYYY(=YS(,/2Q(8'KG$^N*>DQ -M0/Q9E!&R'E6%%9%[L5Q@NF"^.UV]E*9>-.:8#;GZ'XI:^]^;;^WJ9YUL:-2F -M7LQ0O^=OEIPZU1,F/./@<QGJN4EPC#,[2#;C@X3_'N&CW-,]/4++'L.>.7MS -M+G0?%?J/'9NSSW'^^H7!/@=AHF4%!1<G;8'P)M;T@/!6]!X03%:_FF4%;66[ -MR^%<>*A,5T<QM^59T22AVIO2L1R>ZHF'.+`.38>FX:$Q?+X,0@^JI&`EI,=D -M!#T$(2HGWL=XF!?9&`935/H(TJ1^49[1M3R\(B2K'Q+)K>6[RKK*T2,RA_E$ -M931)G=TEA,S4PQ2G8%P&$S*X+XOZX\1`L]J2I+:@,3E9;2']6F92=8M>RTQZ -M%9N5,'T/.ZS(%WE`^0@H4?7%/+'+U&G6_%#U/NJ'F:J?OXG9V[C]!ANAB%?V -M):T9;^E-[$P1_XZP$3I+^0F$:)ZW\2+B;Q&W>^/+(6[(T'[VP&C?#2Y"\;<U -M%7D=X"#F`>ZS<13^++4OK3UTW;3_#!]^TG\SU6K>"MI']R5I8G^A"`O_>&IK -M2N^-O$1(]J4FM31#+6:1/.7:7(3.5,M/C1B'#/L'880R1JA,M<0?>3-+Z0=A -MFN=L!P:Y6S(O0DXD1OMA%1X0@4"C:HR@C2S\U^'O$%I%+F6(=-!%(3<-9!I" -M&ZR6":Z8EX4D%D4'&E;C-<([VYT)VYRV]YVE7K!7ZAWOQH?DPX6?N*`UF4H@ -M@75$&HG#I)5_M&%IP>@1W",?+3SF@CG)4,/YEF#FCXQWA`\.=U[NNB*E$[3\ -M$9.T(#Q%>:2H9V[./%WNO%E\`@U?3D8:V0Y"1E0B&\F0G6Q5B(+:V1?"?,@> -MYGG1+.91J`HW.@W2@@AI-K[T%T(>8@R0S$A,@7`)H4`(GQ7B%H7$\*3_694) -M9@S_"'0UU(`8<\9ED:_#9<PC?FE13I*M$/["1;NUFE.L:*9I#RU"O_NNI$<. -M?0)D/&2O@1C;]E4&6)'<7^E?<C?Z/)E]F+<HQT):V:[IJ$.N4-7TM#';HK(_ -MGDFVQGOGC+S#L6O9HKP[25\\'7WS%/U_>N/T@9GH)7WJ,VU?.2/_,Z7/8?MB -MJ[(W7G;,_EC^X^>I0691%A#I,U4@BTY!\8]%D:U*X_^K<691'$_A/VE#FL9S -M9@4L2M)3>3S,]TQX)5B5JKB*6=.,QQ7^"O^XMF-Q;9^P]^<_K<J\.+/$9]-K -M]NB2E)PN4ZM)%,%ZP;+3Y*@`AC*PVT164H=-NTR[EC8LO1.-@U%AT5SA]O1L -MH.7B?@!(],4TPJ<+X8`\X$*P'+I8J9"$4NT^!!I<1B.9LL!`B2=0)`0*C0&9 -M`109EF;[RD8OV!1P,?8:V@O\]AK&"U8%YG&!N02B\X)E.^J]X+5`,:-;3=`7 -MS7J+_+H#I9F!^=QV-SW\@1?(LP\26*[6.NX%DF&`M#*VN8W;W0RK/0UCYK27 -MR@RD:;Q!#B`_`2GDN;107-GHT#<R26RSJP#E==#Y'2B]F\[H1@4=M+,#97;3 -M6=VMM6UU.Y='UQ2`!LC,^B+GM?-1QTHU@J/&WE7;72?5B(X:J6MY=[TO\DTL -M[OT6B\M##C0N>X$Q*#)H@APP08E!]V4P-?<,.>`X)E&=],.)Z(%$P_MX:KT! -M1?UD3<#LXK+LXLKLXJKLXL6Q^GZQN!_[[P=N*IQ_56""-.VFFU<XF$H6E&NC -M+A+::J[)1Z.U[(!()D^4E-SD@V1&U20T^:B0G<B\$)>GY1Q?<4<_S.L!\*SW -M;VAJ"`JOU`N5BRKJ7EV(A>R*MQLV-`OU_C5">>-F02X1<$EI84DI=@E+*VN% -M0HR+A>`F8:U_0\/6@M5-#;XU_J:&=9O\FYL*?,&-I<[UP8U^9[37N<6Y=LLJ -M5X%K3IZPG/0W$+):U]:M`L9%!1B3KY`OR*2!R<=$`U"P[/+J?P&C)[&/F'$` -!```` -` -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 new file mode 100644 index 0000000..e434c1d --- /dev/null +++ b/sys/dev/cxgb/t3fw-4.1.0.bin.gz.uu @@ -0,0 +1,482 @@ +/************************************************************************** + +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_YKKAIXUP=_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�!&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/modules/cxgb/Makefile b/sys/modules/cxgb/Makefile index 5df8112..cd2081e 100644 --- a/sys/modules/cxgb/Makefile +++ b/sys/modules/cxgb/Makefile @@ -5,22 +5,22 @@ CXGB = ${.CURDIR}/../../dev/cxgb KMOD= if_cxgb SRCS= cxgb_mc5.c cxgb_vsc8211.c cxgb_ael1002.c cxgb_mv88e1xxx.c -SRCS+= cxgb_xgmac.c cxgb_t3_hw.c cxgb_main.c cxgb_sge.c cxgb_lro.c -SRCS+= cxgb_offload.c cxgb_l2t.c +SRCS+= cxgb_xgmac.c cxgb_vsc7323.c cxgb_t3_hw.c cxgb_main.c +SRCS+= cxgb_sge.c cxgb_lro.c cxgb_offload.c cxgb_l2t.c SRCS+= device_if.h bus_if.h pci_if.h opt_zero.h SRCS+= uipc_mvec.c -CFLAGS+= -DCONFIG_CHELSIO_T3_CORE -g -DDEFAULT_JUMBO -DCONFIG_DEFINED -I${CXGB} -#CFLAGS+= -DINVARIANT_SUPPORT -DINVARIANTS -DDEBUG +CFLAGS+= -DCONFIG_CHELSIO_T3_CORE -g -DCONFIG_DEFINED -DDEFAULT_JUMBO -I${CXGB} +#CFLAGS+= -DINVARIANT_SUPPORT -DINVARIANTS .if ${MACHINE_ARCH} != "ia64" # ld is broken on ia64 -t3fw-4.0.0.bin: ${CXGB}/t3fw-4.0.0.bin.gz.uu - uudecode -p < ${CXGB}/t3fw-4.0.0.bin.gz.uu \ +t3fw-4.1.0.bin: ${CXGB}/t3fw-4.1.0.bin.gz.uu + uudecode -p < ${CXGB}/t3fw-4.1.0.bin.gz.uu \ | gzip -dc > ${.TARGET} -FIRMWS= t3fw-4.0.0.bin:t3fw400 -CLEANFILES+= t3fw-4.0.0.bin +FIRMWS= t3fw-4.1.0.bin:t3fw410 +CLEANFILES+= t3fw-4.1.0.bin .endif |