diff options
author | Auke Kok <auke-jan.h.kok@intel.com> | 2006-06-21 13:43:50 -0700 |
---|---|---|
committer | Auke-jan Kok <ahkok@gitlost.site> | 2006-06-21 13:43:50 -0700 |
commit | 0d204094d15dac2e8a439b993f71eda385b4dccd (patch) | |
tree | 647f0ddec94d0fb4aaf74fa55bcad75946030f8a /drivers | |
parent | a487a8f7b6947f6445e5a1aa876522916785d5ec (diff) | |
parent | 612eff0e3715a6faff5ba1b74873b99e036c59fe (diff) |
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers')
129 files changed, 12310 insertions, 7055 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index aeb5ab2391e..8b11cebe65d 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -72,4 +72,6 @@ source "drivers/edac/Kconfig" source "drivers/rtc/Kconfig" +source "drivers/dma/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 447d8e68887..3c5170310bd 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -74,3 +74,4 @@ obj-$(CONFIG_SGI_SN) += sn/ obj-y += firmware/ obj-$(CONFIG_CRYPTO) += crypto/ obj-$(CONFIG_SUPERH) += sh/ +obj-$(CONFIG_DMA_ENGINE) += dma/ diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 07bc6dfe662..8920e8c6e24 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -812,6 +812,9 @@ static int irqrouter_resume(struct sys_device *dev) ACPI_FUNCTION_TRACE("irqrouter_resume"); + /* Make sure SCI is enabled again (Apple firmware bug?) */ + acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1, ACPI_MTX_DO_NOT_LOCK); + acpi_in_resume = 1; list_for_each(node, &acpi_link.entries) { link = list_entry(node, struct acpi_pci_link, node); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index abbdb37a7f5..f36db22ce1a 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -577,6 +577,8 @@ acpi_processor_register_performance(struct acpi_processor_performance return_VALUE(-EBUSY); } + WARN_ON(!performance); + pr->performance = performance; if (acpi_processor_get_performance_info(pr)) { @@ -609,7 +611,8 @@ acpi_processor_unregister_performance(struct acpi_processor_performance return_VOID; } - kfree(pr->performance->states); + if (pr->performance) + kfree(pr->performance->states); pr->performance = NULL; acpi_cpufreq_remove_file(pr); diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index fdff774b8ab..c1434ed1188 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -116,8 +116,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, skb = skb_share_check(skb, GFP_ATOMIC); if (skb == NULL) return 0; - if (skb_is_nonlinear(skb)) - if (skb_linearize(skb, GFP_ATOMIC) < 0) + if (skb_linearize(skb)) goto exit; if (!is_aoe_netif(ifp)) goto exit; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index a59876a0bfa..3170eaa2508 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1009,9 +1009,9 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp) if (fp->f_mode & FMODE_WRITE) { ret = -EROFS; if (cdrom_open_write(cdi)) - goto err; + goto err_release; if (!CDROM_CAN(CDC_RAM)) - goto err; + goto err_release; ret = 0; cdi->media_written = 0; } @@ -1026,6 +1026,8 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp) not be mounting, but opening with O_NONBLOCK */ check_disk_change(ip->i_bdev); return 0; +err_release: + cdi->ops->release(cdi); err: cdi->use_count--; return ret; diff --git a/drivers/char/Makefile b/drivers/char/Makefile index f5b01c6d498..fb919bfb282 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -41,9 +41,9 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o -obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o +obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MMTIMER) += mmtimer.o diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c index 2b5838e6475..b4e00a343da 100644 --- a/drivers/char/agp/alpha-agp.c +++ b/drivers/char/agp/alpha-agp.c @@ -46,12 +46,6 @@ struct vm_operations_struct alpha_core_agp_vm_ops = { }; -static int alpha_core_agp_nop(void) -{ - /* just return success */ - return 0; -} - static int alpha_core_agp_fetch_size(void) { return alpha_core_agp_sizes[0].size; @@ -120,6 +114,11 @@ static int alpha_core_agp_remove_memory(struct agp_memory *mem, off_t pg_start, return status; } +static int alpha_core_agp_create_free_gatt_table(struct agp_bridge_data *a) +{ + return 0; +} + struct agp_bridge_driver alpha_core_agp_driver = { .owner = THIS_MODULE, .aperture_sizes = alpha_core_agp_sizes, @@ -135,8 +134,8 @@ struct agp_bridge_driver alpha_core_agp_driver = { .tlb_flush = alpha_core_agp_tlbflush, .mask_memory = agp_generic_mask_memory, .cache_flush = global_cache_flush, - .create_gatt_table = alpha_core_agp_nop, - .free_gatt_table = alpha_core_agp_nop, + .create_gatt_table = alpha_core_agp_create_free_gatt_table, + .free_gatt_table = alpha_core_agp_create_free_gatt_table, .insert_memory = alpha_core_agp_insert_memory, .remove_memory = alpha_core_agp_remove_memory, .alloc_by_type = agp_generic_alloc_by_type, diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 4e1891e2c03..a92ab53a137 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -809,12 +809,10 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) case U32_APER_SIZE: bridge->current_size = A_IDX32(bridge); break; - /* This case will never really happen. */ + /* These cases will never really happen. */ case FIXED_APER_SIZE: case LVL2_APER_SIZE: default: - bridge->current_size = - bridge->current_size; break; } temp = bridge->current_size; diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index bddcae54b16..61ac3809f99 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -736,7 +736,7 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start, static int intel_i915_fetch_size(void) { struct aper_size_info_fixed *values; - u32 temp, offset = 0; + u32 temp, offset; #define I915_256MB_ADDRESS_MASK (1<<27) diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 9846defbddb..1de1b12043b 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -329,7 +329,7 @@ static int agp_uninorth_suspend(struct pci_dev *pdev) /* turn off AGP on the bridge */ agp = pci_find_capability(pdev, PCI_CAP_ID_AGP); pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd); - bridge->dev_private_data = (void *)cmd; + bridge->dev_private_data = (void *)(long)cmd; if (cmd & PCI_AGP_COMMAND_AGP) { printk("uninorth-agp: disabling AGP on bridge %s\n", pci_name(pdev)); @@ -351,7 +351,7 @@ static int agp_uninorth_resume(struct pci_dev *pdev) if (bridge == NULL) return -ENODEV; - command = (u32)bridge->dev_private_data; + command = (long)bridge->dev_private_data; bridge->dev_private_data = NULL; if (!(command & PCI_AGP_COMMAND_AGP)) return 0; diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index ede365d0538..b9371d5bf79 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -1384,8 +1384,10 @@ do_it_again: * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, * we won't get any more characters. */ - if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) + if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { + n_tty_set_room(tty); check_unthrottle(tty); + } if (b - buf >= minimum) break; diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 9f2f00d8291..05f8ce2cfb4 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c @@ -127,7 +127,7 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id) if (found) { cn_queue_free_callback(cbq); - atomic_dec_and_test(&dev->refcnt); + atomic_dec(&dev->refcnt); } } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 29b2fa5534a..44d1eca83a7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -257,7 +257,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { if ((policy) && (policy->cpu == freqs->cpu) && (policy->cur) && (policy->cur != freqs->old)) { - dprintk(KERN_WARNING "Warning: CPU frequency is" + dprintk("Warning: CPU frequency is" " %u, cpufreq assumed %u kHz.\n", freqs->old, policy->cur); freqs->old = policy->cur; @@ -874,7 +874,7 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne { struct cpufreq_freqs freqs; - dprintk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing " + dprintk("Warning: CPU frequency out of sync: cpufreq and timing " "core thinks of %u, is %u kHz.\n", old_freq, new_freq); freqs.cpu = cpu; @@ -1006,7 +1006,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) struct cpufreq_freqs freqs; if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) - dprintk(KERN_DEBUG "Warning: CPU frequency is %u, " + dprintk("Warning: CPU frequency is %u, " "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur); @@ -1087,7 +1087,7 @@ static int cpufreq_resume(struct sys_device * sysdev) struct cpufreq_freqs freqs; if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) - dprintk(KERN_WARNING "Warning: CPU frequency" + dprintk("Warning: CPU frequency" "is %u, cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur); diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 9694b6ed326..c576c0b3f45 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -74,7 +74,7 @@ static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) { struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu]; - if(!stat) + if (!stat) return 0; return sprintf(buf, "%d\n", cpufreq_stats_table[stat->cpu]->total_trans); @@ -86,7 +86,7 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf) ssize_t len = 0; int i; struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu]; - if(!stat) + if (!stat) return 0; cpufreq_stats_update(stat->cpu); for (i = 0; i < stat->state_num; i++) { @@ -104,7 +104,7 @@ show_trans_table(struct cpufreq_policy *policy, char *buf) int i, j; struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu]; - if(!stat) + if (!stat) return 0; cpufreq_stats_update(stat->cpu); len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index a4818ce8891..551f4ccf87f 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -20,7 +20,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, { unsigned int min_freq = ~0; unsigned int max_freq = 0; - unsigned int i = 0; + unsigned int i; for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { unsigned int freq = table[i].frequency; @@ -51,7 +51,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table) { unsigned int next_larger = ~0; - unsigned int i = 0; + unsigned int i; unsigned int count = 0; dprintk("request for verification of policy (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu); @@ -91,20 +91,24 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, unsigned int relation, unsigned int *index) { - struct cpufreq_frequency_table optimal = { .index = ~0, }; - struct cpufreq_frequency_table suboptimal = { .index = ~0, }; + struct cpufreq_frequency_table optimal = { + .index = ~0, + .frequency = 0, + }; + struct cpufreq_frequency_table suboptimal = { + .index = ~0, + .frequency = 0, + }; unsigned int i; dprintk("request for target %u kHz (relation: %u) for cpu %u\n", target_freq, relation, policy->cpu); switch (relation) { case CPUFREQ_RELATION_H: - optimal.frequency = 0; suboptimal.frequency = ~0; break; case CPUFREQ_RELATION_L: optimal.frequency = ~0; - suboptimal.frequency = 0; break; } diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig new file mode 100644 index 00000000000..30d021d1a07 --- /dev/null +++ b/drivers/dma/Kconfig @@ -0,0 +1,34 @@ +# +# DMA engine configuration +# + +menu "DMA Engine support" + +config DMA_ENGINE + bool "Support for DMA engines" + ---help--- + DMA engines offload copy operations from the CPU to dedicated + hardware, allowing the copies to happen asynchronously. + +comment "DMA Clients" + +config NET_DMA + bool "Network: TCP receive copy offload" + depends on DMA_ENGINE && NET + default y + ---help--- + This enables the use of DMA engines in the network stack to + offload receive copy-to-user operations, freeing CPU cycles. + Since this is the main user of the DMA engine, it should be enabled; + say Y here. + +comment "DMA Devices" + +config INTEL_IOATDMA + tristate "Intel I/OAT DMA support" + depends on DMA_ENGINE && PCI + default m + ---help--- + Enable support for the Intel(R) I/OAT DMA engine. + +endmenu diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile new file mode 100644 index 00000000000..bdcfdbdb1ae --- /dev/null +++ b/drivers/dma/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DMA_ENGINE) += dmaengine.o +obj-$(CONFIG_NET_DMA) += iovlock.o +obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c new file mode 100644 index 00000000000..5829143558e --- /dev/null +++ b/drivers/dma/dmaengine.c @@ -0,0 +1,408 @@ +/* + * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ + +/* + * This code implements the DMA subsystem. It provides a HW-neutral interface + * for other kernel code to use asynchronous memory copy capabilities, + * if present, and allows different HW DMA drivers to register as providing + * this capability. + * + * Due to the fact we are accelerating what is already a relatively fast + * operation, the code goes to great lengths to avoid additional overhead, + * such as locking. + * + * LOCKING: + * + * The subsystem keeps two global lists, dma_device_list and dma_client_list. + * Both of these are protected by a mutex, dma_list_mutex. + * + * Each device has a channels list, which runs unlocked but is never modified + * once the device is registered, it's just setup by the driver. + * + * Each client has a channels list, it's only modified under the client->lock + * and in an RCU callback, so it's safe to read under rcu_read_lock(). + * + * Each device has a kref, which is initialized to 1 when the device is + * registered. A kref_put is done for each class_device registered. When the + * class_device is released, the coresponding kref_put is done in the release + * method. Every time one of the device's channels is allocated to a client, + * a kref_get occurs. When the channel is freed, the coresponding kref_put + * happens. The device's release function does a completion, so + * unregister_device does a remove event, class_device_unregister, a kref_put + * for the first reference, then waits on the completion for all other + * references to finish. + * + * Each channel has an open-coded implementation of Rusty Russell's "bigref," + * with a kref and a per_cpu local_t. A single reference is set when on an + * ADDED event, and removed with a REMOVE event. Net DMA client takes an + * extra reference per outstanding transaction. The relase function does a + * kref_put on the device. -ChrisL + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/dmaengine.h> +#include <linux/hardirq.h> +#include <linux/spinlock.h> +#include <linux/percpu.h> +#include <linux/rcupdate.h> +#include <linux/mutex.h> + +static DEFINE_MUTEX(dma_list_mutex); +static LIST_HEAD(dma_device_list); +static LIST_HEAD(dma_client_list); + +/* --- sysfs implementation --- */ + +static ssize_t show_memcpy_count(struct class_device *cd, char *buf) +{ + struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); + unsigned long count = 0; + int i; + + for_each_possible_cpu(i) + count += per_cpu_ptr(chan->local, i)->memcpy_count; + + return sprintf(buf, "%lu\n", count); +} + +static ssize_t show_bytes_transferred(struct class_device *cd, char *buf) +{ + struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); + unsigned long count = 0; + int i; + + for_each_possible_cpu(i) + count += per_cpu_ptr(chan->local, i)->bytes_transferred; + + return sprintf(buf, "%lu\n", count); +} + +static ssize_t show_in_use(struct class_device *cd, char *buf) +{ + struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); + + return sprintf(buf, "%d\n", (chan->client ? 1 : 0)); +} + +static struct class_device_attribute dma_class_attrs[] = { + __ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL), + __ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL), + __ATTR(in_use, S_IRUGO, show_in_use, NULL), + __ATTR_NULL +}; + +static void dma_async_device_cleanup(struct kref *kref); + +static void dma_class_dev_release(struct class_device *cd) +{ + struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); + kref_put(&chan->device->refcount, dma_async_device_cleanup); +} + +static struct class dma_devclass = { + .name = "dma", + .class_dev_attrs = dma_class_attrs, + .release = dma_class_dev_release, +}; + +/* --- client and device registration --- */ + +/** + * dma_client_chan_alloc - try to allocate a channel to a client + * @client: &dma_client + * + * Called with dma_list_mutex held. + */ +static struct dma_chan *dma_client_chan_alloc(struct dma_client *client) +{ + struct dma_device *device; + struct dma_chan *chan; + unsigned long flags; + int desc; /* allocated descriptor count */ + + /* Find a channel, any DMA engine will do */ + list_for_each_entry(device, &dma_device_list, global_node) { + list_for_each_entry(chan, &device->channels, device_node) { + if (chan->client) + continue; + + desc = chan->device->device_alloc_chan_resources(chan); + if (desc >= 0) { + kref_get(&device->refcount); + kref_init(&chan->refcount); + chan->slow_ref = 0; + INIT_RCU_HEAD(&chan->rcu); + chan->client = client; + spin_lock_irqsave(&client->lock, flags); + list_add_tail_rcu(&chan->client_node, + &client->channels); + spin_unlock_irqrestore(&client->lock, flags); + return chan; + } + } + } + + return NULL; +} + +/** + * dma_client_chan_free - release a DMA channel + * @chan: &dma_chan + */ +void dma_chan_cleanup(struct kref *kref) +{ + struct dma_chan *chan = container_of(kref, struct dma_chan, refcount); + chan->device->device_free_chan_resources(chan); + chan->client = NULL; + kref_put(&chan->device->refcount, dma_async_device_cleanup); +} + +static void dma_chan_free_rcu(struct rcu_head *rcu) +{ + struct dma_chan *chan = container_of(rcu, struct dma_chan, rcu); + int bias = 0x7FFFFFFF; + int i; + for_each_possible_cpu(i) + bias -= local_read(&per_cpu_ptr(chan->local, i)->refcount); + atomic_sub(bias, &chan->refcount.refcount); + kref_put(&chan->refcount, dma_chan_cleanup); +} + +static void dma_client_chan_free(struct dma_chan *chan) +{ + atomic_add(0x7FFFFFFF, &chan->refcount.refcount); + chan->slow_ref = 1; + call_rcu(&chan->rcu, dma_chan_free_rcu); +} + +/** + * dma_chans_rebalance - reallocate channels to clients + * + * When the number of DMA channel in the system changes, + * channels need to be rebalanced among clients + */ +static void dma_chans_rebalance(void) +{ + struct dma_client *client; + struct dma_chan *chan; + unsigned long flags; + + mutex_lock(&dma_list_mutex); + + list_for_each_entry(client, &dma_client_list, global_node) { + while (client->chans_desired > client->chan_count) { + chan = dma_client_chan_alloc(client); + if (!chan) + break; + client->chan_count++; + client->event_callback(client, + chan, + DMA_RESOURCE_ADDED); + } + while (client->chans_desired < client->chan_count) { + spin_lock_irqsave(&client->lock, flags); + chan = list_entry(client->channels.next, + struct dma_chan, + client_node); + list_del_rcu(&chan->client_node); + spin_unlock_irqrestore(&client->lock, flags); + client->chan_count--; + client->event_callback(client, + chan, + DMA_RESOURCE_REMOVED); + dma_client_chan_free(chan); + } + } + + mutex_unlock(&dma_list_mutex); +} + +/** + * dma_async_client_register - allocate and register a &dma_client + * @event_callback: callback for notification of channel addition/removal + */ +struct dma_client *dma_async_client_register(dma_event_callback event_callback) +{ + struct dma_client *client; + + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return NULL; + + INIT_LIST_HEAD(&client->channels); + spin_lock_init(&client->lock); + client->chans_desired = 0; + client->chan_count = 0; + client->event_callback = event_callback; + + mutex_lock(&dma_list_mutex); + list_add_tail(&client->global_node, &dma_client_list); + mutex_unlock(&dma_list_mutex); + + return client; +} + +/** + * dma_async_client_unregister - unregister a client and free the &dma_client + * @client: + * + * Force frees any allocated DMA channels, frees the &dma_client memory + */ +void dma_async_client_unregister(struct dma_client *client) +{ + struct dma_chan *chan; + + if (!client) + return; + + rcu_read_lock(); + list_for_each_entry_rcu(chan, &client->channels, client_node) + dma_client_chan_free(chan); + rcu_read_unlock(); + + mutex_lock(&dma_list_mutex); + list_del(&client->global_node); + mutex_unlock(&dma_list_mutex); + + kfree(client); + dma_chans_rebalance(); +} + +/** + * dma_async_client_chan_request - request DMA channels + * @client: &dma_client + * @number: count of DMA channels requested + * + * Clients call dma_async_client_chan_request() to specify how many + * DMA channels they need, 0 to free all currently allocated. + * The resulting allocations/frees are indicated to the client via the + * event callback. + */ +void dma_async_client_chan_request(struct dma_client *client, + unsigned int number) +{ + client->chans_desired = number; + dma_chans_rebalance(); +} + +/** + * dma_async_device_register - + * @device: &dma_device + */ +int dma_async_device_register(struct dma_device *device) +{ + static int id; + int chancnt = 0; + struct dma_chan* chan; + + if (!device) + return -ENODEV; + + init_completion(&device->done); + kref_init(&device->refcount); + device->dev_id = id++; + + /* represent channels in sysfs. Probably want devs too */ + list_for_each_entry(chan, &device->channels, device_node) { + chan->local = alloc_percpu(typeof(*chan->local)); + if (chan->local == NULL) + continue; + + chan->chan_id = chancnt++; + chan->class_dev.class = &dma_devclass; + chan->class_dev.dev = NULL; + snprintf(chan->class_dev.class_id, BUS_ID_SIZE, "dma%dchan%d", + device->dev_id, chan->chan_id); + + kref_get(&device->refcount); + class_device_register(&chan->class_dev); + } + + mutex_lock(&dma_list_mutex); + list_add_tail(&device->global_node, &dma_device_list); + mutex_unlock(&dma_list_mutex); + + dma_chans_rebalance(); + + return 0; +} + +/** + * dma_async_device_unregister - + * @device: &dma_device + */ +static void dma_async_device_cleanup(struct kref *kref) +{ + struct dma_device *device; + + device = container_of(kref, struct dma_device, refcount); + complete(&device->done); +} + +void dma_async_device_unregister(struct dma_device* device) +{ + struct dma_chan *chan; + unsigned long flags; + + mutex_lock(&dma_list_mutex); + list_del(&device->global_node); + mutex_unlock(&dma_list_mutex); + + list_for_each_entry(chan, &device->channels, device_node) { + if (chan->client) { + spin_lock_irqsave(&chan->client->lock, flags); + list_del(&chan->client_node); + chan->client->chan_count--; + spin_unlock_irqrestore(&chan->client->lock, flags); + chan->client->event_callback(chan->client, + chan, + DMA_RESOURCE_REMOVED); + dma_client_chan_free(chan); + } + class_device_unregister(&chan->class_dev); + } + dma_chans_rebalance(); + + kref_put(&device->refcount, dma_async_device_cleanup); + wait_for_completion(&device->done); +} + +static int __init dma_bus_init(void) +{ + mutex_init(&dma_list_mutex); + return class_register(&dma_devclass); +} + +subsys_initcall(dma_bus_init); + +EXPORT_SYMBOL(dma_async_client_register); +EXPORT_SYMBOL(dma_async_client_unregister); +EXPORT_SYMBOL(dma_async_client_chan_request); +EXPORT_SYMBOL(dma_async_memcpy_buf_to_buf); +EXPORT_SYMBOL(dma_async_memcpy_buf_to_pg); +EXPORT_SYMBOL(dma_async_memcpy_pg_to_pg); +EXPORT_SYMBOL(dma_async_memcpy_complete); +EXPORT_SYMBOL(dma_async_memcpy_issue_pending); +EXPORT_SYMBOL(dma_async_device_register); +EXPORT_SYMBOL(dma_async_device_unregister); +EXPORT_SYMBOL(dma_chan_cleanup); diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c new file mode 100644 index 00000000000..0fdf7fbd649 --- /dev/null +++ b/drivers/dma/ioatdma.c @@ -0,0 +1,840 @@ +/* + * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ + +/* + * This driver supports an Intel I/OAT DMA engine, which does asynchronous + * copy operations. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/interrupt.h> +#include <linux/dmaengine.h> +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include "ioatdma.h" +#include "ioatdma_io.h" +#include "ioatdma_registers.h" +#include "ioatdma_hw.h" + +#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common) +#define to_ioat_device(dev) container_of(dev, struct ioat_device, common) +#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node) + +/* internal functions */ +static int __devinit ioat_probe(struct pci_dev *pdev, const struct pci_device_id *ent); +static void __devexit ioat_remove(struct pci_dev *pdev); + +static int enumerate_dma_channels(struct ioat_device *device) +{ + u8 xfercap_scale; + u32 xfercap; + int i; + struct ioat_dma_chan *ioat_chan; + + device->common.chancnt = ioatdma_read8(device, IOAT_CHANCNT_OFFSET); + xfercap_scale = ioatdma_read8(device, IOAT_XFERCAP_OFFSET); + xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale)); + + for (i = 0; i < device->common.chancnt; i++) { + ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL); + if (!ioat_chan) { + device->common.chancnt = i; + break; + } + + ioat_chan->device = device; + ioat_chan->reg_base = device->reg_base + (0x80 * (i + 1)); + ioat_chan->xfercap = xfercap; + spin_lock_init(&ioat_chan->cleanup_lock); + spin_lock_init(&ioat_chan->desc_lock); + INIT_LIST_HEAD(&ioat_chan->free_desc); + INIT_LIST_HEAD(&ioat_chan->used_desc); + /* This should be made common somewhere in dmaengine.c */ + ioat_chan->common.device = &device->common; + ioat_chan->common.client = NULL; + list_add_tail(&ioat_chan->common.device_node, + &device->common.channels); + } + return device->common.chancnt; +} + +static struct ioat_desc_sw *ioat_dma_alloc_descriptor( + struct ioat_dma_chan *ioat_chan, + int flags) +{ + struct ioat_dma_descriptor *desc; + struct ioat_desc_sw *desc_sw; + struct ioat_device *ioat_device; + dma_addr_t phys; + + ioat_device = to_ioat_device(ioat_chan->common.device); + desc = pci_pool_alloc(ioat_device->dma_pool, flags, &phys); + if (unlikely(!desc)) + return NULL; + + desc_sw = kzalloc(sizeof(*desc_sw), flags); + if (unlikely(!desc_sw)) { + pci_pool_free(ioat_device->dma_pool, desc, phys); + return NULL; + } + + memset(desc, 0, sizeof(*desc)); + desc_sw->hw = desc; + desc_sw->phys = phys; + + return desc_sw; +} + +#define INITIAL_IOAT_DESC_COUNT 128 + +static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan); + +/* returns the actual number of allocated descriptors */ +static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) +{ + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); + struct ioat_desc_sw *desc = NULL; + u16 chanctrl; + u32 chanerr; + int i; + LIST_HEAD(tmp_list); + + /* + * In-use bit automatically set by reading chanctrl + * If 0, we got it, if 1, someone else did + */ + chanctrl = ioatdma_chan_read16(ioat_chan, IOAT_CHANCTRL_OFFSET); + if (chanctrl & IOAT_CHANCTRL_CHANNEL_IN_USE) + return -EBUSY; + + /* Setup register to interrupt and write completion status on error */ + chanctrl = IOAT_CHANCTRL_CHANNEL_IN_USE | + IOAT_CHANCTRL_ERR_INT_EN | + IOAT_CHANCTRL_ANY_ERR_ABORT_EN | + IOAT_CHANCTRL_ERR_COMPLETION_EN; + ioatdma_chan_write16(ioat_chan, IOAT_CHANCTRL_OFFSET, chanctrl); + + chanerr = ioatdma_chan_read32(ioat_chan, IOAT_CHANERR_OFFSET); + if (chanerr) { + printk("IOAT: CHANERR = %x, clearing\n", chanerr); + ioatdma_chan_write32(ioat_chan, IOAT_CHANERR_OFFSET, chanerr); + } + + /* Allocate descriptors */ + for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) { + desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); + if (!desc) { + printk(KERN_ERR "IOAT: Only %d initial descriptors\n", i); + break; + } + list_add_tail(&desc->node, &tmp_list); + } + spin_lock_bh(&ioat_chan->desc_lock); + list_splice(&tmp_list, &ioat_chan->free_desc); + spin_unlock_bh(&ioat_chan->desc_lock); + + /* allocate a completion writeback area */ + /* doing 2 32bit writes to mmio since 1 64b write doesn't work */ + ioat_chan->completion_virt = + pci_pool_alloc(ioat_chan->device->completion_pool, + GFP_KERNEL, + &ioat_chan->completion_addr); + memset(ioat_chan->completion_virt, 0, + sizeof(*ioat_chan->completion_virt)); + ioatdma_chan_write32(ioat_chan, IOAT_CHANCMP_OFFSET_LOW, + ((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF); + ioatdma_chan_write32(ioat_chan, IOAT_CHANCMP_OFFSET_HIGH, + ((u64) ioat_chan->completion_addr) >> 32); + + ioat_start_null_desc(ioat_chan); + return i; +} + +static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan); + +static void ioat_dma_free_chan_resources(struct dma_chan *chan) +{ + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); + struct ioat_device *ioat_device = to_ioat_device(chan->device); + struct ioat_desc_sw *desc, *_desc; + u16 chanctrl; + int in_use_descs = 0; + + ioat_dma_memcpy_cleanup(ioat_chan); + + ioatdma_chan_write8(ioat_chan, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_RESET); + + spin_lock_bh(&ioat_chan->desc_lock); + list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) { + in_use_descs++; + list_del(&desc->node); + pci_pool_free(ioat_device->dma_pool, desc->hw, desc->phys); + kfree(desc); + } + list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) { + list_del(&desc->node); + pci_pool_free(ioat_device->dma_pool, desc->hw, desc->phys); + kfree(desc); + } + spin_unlock_bh(&ioat_chan->desc_lock); + + pci_pool_free(ioat_device->completion_pool, + ioat_chan->completion_virt, + ioat_chan->completion_addr); + + /* one is ok since we left it on there on purpose */ + if (in_use_descs > 1) + printk(KERN_ERR "IOAT: Freeing %d in use descriptors!\n", + in_use_descs - 1); + + ioat_chan->last_completion = ioat_chan->completion_addr = 0; + + /* Tell hw the chan is free */ + chanctrl = ioatdma_chan_read16(ioat_chan, IOAT_CHANCTRL_OFFSET); + chanctrl &= ~IOAT_CHANCTRL_CHANNEL_IN_USE; + ioatdma_chan_write16(ioat_chan, IOAT_CHANCTRL_OFFSET, chanctrl); +} + +/** + * do_ioat_dma_memcpy - actual function that initiates a IOAT DMA transaction + * @chan: IOAT DMA channel handle + * @dest: DMA destination address + * @src: DMA source address + * @len: transaction length in bytes + */ + +static dma_cookie_t do_ioat_dma_memcpy(struct ioat_dma_chan *ioat_chan, + dma_addr_t dest, + dma_addr_t src, + size_t len) +{ + struct ioat_desc_sw *first; + struct ioat_desc_sw *prev; + struct ioat_desc_sw *new; + dma_cookie_t cookie; + LIST_HEAD(new_chain); + u32 copy; + size_t orig_len; + dma_addr_t orig_src, orig_dst; + unsigned int desc_count = 0; + unsigned int append = 0; + + if (!ioat_chan || !dest || !src) + return -EFAULT; + + if (!len) + return ioat_chan->common.cookie; + + orig_len = len; + orig_src = src; + orig_dst = dest; + + first = NULL; + prev = NULL; + + spin_lock_bh(&ioat_chan->desc_lock); + + while (len) { + if (!list_empty(&ioat_chan->free_desc)) { + new = to_ioat_desc(ioat_chan->free_desc.next); + list_del(&new->node); + } else { + /* try to get another desc */ + new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC); + /* will this ever happen? */ + /* TODO add upper limit on these */ + BUG_ON(!new); + } + + copy = min((u32) len, ioat_chan->xfercap); + + new->hw->size = copy; + new->hw->ctl = 0; + new->hw->src_addr = src; + new->hw->dst_addr = dest; + new->cookie = 0; + + /* chain together the physical address list for the HW */ + if (!first) + first = new; + else + prev->hw->next = (u64) new->phys; + + prev = new; + + len -= copy; + dest += copy; + src += copy; + + list_add_tail(&new->node, &new_chain); + desc_count++; + } + new->hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; + new->hw->next = 0; + + /* cookie incr and addition to used_list must be atomic */ + + cookie = ioat_chan->common.cookie; + cookie++; + if (cookie < 0) + cookie = 1; + ioat_chan->common.cookie = new->cookie = cookie; + + pci_unmap_addr_set(new, src, orig_src); + pci_unmap_addr_set(new, dst, orig_dst); + pci_unmap_len_set(new, src_len, orig_len); + pci_unmap_len_set(new, dst_len, orig_len); + + /* write address into NextDescriptor field of last desc in chain */ + to_ioat_desc(ioat_chan->used_desc.prev)->hw->next = first->phys; + list_splice_init(&new_chain, ioat_chan->used_desc.prev); + + ioat_chan->pending += desc_count; + if (ioat_chan->pending >= 20) { + append = 1; + ioat_chan->pending = 0; + } + + spin_unlock_bh(&ioat_chan->desc_lock); + + if (append) + ioatdma_chan_write8(ioat_chan, + IOAT_CHANCMD_OFFSET, + IOAT_CHANCMD_APPEND); + return cookie; +} + +/** + * ioat_dma_memcpy_buf_to_buf - wrapper that takes src & dest bufs + * @chan: IOAT DMA channel handle + * @dest: DMA destination address + * @src: DMA source address + * @len: transaction length in bytes + */ + +static dma_cookie_t ioat_dma_memcpy_buf_to_buf(struct dma_chan *chan, + void *dest, + void *src, + size_t len) +{ + dma_addr_t dest_addr; + dma_addr_t src_addr; + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); + + dest_addr = pci_map_single(ioat_chan->device->pdev, + dest, len, PCI_DMA_FROMDEVICE); + src_addr = pci_map_single(ioat_chan->device->pdev, + src, len, PCI_DMA_TODEVICE); + + return do_ioat_dma_memcpy(ioat_chan, dest_addr, src_addr, len); +} + +/** + * ioat_dma_memcpy_buf_to_pg - wrapper, copying from a buf to a page + * @chan: IOAT DMA channel handle + * @page: pointer to the page to copy to + * @offset: offset into that page + * @src: DMA source address + * @len: transaction length in bytes + */ + +static dma_cookie_t ioat_dma_memcpy_buf_to_pg(struct dma_chan *chan, + struct page *page, + unsigned int offset, + void *src, + size_t len) +{ + dma_addr_t dest_addr; + dma_addr_t src_addr; + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); + + dest_addr = pci_map_page(ioat_chan->device->pdev, + page, offset, len, PCI_DMA_FROMDEVICE); + src_addr = pci_map_single(ioat_chan->device->pdev, + src, len, PCI_DMA_TODEVICE); + + return do_ioat_dma_memcpy(ioat_chan, dest_addr, src_addr, len); +} + +/** + * ioat_dma_memcpy_pg_to_pg - wrapper, copying between two pages + * @chan: IOAT DMA channel handle + * @dest_pg: pointer to the page to copy to + * @dest_off: offset into that page + * @src_pg: pointer to the page to copy from + * @src_off: offset into that page + * @len: transaction length in bytes. This is guaranteed to not make a copy + * across a page boundary. + */ + +static dma_cookie_t ioat_dma_memcpy_pg_to_pg(struct dma_chan *chan, + struct page *dest_pg, + unsigned int dest_off, + struct page *src_pg, + unsigned int src_off, + size_t len) +{ + dma_addr_t dest_addr; + dma_addr_t src_addr; + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); + + dest_addr = pci_map_page(ioat_chan->device->pdev, + dest_pg, dest_off, len, PCI_DMA_FROMDEVICE); + src_addr = pci_map_page(ioat_chan->device->pdev, + src_pg, src_off, len, PCI_DMA_TODEVICE); + + return do_ioat_dma_memcpy(ioat_chan, dest_addr, src_addr, len); +} + +/** + * ioat_dma_memcpy_issue_pending - push potentially unrecognoized appended descriptors to hw + * @chan: DMA channel handle + */ + +static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan) +{ + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); + + if (ioat_chan->pending != 0) { + ioat_chan->pending = 0; + ioatdma_chan_write8(ioat_chan, + IOAT_CHANCMD_OFFSET, + IOAT_CHANCMD_APPEND); + } +} + +static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan) +{ + unsigned long phys_complete; + struct ioat_desc_sw *desc, *_desc; + dma_cookie_t cookie = 0; + + prefetch(chan->completion_virt); + + if (!spin_trylock(&chan->cleanup_lock)) + return; + + /* The completion writeback can happen at any time, + so reads by the driver need to be atomic operations + The descriptor physical addresses are limited to 32-bits + when the CPU can only do a 32-bit mov */ + +#if (BITS_PER_LONG == 64) + phys_complete = + chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; +#else + phys_complete = chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK; +#endif + + if ((chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) == + IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) { + printk("IOAT: Channel halted, chanerr = %x\n", + ioatdma_chan_read32(chan, IOAT_CHANERR_OFFSET)); + + /* TODO do something to salvage the situation */ + } + + if (phys_complete == chan->last_completion) { + spin_unlock(&chan->cleanup_lock); + return; + } + + spin_lock_bh(&chan->desc_lock); + list_for_each_entry_safe(desc, _desc, &chan->used_desc, node) { + + /* + * Incoming DMA requests may use multiple descriptors, due to + * exceeding xfercap, perhaps. If so, only the last one will + * have a cookie, and require unmapping. + */ + if (desc->cookie) { + cookie = desc->cookie; + + /* yes we are unmapping both _page and _single alloc'd + regions with unmap_page. Is this *really* that bad? + */ + pci_unmap_page(chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, dst_len), + PCI_DMA_FROMDEVICE); + pci_unmap_page(chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, src_len), + PCI_DMA_TODEVICE); + } + + if (desc->phys != phys_complete) { + /* a completed entry, but not the last, so cleanup */ + list_del(&desc->node); + list_add_tail(&desc->node, &chan->free_desc); + } else { + /* last used desc. Do not remove, so we can append from + it, but don't look at it next time, either */ + desc->cookie = 0; + + /* TODO check status bits? */ + break; + } + } + + spin_unlock_bh(&chan->desc_lock); + + chan->last_completion = phys_complete; + if (cookie != 0) + chan->completed_cookie = cookie; + + spin_unlock(&chan->cleanup_lock); +} + +/** + * ioat_dma_is_complete - poll the status of a IOAT DMA transaction + * @chan: IOAT DMA channel handle + * @cookie: DMA transaction identifier + */ + +static enum dma_status ioat_dma_is_complete(struct dma_chan *chan, + dma_cookie_t cookie, + dma_cookie_t *done, + dma_cookie_t *used) +{ + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + enum dma_status ret; + + last_used = chan->cookie; + last_complete = ioat_chan->completed_cookie; + + if (done) + *done= last_complete; + if (used) + *used = last_used; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + if (ret == DMA_SUCCESS) + return ret; + + ioat_dma_memcpy_cleanup(ioat_chan); + + last_used = chan->cookie; + last_complete = ioat_chan->completed_cookie; + + if (done) + *done= last_complete; + if (used) + *used = last_used; + + return dma_async_is_complete(cookie, last_complete, last_used); +} + +/* PCI API */ + +static struct pci_device_id ioat_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) }, + { 0, } +}; + +static struct pci_driver ioat_pci_drv = { + .name = "ioatdma", + .id_table = ioat_pci_tbl, + .probe = ioat_probe, + .remove = __devexit_p(ioat_remove), +}; + +static irqreturn_t ioat_do_interrupt(int irq, void *data, struct pt_regs *regs) +{ + struct ioat_device *instance = data; + unsigned long attnstatus; + u8 intrctrl; + + intrctrl = ioatdma_read8(instance, IOAT_INTRCTRL_OFFSET); + + if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN)) + return IRQ_NONE; + + if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) { + ioatdma_write8(instance, IOAT_INTRCTRL_OFFSET, intrctrl); + return IRQ_NONE; + } + + attnstatus = ioatdma_read32(instance, IOAT_ATTNSTATUS_OFFSET); + + printk(KERN_ERR "ioatdma error: interrupt! status %lx\n", attnstatus); + + ioatdma_write8(instance, IOAT_INTRCTRL_OFFSET, intrctrl); + return IRQ_HANDLED; +} + +static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan) +{ + struct ioat_desc_sw *desc; + + spin_lock_bh(&ioat_chan->desc_lock); + + if (!list_empty(&ioat_chan->free_desc)) { + desc = to_ioat_desc(ioat_chan->free_desc.next); + list_del(&desc->node); + } else { + /* try to get another desc */ + spin_unlock_bh(&ioat_chan->desc_lock); + desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); + spin_lock_bh(&ioat_chan->desc_lock); + /* will this ever happen? */ + BUG_ON(!desc); + } + + desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL; + desc->hw->next = 0; + + list_add_tail(&desc->node, &ioat_chan->used_desc); + spin_unlock_bh(&ioat_chan->desc_lock); + +#if (BITS_PER_LONG == 64) + ioatdma_chan_write64(ioat_chan, IOAT_CHAINADDR_OFFSET, desc->phys); +#else + ioatdma_chan_write32(ioat_chan, + IOAT_CHAINADDR_OFFSET_LOW, + (u32) desc->phys); + ioatdma_chan_write32(ioat_chan, IOAT_CHAINADDR_OFFSET_HIGH, 0); +#endif + ioatdma_chan_write8(ioat_chan, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_START); +} + +/* + * Perform a IOAT transaction to verify the HW works. + */ +#define IOAT_TEST_SIZE 2000 + +static int ioat_self_test(struct ioat_device *device) +{ + int i; + u8 *src; + u8 *dest; + struct dma_chan *dma_chan; + dma_cookie_t cookie; + int err = 0; + + src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL); + if (!src) + return -ENOMEM; + dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL); + if (!dest) { + kfree(src); + return -ENOMEM; + } + + /* Fill in src buffer */ + for (i = 0; i < IOAT_TEST_SIZE; i++) + src[i] = (u8)i; + + /* Start copy, using first DMA channel */ + dma_chan = container_of(device->common.channels.next, + struct dma_chan, + device_node); + if (ioat_dma_alloc_chan_resources(dma_chan) < 1) { + err = -ENODEV; + goto out; + } + + cookie = ioat_dma_memcpy_buf_to_buf(dma_chan, dest, src, IOAT_TEST_SIZE); + ioat_dma_memcpy_issue_pending(dma_chan); + msleep(1); + + if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + printk(KERN_ERR "ioatdma: Self-test copy timed out, disabling\n"); + err = -ENODEV; + goto free_resources; + } + if (memcmp(src, dest, IOAT_TEST_SIZE)) { + printk(KERN_ERR "ioatdma: Self-test copy failed compare, disabling\n"); + err = -ENODEV; + goto free_resources; + } + +free_resources: + ioat_dma_free_chan_resources(dma_chan); +out: + kfree(src); + kfree(dest); + return err; +} + +static int __devinit ioat_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int err; + unsigned long mmio_start, mmio_len; + void *reg_base; + struct ioat_device *device; + + err = pci_enable_device(pdev); + if (err) + goto err_enable_device; + + err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); + if (err) + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (err) + goto err_set_dma_mask; + + err = pci_request_regions(pdev, ioat_pci_drv.name); + if (err) + goto err_request_regions; + + mmio_start = pci_resource_start(pdev, 0); + mmio_len = pci_resource_len(pdev, 0); + + reg_base = ioremap(mmio_start, mmio_len); + if (!reg_base) { + err = -ENOMEM; + goto err_ioremap; + } + + device = kzalloc(sizeof(*device), GFP_KERNEL); + if (!device) { + err = -ENOMEM; + goto err_kzalloc; + } + + /* DMA coherent memory pool for DMA descriptor allocations */ + device->dma_pool = pci_pool_create("dma_desc_pool", pdev, + sizeof(struct ioat_dma_descriptor), 64, 0); + if (!device->dma_pool) { + err = -ENOMEM; + goto err_dma_pool; + } + + device->completion_pool = pci_pool_create("completion_pool", pdev, sizeof(u64), SMP_CACHE_BYTES, SMP_CACHE_BYTES); + if (!device->completion_pool) { + err = -ENOMEM; + goto err_completion_pool; + } + + device->pdev = pdev; + pci_set_drvdata(pdev, device); +#ifdef CONFIG_PCI_MSI + if (pci_enable_msi(pdev) == 0) { + device->msi = 1; + } else { + device->msi = 0; + } +#endif + err = request_irq(pdev->irq, &ioat_do_interrupt, SA_SHIRQ, "ioat", + device); + if (err) + goto err_irq; + + device->reg_base = reg_base; + + ioatdma_write8(device, IOAT_INTRCTRL_OFFSET, IOAT_INTRCTRL_MASTER_INT_EN); + pci_set_master(pdev); + + INIT_LIST_HEAD(&device->common.channels); + enumerate_dma_channels(device); + + device->common.device_alloc_chan_resources = ioat_dma_alloc_chan_resources; + device->common.device_free_chan_resources = ioat_dma_free_chan_resources; + device->common.device_memcpy_buf_to_buf = ioat_dma_memcpy_buf_to_buf; + device->common.device_memcpy_buf_to_pg = ioat_dma_memcpy_buf_to_pg; + device->common.device_memcpy_pg_to_pg = ioat_dma_memcpy_pg_to_pg; + device->common.device_memcpy_complete = ioat_dma_is_complete; + device->common.device_memcpy_issue_pending = ioat_dma_memcpy_issue_pending; + printk(KERN_INFO "Intel(R) I/OAT DMA Engine found, %d channels\n", + device->common.chancnt); + + err = ioat_self_test(device); + if (err) + goto err_self_test; + + dma_async_device_register(&device->common); + + return 0; + +err_self_test: +err_irq: + pci_pool_destroy(device->completion_pool); +err_completion_pool: + pci_pool_destroy(device->dma_pool); +err_dma_pool: + kfree(device); +err_kzalloc: + iounmap(reg_base); +err_ioremap: + pci_release_regions(pdev); +err_request_regions: +err_set_dma_mask: + pci_disable_device(pdev); +err_enable_device: + return err; +} + +static void __devexit ioat_remove(struct pci_dev *pdev) +{ + struct ioat_device *device; + struct dma_chan *chan, *_chan; + struct ioat_dma_chan *ioat_chan; + + device = pci_get_drvdata(pdev); + dma_async_device_unregister(&device->common); + + free_irq(device->pdev->irq, device); +#ifdef CONFIG_PCI_MSI + if (device->msi) + pci_disable_msi(device->pdev); +#endif + pci_pool_destroy(device->dma_pool); + pci_pool_destroy(device->completion_pool); + iounmap(device->reg_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + list_for_each_entry_safe(chan, _chan, &device->common.channels, device_node) { + ioat_chan = to_ioat_chan(chan); + list_del(&chan->device_node); + kfree(ioat_chan); + } + kfree(device); +} + +/* MODULE API */ +MODULE_VERSION("1.7"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Intel Corporation"); + +static int __init ioat_init_module(void) +{ + /* it's currently unsafe to unload this module */ + /* if forced, worst case is that rmmod hangs */ + if (THIS_MODULE != NULL) + THIS_MODULE->unsafe = 1; + + return pci_module_init(&ioat_pci_drv); +} + +module_init(ioat_init_module); + +static void __exit ioat_exit_module(void) +{ + pci_unregister_driver(&ioat_pci_drv); +} + +module_exit(ioat_exit_module); diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h new file mode 100644 index 00000000000..a5d3b364416 --- /dev/null +++ b/drivers/dma/ioatdma.h @@ -0,0 +1,125 @@ +/* + * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ +#ifndef IOATDMA_H +#define IOATDMA_H + +#include <linux/dmaengine.h> +#include "ioatdma_hw.h" +#include <linux/init.h> +#include <linux/dmapool.h> +#include <linux/cache.h> +#include <linux/pci_ids.h> + +#define IOAT_LOW_COMPLETION_MASK 0xffffffc0 + +extern struct list_head dma_device_list; +extern struct list_head dma_client_list; + +/** + * struct ioat_device - internal representation of a IOAT device + * @pdev: PCI-Express device + * @reg_base: MMIO register space base address + * @dma_pool: for allocating DMA descriptors + * @common: embedded struct dma_device + * @msi: Message Signaled Interrupt number + */ + +struct ioat_device { + struct pci_dev *pdev; + void *reg_base; + struct pci_pool *dma_pool; + struct pci_pool *completion_pool; + + struct dma_device common; + u8 msi; +}; + +/** + * struct ioat_dma_chan - internal representation of a DMA channel + * @device: + * @reg_base: + * @sw_in_use: + * @completion: + * @completion_low: + * @completion_high: + * @completed_cookie: last cookie seen completed on cleanup + * @cookie: value of last cookie given to client + * @last_completion: + * @xfercap: + * @desc_lock: + * @free_desc: + * @used_desc: + * @resource: + * @device_node: + */ + +struct ioat_dma_chan { + + void *reg_base; + + dma_cookie_t completed_cookie; + unsigned long last_completion; + + u32 xfercap; /* XFERCAP register value expanded out */ + + spinlock_t cleanup_lock; + spinlock_t desc_lock; + struct list_head free_desc; + struct list_head used_desc; + + int pending; + + struct ioat_device *device; + struct dma_chan common; + + dma_addr_t completion_addr; + union { + u64 full; /* HW completion writeback */ + struct { + u32 low; + u32 high; + }; + } *completion_virt; +}; + +/* wrapper around hardware descriptor format + additional software fields */ + +/** + * struct ioat_desc_sw - wrapper around hardware descriptor + * @hw: hardware DMA descriptor + * @node: + * @cookie: + * @phys: + */ + +struct ioat_desc_sw { + struct ioat_dma_descriptor *hw; + struct list_head node; + dma_cookie_t cookie; + dma_addr_t phys; + DECLARE_PCI_UNMAP_ADDR(src) + DECLARE_PCI_UNMAP_LEN(src_len) + DECLARE_PCI_UNMAP_ADDR(dst) + DECLARE_PCI_UNMAP_LEN(dst_len) +}; + +#endif /* IOATDMA_H */ + diff --git a/drivers/dma/ioatdma_hw.h b/drivers/dma/ioatdma_hw.h new file mode 100644 index 00000000000..4d7a12880be --- /dev/null +++ b/drivers/dma/ioatdma_hw.h @@ -0,0 +1,52 @@ +/* + * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ +#ifndef _IOAT_HW_H_ +#define _IOAT_HW_H_ + +/* PCI Configuration Space Values */ +#define IOAT_PCI_VID 0x8086 +#define IOAT_PCI_DID 0x1A38 +#define IOAT_PCI_RID 0x00 +#define IOAT_PCI_SVID 0x8086 +#define IOAT_PCI_SID 0x8086 +#define IOAT_VER 0x12 /* Version 1.2 */ + +struct ioat_dma_descriptor { + uint32_t size; + uint32_t ctl; + uint64_t src_addr; + uint64_t dst_addr; + uint64_t next; + uint64_t rsv1; + uint64_t rsv2; + uint64_t user1; + uint64_t user2; +}; + +#define IOAT_DMA_DESCRIPTOR_CTL_INT_GN 0x00000001 +#define IOAT_DMA_DESCRIPTOR_CTL_SRC_SN 0x00000002 +#define IOAT_DMA_DESCRIPTOR_CTL_DST_SN 0x00000004 +#define IOAT_DMA_DESCRIPTOR_CTL_CP_STS 0x00000008 +#define IOAT_DMA_DESCRIPTOR_CTL_FRAME 0x00000010 +#define IOAT_DMA_DESCRIPTOR_NUL 0x00000020 +#define IOAT_DMA_DESCRIPTOR_OPCODE 0xFF000000 + +#endif diff --git a/drivers/dma/ioatdma_io.h b/drivers/dma/ioatdma_io.h new file mode 100644 index 00000000000..c0b4bf66c92 --- /dev/null +++ b/drivers/dma/ioatdma_io.h @@ -0,0 +1,118 @@ +/* + * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ +#ifndef IOATDMA_IO_H +#define IOATDMA_IO_H + +#include <asm/io.h> + +/* + * device and per-channel MMIO register read and write functions + * this is a lot of anoying inline functions, but it's typesafe + */ + +static inline u8 ioatdma_read8(struct ioat_device *device, + unsigned int offset) +{ + return readb(device->reg_base + offset); +} + +static inline u16 ioatdma_read16(struct ioat_device *device, + unsigned int offset) +{ + return readw(device->reg_base + offset); +} + +static inline u32 ioatdma_read32(struct ioat_device *device, + unsigned int offset) +{ + return readl(device->reg_base + offset); +} + +static inline void ioatdma_write8(struct ioat_device *device, + unsigned int offset, u8 value) +{ + writeb(value, device->reg_base + offset); +} + +static inline void ioatdma_write16(struct ioat_device *device, + unsigned int offset, u16 value) +{ + writew(value, device->reg_base + offset); +} + +static inline void ioatdma_write32(struct ioat_device *device, + unsigned int offset, u32 value) +{ + writel(value, device->reg_base + offset); +} + +static inline u8 ioatdma_chan_read8(struct ioat_dma_chan *chan, + unsigned int offset) +{ + return readb(chan->reg_base + offset); +} + +static inline u16 ioatdma_chan_read16(struct ioat_dma_chan *chan, + unsigned int offset) +{ + return readw(chan->reg_base + offset); +} + +static inline u32 ioatdma_chan_read32(struct ioat_dma_chan *chan, + unsigned int offset) +{ + return readl(chan->reg_base + offset); +} + +static inline void ioatdma_chan_write8(struct ioat_dma_chan *chan, + unsigned int offset, u8 value) +{ + writeb(value, chan->reg_base + offset); +} + +static inline void ioatdma_chan_write16(struct ioat_dma_chan *chan, + unsigned int offset, u16 value) +{ + writew(value, chan->reg_base + offset); +} + +static inline void ioatdma_chan_write32(struct ioat_dma_chan *chan, + unsigned int offset, u32 value) +{ + writel(value, chan->reg_base + offset); +} + +#if (BITS_PER_LONG == 64) +static inline u64 ioatdma_chan_read64(struct ioat_dma_chan *chan, + unsigned int offset) +{ + return readq(chan->reg_base + offset); +} + +static inline void ioatdma_chan_write64(struct ioat_dma_chan *chan, + unsigned int offset, u64 value) +{ + writeq(value, chan->reg_base + offset); +} +#endif + +#endif /* IOATDMA_IO_H */ + diff --git a/drivers/dma/ioatdma_registers.h b/drivers/dma/ioatdma_registers.h new file mode 100644 index 00000000000..41a21ab2b00 --- /dev/null +++ b/drivers/dma/ioatdma_registers.h @@ -0,0 +1,126 @@ +/* + * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ +#ifndef _IOAT_REGISTERS_H_ +#define _IOAT_REGISTERS_H_ + + +/* MMIO Device Registers */ +#define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */ + +#define IOAT_XFERCAP_OFFSET 0x01 /* 8-bit */ +#define IOAT_XFERCAP_4KB 12 +#define IOAT_XFERCAP_8KB 13 +#define IOAT_XFERCAP_16KB 14 +#define IOAT_XFERCAP_32KB 15 +#define IOAT_XFERCAP_32GB 0 + +#define IOAT_GENCTRL_OFFSET 0x02 /* 8-bit */ +#define IOAT_GENCTRL_DEBUG_EN 0x01 + +#define IOAT_INTRCTRL_OFFSET 0x03 /* 8-bit */ +#define IOAT_INTRCTRL_MASTER_INT_EN 0x01 /* Master Interrupt Enable */ +#define IOAT_INTRCTRL_INT_STATUS 0x02 /* ATTNSTATUS -or- Channel Int */ +#define IOAT_INTRCTRL_INT 0x04 /* INT_STATUS -and- MASTER_INT_EN */ + +#define IOAT_ATTNSTATUS_OFFSET 0x04 /* Each bit is a channel */ + +#define IOAT_VER_OFFSET 0x08 /* 8-bit */ +#define IOAT_VER_MAJOR_MASK 0xF0 +#define IOAT_VER_MINOR_MASK 0x0F +#define GET_IOAT_VER_MAJOR(x) ((x) & IOAT_VER_MAJOR_MASK) +#define GET_IOAT_VER_MINOR(x) ((x) & IOAT_VER_MINOR_MASK) + +#define IOAT_PERPORTOFFSET_OFFSET 0x0A /* 16-bit */ + +#define IOAT_INTRDELAY_OFFSET 0x0C /* 16-bit */ +#define IOAT_INTRDELAY_INT_DELAY_MASK 0x3FFF /* Interrupt Delay Time */ +#define IOAT_INTRDELAY_COALESE_SUPPORT 0x8000 /* Interrupt Coalesing Supported */ + +#define IOAT_DEVICE_STATUS_OFFSET 0x0E /* 16-bit */ +#define IOAT_DEVICE_STATUS_DEGRADED_MODE 0x0001 + + +#define IOAT_CHANNEL_MMIO_SIZE 0x80 /* Each Channel MMIO space is this size */ + +/* DMA Channel Registers */ +#define IOAT_CHANCTRL_OFFSET 0x00 /* 16-bit Channel Control Register */ +#define IOAT_CHANCTRL_CHANNEL_PRIORITY_MASK 0xF000 +#define IOAT_CHANCTRL_CHANNEL_IN_USE 0x0100 +#define IOAT_CHANCTRL_DESCRIPTOR_ADDR_SNOOP_CONTROL 0x0020 +#define IOAT_CHANCTRL_ERR_INT_EN 0x0010 +#define IOAT_CHANCTRL_ANY_ERR_ABORT_EN 0x0008 +#define IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004 +#define IOAT_CHANCTRL_INT_DISABLE 0x0001 + +#define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatability */ +#define IOAT_DMA_COMP_V1 0x0001 /* Compatability with DMA version 1 */ + +#define IOAT_CHANSTS_OFFSET 0x04 /* 64-bit Channel Status Register */ +#define IOAT_CHANSTS_OFFSET_LOW 0x04 +#define IOAT_CHANSTS_OFFSET_HIGH 0x08 +#define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR 0xFFFFFFFFFFFFFFC0 +#define IOAT_CHANSTS_SOFT_ERR 0x0000000000000010 +#define IOAT_CHANSTS_DMA_TRANSFER_STATUS 0x0000000000000007 +#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE 0x0 +#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_DONE 0x1 +#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_SUSPENDED 0x2 +#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED 0x3 + +#define IOAT_CHAINADDR_OFFSET 0x0C /* 64-bit Descriptor Chain Address Register */ +#define IOAT_CHAINADDR_OFFSET_LOW 0x0C +#define IOAT_CHAINADDR_OFFSET_HIGH 0x10 + +#define IOAT_CHANCMD_OFFSET 0x14 /* 8-bit DMA Channel Command Register */ +#define IOAT_CHANCMD_RESET 0x20 +#define IOAT_CHANCMD_RESUME 0x10 +#define IOAT_CHANCMD_ABORT 0x08 +#define IOAT_CHANCMD_SUSPEND 0x04 +#define IOAT_CHANCMD_APPEND 0x02 +#define IOAT_CHANCMD_START 0x01 + +#define IOAT_CHANCMP_OFFSET 0x18 /* 64-bit Channel Completion Address Register */ +#define IOAT_CHANCMP_OFFSET_LOW 0x18 +#define IOAT_CHANCMP_OFFSET_HIGH 0x1C + +#define IOAT_CDAR_OFFSET 0x20 /* 64-bit Current Descriptor Address Register */ +#define IOAT_CDAR_OFFSET_LOW 0x20 +#define IOAT_CDAR_OFFSET_HIGH 0x24 + +#define IOAT_CHANERR_OFFSET 0x28 /* 32-bit Channel Error Register */ +#define IOAT_CHANERR_DMA_TRANSFER_SRC_ADDR_ERR 0x0001 +#define IOAT_CHANERR_DMA_TRANSFER_DEST_ADDR_ERR 0x0002 +#define IOAT_CHANERR_NEXT_DESCRIPTOR_ADDR_ERR 0x0004 +#define IOAT_CHANERR_NEXT_DESCRIPTOR_ALIGNMENT_ERR 0x0008 +#define IOAT_CHANERR_CHAIN_ADDR_VALUE_ERR 0x0010 +#define IOAT_CHANERR_CHANCMD_ERR 0x0020 +#define IOAT_CHANERR_CHIPSET_UNCORRECTABLE_DATA_INTEGRITY_ERR 0x0040 +#define IOAT_CHANERR_DMA_UNCORRECTABLE_DATA_INTEGRITY_ERR 0x0080 +#define IOAT_CHANERR_READ_DATA_ERR 0x0100 +#define IOAT_CHANERR_WRITE_DATA_ERR 0x0200 +#define IOAT_CHANERR_DESCRIPTOR_CONTROL_ERR 0x0400 +#define IOAT_CHANERR_DESCRIPTOR_LENGTH_ERR 0x0800 +#define IOAT_CHANERR_COMPLETION_ADDR_ERR 0x1000 +#define IOAT_CHANERR_INT_CONFIGURATION_ERR 0x2000 +#define IOAT_CHANERR_SOFT_ERR 0x4000 + +#define IOAT_CHANERR_MASK_OFFSET 0x2C /* 32-bit Channel Error Register */ + +#endif /* _IOAT_REGISTERS_H_ */ diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c new file mode 100644 index 00000000000..5ed327e453a --- /dev/null +++ b/drivers/dma/iovlock.c @@ -0,0 +1,301 @@ +/* + * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + * Portions based on net/core/datagram.c and copyrighted by their authors. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ + +/* + * This code allows the net stack to make use of a DMA engine for + * skb to iovec copies. + */ + +#include <linux/dmaengine.h> +#include <linux/pagemap.h> +#include <net/tcp.h> /* for memcpy_toiovec */ +#include <asm/io.h> +#include <asm/uaccess.h> + +int num_pages_spanned(struct iovec *iov) +{ + return + ((PAGE_ALIGN((unsigned long)iov->iov_base + iov->iov_len) - + ((unsigned long)iov->iov_base & PAGE_MASK)) >> PAGE_SHIFT); +} + +/* + * Pin down all the iovec pages needed for len bytes. + * Return a struct dma_pinned_list to keep track of pages pinned down. + * + * We are allocating a single chunk of memory, and then carving it up into + * 3 sections, the latter 2 whose size depends on the number of iovecs and the + * total number of pages, respectively. + */ +struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) +{ + struct dma_pinned_list *local_list; + struct page **pages; + int i; + int ret; + int nr_iovecs = 0; + int iovec_len_used = 0; + int iovec_pages_used = 0; + long err; + + /* don't pin down non-user-based iovecs */ + if (segment_eq(get_fs(), KERNEL_DS)) + return NULL; + + /* determine how many iovecs/pages there are, up front */ + do { + iovec_len_used += iov[nr_iovecs].iov_len; + iovec_pages_used += num_pages_spanned(&iov[nr_iovecs]); + nr_iovecs++; + } while (iovec_len_used < len); + + /* single kmalloc for pinned list, page_list[], and the page arrays */ + local_list = kmalloc(sizeof(*local_list) + + (nr_iovecs * sizeof (struct dma_page_list)) + + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); + if (!local_list) { + err = -ENOMEM; + goto out; + } + + /* list of pages starts right after the page list array */ + pages = (struct page **) &local_list->page_list[nr_iovecs]; + + for (i = 0; i < nr_iovecs; i++) { + struct dma_page_list *page_list = &local_list->page_list[i]; + + len -= iov[i].iov_len; + + if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) { + err = -EFAULT; + goto unpin; + } + + page_list->nr_pages = num_pages_spanned(&iov[i]); + page_list->base_address = iov[i].iov_base; + + page_list->pages = pages; + pages += page_list->nr_pages; + + /* pin pages down */ + down_read(¤t->mm->mmap_sem); + ret = get_user_pages( + current, + current->mm, + (unsigned long) iov[i].iov_base, + page_list->nr_pages, + 1, /* write */ + 0, /* force */ + page_list->pages, + NULL); + up_read(¤t->mm->mmap_sem); + + if (ret != page_list->nr_pages) { + err = -ENOMEM; + goto unpin; + } + + local_list->nr_iovecs = i + 1; + } + + return local_list; + +unpin: + dma_unpin_iovec_pages(local_list); +out: + return ERR_PTR(err); +} + +void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) +{ + int i, j; + + if (!pinned_list) + return; + + for (i = 0; i < pinned_list->nr_iovecs; i++) { + struct dma_page_list *page_list = &pinned_list->page_list[i]; + for (j = 0; j < page_list->nr_pages; j++) { + set_page_dirty_lock(page_list->pages[j]); + page_cache_release(page_list->pages[j]); + } + } + + kfree(pinned_list); +} + +static dma_cookie_t dma_memcpy_to_kernel_iovec(struct dma_chan *chan, struct + iovec *iov, unsigned char *kdata, size_t len) +{ + dma_cookie_t dma_cookie = 0; + + while (len > 0) { + if (iov->iov_len) { + int copy = min_t(unsigned int, iov->iov_len, len); + dma_cookie = dma_async_memcpy_buf_to_buf( + chan, + iov->iov_base, + kdata, + copy); + kdata += copy; + len -= copy; + iov->iov_len -= copy; + iov->iov_base += copy; + } + iov++; + } + + return dma_cookie; +} + +/* + * We have already pinned down the pages we will be using in the iovecs. + * Each entry in iov array has corresponding entry in pinned_list->page_list. + * Using array indexing to keep iov[] and page_list[] in sync. + * Initial elements in iov array's iov->iov_len will be 0 if already copied into + * by another call. + * iov array length remaining guaranteed to be bigger than len. + */ +dma_cookie_t dma_memcpy_to_iovec(struct dma_chan *chan, struct iovec *iov, + struct dma_pinned_list *pinned_list, unsigned char *kdata, size_t len) +{ + int iov_byte_offset; + int copy; + dma_cookie_t dma_cookie = 0; + int iovec_idx; + int page_idx; + + if (!chan) + return memcpy_toiovec(iov, kdata, len); + + /* -> kernel copies (e.g. smbfs) */ + if (!pinned_list) + return dma_memcpy_to_kernel_iovec(chan, iov, kdata, len); + + iovec_idx = 0; + while (iovec_idx < pinned_list->nr_iovecs) { + struct dma_page_list *page_list; + + /* skip already used-up iovecs */ + while (!iov[iovec_idx].iov_len) + iovec_idx++; + + page_list = &pinned_list->page_list[iovec_idx]; + + iov_byte_offset = ((unsigned long)iov[iovec_idx].iov_base & ~PAGE_MASK); + page_idx = (((unsigned long)iov[iovec_idx].iov_base & PAGE_MASK) + - ((unsigned long)page_list->base_address & PAGE_MASK)) >> PAGE_SHIFT; + + /* break up copies to not cross page boundary */ + while (iov[iovec_idx].iov_len) { + copy = min_t(int, PAGE_SIZE - iov_byte_offset, len); + copy = min_t(int, copy, iov[iovec_idx].iov_len); + + dma_cookie = dma_async_memcpy_buf_to_pg(chan, + page_list->pages[page_idx], + iov_byte_offset, + kdata, + copy); + + len -= copy; + iov[iovec_idx].iov_len -= copy; + iov[iovec_idx].iov_base += copy; + + if (!len) + return dma_cookie; + + kdata += copy; + iov_byte_offset = 0; + page_idx++; + } + iovec_idx++; + } + + /* really bad if we ever run out of iovecs */ + BUG(); + return -EFAULT; +} + +dma_cookie_t dma_memcpy_pg_to_iovec(struct dma_chan *chan, struct iovec *iov, + struct dma_pinned_list *pinned_list, struct page *page, + unsigned int offset, size_t len) +{ + int iov_byte_offset; + int copy; + dma_cookie_t dma_cookie = 0; + int iovec_idx; + int page_idx; + int err; + + /* this needs as-yet-unimplemented buf-to-buff, so punt. */ + /* TODO: use dma for this */ + if (!chan || !pinned_list) { + u8 *vaddr = kmap(page); + err = memcpy_toiovec(iov, vaddr + offset, len); + kunmap(page); + return err; + } + + iovec_idx = 0; + while (iovec_idx < pinned_list->nr_iovecs) { + struct dma_page_list *page_list; + + /* skip already used-up iovecs */ + while (!iov[iovec_idx].iov_len) + iovec_idx++; + + page_list = &pinned_list->page_list[iovec_idx]; + + iov_byte_offset = ((unsigned long)iov[iovec_idx].iov_base & ~PAGE_MASK); + page_idx = (((unsigned long)iov[iovec_idx].iov_base & PAGE_MASK) + - ((unsigned long)page_list->base_address & PAGE_MASK)) >> PAGE_SHIFT; + + /* break up copies to not cross page boundary */ + while (iov[iovec_idx].iov_len) { + copy = min_t(int, PAGE_SIZE - iov_byte_offset, len); + copy = min_t(int, copy, iov[iovec_idx].iov_len); + + dma_cookie = dma_async_memcpy_pg_to_pg(chan, + page_list->pages[page_idx], + iov_byte_offset, + page, + offset, + copy); + + len -= copy; + iov[iovec_idx].iov_len -= copy; + iov[iovec_idx].iov_base += copy; + + if (!len) + return dma_cookie; + + offset += copy; + iov_byte_offset = 0; + page_idx++; + } + iovec_idx++; + } + + /* really bad if we ever run out of iovecs */ + BUG(); + return -EFAULT; +} diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index afc612b8577..ba2d6505e9a 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig @@ -29,6 +29,11 @@ config INFINIBAND_USER_ACCESS libibverbs, libibcm and a hardware driver library from <http://www.openib.org>. +config INFINIBAND_ADDR_TRANS + bool + depends on INFINIBAND && INET + default y + source "drivers/infiniband/hw/mthca/Kconfig" source "drivers/infiniband/hw/ipath/Kconfig" diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index ec3353f24b2..68e73ec2d1f 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile @@ -1,5 +1,7 @@ +infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := ib_addr.o rdma_cm.o + obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ - ib_cm.o + ib_cm.o $(infiniband-y) obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o @@ -12,8 +14,13 @@ ib_sa-y := sa_query.o ib_cm-y := cm.o +rdma_cm-y := cma.o + +ib_addr-y := addr.o + ib_umad-y := user_mad.o ib_ucm-y := ucm.o -ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_mem.o +ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_mem.o \ + uverbs_marshall.o diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c new file mode 100644 index 00000000000..d294bbc42f0 --- /dev/null +++ b/drivers/infiniband/core/addr.c @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2005 Voltaire Inc. All rights reserved. + * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. + * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved. + * Copyright (c) 2005 Intel Corporation. All rights reserved. + * + * This Software is licensed under one of the following licenses: + * + * 1) under the terms of the "Common Public License 1.0" a copy of which is + * available from the Open Source Initiative, see + * http://www.opensource.org/licenses/cpl.php. + * + * 2) under the terms of the "The BSD License" a copy of which is + * available from the Open Source Initiative, see + * http://www.opensource.org/licenses/bsd-license.php. + * + * 3) under the terms of the "GNU General Public License (GPL) Version 2" a + * copy of which is available from the Open Source Initiative, see + * http://www.opensource.org/licenses/gpl-license.php. + * + * Licensee has the right to choose one of the above licenses. + * + * Redistributions of source code must retain the above copyright + * notice and one of the license notices. + * + * Redistributions in binary form must reproduce both the above copyright + * notice, one of the license notices in the documentation + * and/or other materials provided with the distribution. + */ + +#include <linux/mutex.h> +#include <linux/inetdevice.h> +#include <linux/workqueue.h> +#include <linux/if_arp.h> +#include <net/arp.h> +#include <net/neighbour.h> +#include <net/route.h> +#include <rdma/ib_addr.h> + +MODULE_AUTHOR("Sean Hefty"); +MODULE_DESCRIPTION("IB Address Translation"); +MODULE_LICENSE("Dual BSD/GPL"); + +struct addr_req { + struct list_head list; + struct sockaddr src_addr; + struct sockaddr dst_addr; + struct rdma_dev_addr *addr; + void *context; + void (*callback)(int status, struct sockaddr *src_addr, + struct rdma_dev_addr *addr, void *context); + unsigned long timeout; + int status; +}; + +static void process_req(void *data); + +static DEFINE_MUTEX(lock); +static LIST_HEAD(req_list); +static DECLARE_WORK(work, process_req, NULL); +static struct workqueue_struct *addr_wq; + +static int copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, + unsigned char *dst_dev_addr) +{ + switch (dev->type) { + case ARPHRD_INFINIBAND: + dev_addr->dev_type = IB_NODE_CA; + break; + default: + return -EADDRNOTAVAIL; + } + + memcpy(dev_addr->src_dev_addr, dev->dev_addr, MAX_ADDR_LEN); + memcpy(dev_addr->broadcast, dev->broadcast, MAX_ADDR_LEN); + if (dst_dev_addr) + memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN); + return 0; +} + +int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) +{ + struct net_device *dev; + u32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr; + int ret; + + dev = ip_dev_find(ip); + if (!dev) + return -EADDRNOTAVAIL; + + ret = copy_addr(dev_addr, dev, NULL); + dev_put(dev); + return ret; +} +EXPORT_SYMBOL(rdma_translate_ip); + +static void set_timeout(unsigned long time) +{ + unsigned long delay; + + cancel_delayed_work(&work); + + delay = time - jiffies; + if ((long)delay <= 0) + delay = 1; + + queue_delayed_work(addr_wq, &work, delay); +} + +static void queue_req(struct addr_req *req) +{ + struct addr_req *temp_req; + + mutex_lock(&lock); + list_for_each_entry_reverse(temp_req, &req_list, list) { + if (time_after(req->timeout, temp_req->timeout)) + break; + } + + list_add(&req->list, &temp_req->list); + + if (req_list.next == &req->list) + set_timeout(req->timeout); + mutex_unlock(&lock); +} + +static void addr_send_arp(struct sockaddr_in *dst_in) +{ + struct rtable *rt; + struct flowi fl; + u32 dst_ip = dst_in->sin_addr.s_addr; + + memset(&fl, 0, sizeof fl); + fl.nl_u.ip4_u.daddr = dst_ip; + if (ip_route_output_key(&rt, &fl)) + return; + + arp_send(ARPOP_REQUEST, ETH_P_ARP, rt->rt_gateway, rt->idev->dev, + rt->rt_src, NULL, rt->idev->dev->dev_addr, NULL); + ip_rt_put(rt); +} + +static int addr_resolve_remote(struct sockaddr_in *src_in, + struct sockaddr_in *dst_in, + struct rdma_dev_addr *addr) +{ + u32 src_ip = src_in->sin_addr.s_addr; + u32 dst_ip = dst_in->sin_addr.s_addr; + struct flowi fl; + struct rtable *rt; + struct neighbour *neigh; + int ret; + + memset(&fl, 0, sizeof fl); + fl.nl_u.ip4_u.daddr = dst_ip; + fl.nl_u.ip4_u.saddr = src_ip; + ret = ip_route_output_key(&rt, &fl); + if (ret) + goto out; + + /* If the device does ARP internally, return 'done' */ + if (rt->idev->dev->flags & IFF_NOARP) { + copy_addr(addr, rt->idev->dev, NULL); + goto put; + } + + neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev); + if (!neigh) { + ret = -ENODATA; + goto put; + } + + if (!(neigh->nud_state & NUD_VALID)) { + ret = -ENODATA; + goto release; + } + + if (!src_ip) { + src_in->sin_family = dst_in->sin_family; + src_in->sin_addr.s_addr = rt->rt_src; + } + + ret = copy_addr(addr, neigh->dev, neigh->ha); +release: + neigh_release(neigh); +put: + ip_rt_put(rt); +out: + return ret; +} + +static void process_req(void *data) +{ + struct addr_req *req, *temp_req; + struct sockaddr_in *src_in, *dst_in; + struct list_head done_list; + + INIT_LIST_HEAD(&done_list); + + mutex_lock(&lock); + list_for_each_entry_safe(req, temp_req, &req_list, list) { + if (req->status) { + src_in = (struct sockaddr_in *) &req->src_addr; + dst_in = (struct sockaddr_in *) &req->dst_addr; + req->status = addr_resolve_remote(src_in, dst_in, + req->addr); + } + if (req->status && time_after(jiffies, req->timeout)) + req->status = -ETIMEDOUT; + else if (req->status == -ENODATA) + continue; + + list_del(&req->list); + list_add_tail(&req->list, &done_list); + } + + if (!list_empty(&req_list)) { + req = list_entry(req_list.next, struct addr_req, list); + set_timeout(req->timeout); + } + mutex_unlock(&lock); + + list_for_each_entry_safe(req, temp_req, &done_list, list) { + list_del(&req->list); + req->callback(req->status, &req->src_addr, req->addr, + req->context); + kfree(req); + } +} + +static int addr_resolve_local(struct sockaddr_in *src_in, + struct sockaddr_in *dst_in, + struct rdma_dev_addr *addr) +{ + struct net_device *dev; + u32 src_ip = src_in->sin_addr.s_addr; + u32 dst_ip = dst_in->sin_addr.s_addr; + int ret; + + dev = ip_dev_find(dst_ip); + if (!dev) + return -EADDRNOTAVAIL; + + if (ZERONET(src_ip)) { + src_in->sin_family = dst_in->sin_family; + src_in->sin_addr.s_addr = dst_ip; + ret = copy_addr(addr, dev, dev->dev_addr); + } else if (LOOPBACK(src_ip)) { + ret = rdma_translate_ip((struct sockaddr *)dst_in, addr); + if (!ret) + memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); + } else { + ret = rdma_translate_ip((struct sockaddr *)src_in, addr); + if (!ret) + memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); + } + + dev_put(dev); + return ret; +} + +int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, + struct rdma_dev_addr *addr, int timeout_ms, + void (*callback)(int status, struct sockaddr *src_addr, + struct rdma_dev_addr *addr, void *context), + void *context) +{ + struct sockaddr_in *src_in, *dst_in; + struct addr_req *req; + int ret = 0; + + req = kmalloc(sizeof *req, GFP_KERNEL); + if (!req) + return -ENOMEM; + memset(req, 0, sizeof *req); + + if (src_addr) + memcpy(&req->src_addr, src_addr, ip_addr_size(src_addr)); + memcpy(&req->dst_addr, dst_addr, ip_addr_size(dst_addr)); + req->addr = addr; + req->callback = callback; + req->context = context; + + src_in = (struct sockaddr_in *) &req->src_addr; + dst_in = (struct sockaddr_in *) &req->dst_addr; + + req->status = addr_resolve_local(src_in, dst_in, addr); + if (req->status == -EADDRNOTAVAIL) + req->status = addr_resolve_remote(src_in, dst_in, addr); + + switch (req->status) { + case 0: + req->timeout = jiffies; + queue_req(req); + break; + case -ENODATA: + req->timeout = msecs_to_jiffies(timeout_ms) + jiffies; + queue_req(req); + addr_send_arp(dst_in); + break; + default: + ret = req->status; + kfree(req); + break; + } + return ret; +} +EXPORT_SYMBOL(rdma_resolve_ip); + +void rdma_addr_cancel(struct rdma_dev_addr *addr) +{ + struct addr_req *req, *temp_req; + + mutex_lock(&lock); + list_for_each_entry_safe(req, temp_req, &req_list, list) { + if (req->addr == addr) { + req->status = -ECANCELED; + req->timeout = jiffies; + list_del(&req->list); + list_add(&req->list, &req_list); + set_timeout(req->timeout); + break; + } + } + mutex_unlock(&lock); +} +EXPORT_SYMBOL(rdma_addr_cancel); + +static int addr_arp_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pkt, struct net_device *orig_dev) +{ + struct arphdr *arp_hdr; + + arp_hdr = (struct arphdr *) skb->nh.raw; + + if (arp_hdr->ar_op == htons(ARPOP_REQUEST) || + arp_hdr->ar_op == htons(ARPOP_REPLY)) + set_timeout(jiffies); + + kfree_skb(skb); + return 0; +} + +static struct packet_type addr_arp = { + .type = __constant_htons(ETH_P_ARP), + .func = addr_arp_recv, + .af_packet_priv = (void*) 1, +}; + +static int addr_init(void) +{ + addr_wq = create_singlethread_workqueue("ib_addr_wq"); + if (!addr_wq) + return -ENOMEM; + + dev_add_pack(&addr_arp); + return 0; +} + +static void addr_cleanup(void) +{ + dev_remove_pack(&addr_arp); + destroy_workqueue(addr_wq); +} + +module_init(addr_init); +module_exit(addr_cleanup); diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 50364c0b090..e05ca2cdc73 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -191,6 +191,24 @@ int ib_find_cached_pkey(struct ib_device *device, } EXPORT_SYMBOL(ib_find_cached_pkey); +int ib_get_cached_lmc(struct ib_device *device, + u8 port_num, + u8 *lmc) +{ + unsigned long flags; + int ret = 0; + + if (port_num < start_port(device) || port_num > end_port(device)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); + *lmc = device->cache.lmc_cache[port_num - start_port(device)]; + read_unlock_irqrestore(&device->cache.lock, flags); + + return ret; +} +EXPORT_SYMBOL(ib_get_cached_lmc); + static void ib_cache_update(struct ib_device *device, u8 port) { @@ -251,6 +269,8 @@ static void ib_cache_update(struct ib_device *device, device->cache.pkey_cache[port - start_port(device)] = pkey_cache; device->cache.gid_cache [port - start_port(device)] = gid_cache; + device->cache.lmc_cache[port - start_port(device)] = tprops->lmc; + write_unlock_irq(&device->cache.lock); kfree(old_pkey_cache); @@ -305,7 +325,13 @@ static void ib_cache_setup_one(struct ib_device *device) kmalloc(sizeof *device->cache.gid_cache * (end_port(device) - start_port(device) + 1), GFP_KERNEL); - if (!device->cache.pkey_cache || !device->cache.gid_cache) { + device->cache.lmc_cache = kmalloc(sizeof *device->cache.lmc_cache * + (end_port(device) - + start_port(device) + 1), + GFP_KERNEL); + + if (!device->cache.pkey_cache || !device->cache.gid_cache || + !device->cache.lmc_cache) { printk(KERN_WARNING "Couldn't allocate cache " "for %s\n", device->name); goto err; @@ -333,6 +359,7 @@ err_cache: err: kfree(device->cache.pkey_cache); kfree(device->cache.gid_cache); + kfree(device->cache.lmc_cache); } static void ib_cache_cleanup_one(struct ib_device *device) @@ -349,6 +376,7 @@ static void ib_cache_cleanup_one(struct ib_device *device) kfree(device->cache.pkey_cache); kfree(device->cache.gid_cache); + kfree(device->cache.lmc_cache); } static struct ib_client cache_client = { diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 86fee43502c..450adfe0a4f 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -32,7 +32,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * $Id: cm.c 2821 2005-07-08 17:07:28Z sean.hefty $ + * $Id: cm.c 4311 2005-12-05 18:42:01Z sean.hefty $ */ #include <linux/completion.h> @@ -132,6 +132,7 @@ struct cm_id_private { /* todo: use alternate port on send failure */ struct cm_av av; struct cm_av alt_av; + struct ib_cm_compare_data *compare_data; void *private_data; __be64 tid; @@ -253,23 +254,13 @@ static void cm_set_private_data(struct cm_id_private *cm_id_priv, cm_id_priv->private_data_len = private_data_len; } -static void cm_set_ah_attr(struct ib_ah_attr *ah_attr, u8 port_num, - u16 dlid, u8 sl, u16 src_path_bits) -{ - memset(ah_attr, 0, sizeof ah_attr); - ah_attr->dlid = dlid; - ah_attr->sl = sl; - ah_attr->src_path_bits = src_path_bits; - ah_attr->port_num = port_num; -} - -static void cm_init_av_for_response(struct cm_port *port, - struct ib_wc *wc, struct cm_av *av) +static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc, + struct ib_grh *grh, struct cm_av *av) { av->port = port; av->pkey_index = wc->pkey_index; - cm_set_ah_attr(&av->ah_attr, port->port_num, wc->slid, - wc->sl, wc->dlid_path_bits); + ib_init_ah_from_wc(port->cm_dev->device, port->port_num, wc, + grh, &av->ah_attr); } static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) @@ -299,9 +290,8 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) return ret; av->port = port; - cm_set_ah_attr(&av->ah_attr, av->port->port_num, - be16_to_cpu(path->dlid), path->sl, - be16_to_cpu(path->slid) & 0x7F); + ib_init_ah_from_path(cm_dev->device, port->port_num, path, + &av->ah_attr); av->packet_life_time = path->packet_life_time; return 0; } @@ -357,6 +347,41 @@ static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id) return cm_id_priv; } +static void cm_mask_copy(u8 *dst, u8 *src, u8 *mask) +{ + int i; + + for (i = 0; i < IB_CM_COMPARE_SIZE / sizeof(unsigned long); i++) + ((unsigned long *) dst)[i] = ((unsigned long *) src)[i] & + ((unsigned long *) mask)[i]; +} + +static int cm_compare_data(struct ib_cm_compare_data *src_data, + struct ib_cm_compare_data *dst_data) +{ + u8 src[IB_CM_COMPARE_SIZE]; + u8 dst[IB_CM_COMPARE_SIZE]; + + if (!src_data || !dst_data) + return 0; + + cm_mask_copy(src, src_data->data, dst_data->mask); + cm_mask_copy(dst, dst_data->data, src_data->mask); + return memcmp(src, dst, IB_CM_COMPARE_SIZE); +} + +static int cm_compare_private_data(u8 *private_data, + struct ib_cm_compare_data *dst_data) +{ + u8 src[IB_CM_COMPARE_SIZE]; + + if (!dst_data) + return 0; + + cm_mask_copy(src, private_data, dst_data->mask); + return memcmp(src, dst_data->data, IB_CM_COMPARE_SIZE); +} + static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) { struct rb_node **link = &cm.listen_service_table.rb_node; @@ -364,14 +389,18 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) struct cm_id_private *cur_cm_id_priv; __be64 service_id = cm_id_priv->id.service_id; __be64 service_mask = cm_id_priv->id.service_mask; + int data_cmp; while (*link) { parent = *link; cur_cm_id_priv = rb_entry(parent, struct cm_id_private, service_node); + data_cmp = cm_compare_data(cm_id_priv->compare_data, + cur_cm_id_priv->compare_data); if ((cur_cm_id_priv->id.service_mask & service_id) == (service_mask & cur_cm_id_priv->id.service_id) && - (cm_id_priv->id.device == cur_cm_id_priv->id.device)) + (cm_id_priv->id.device == cur_cm_id_priv->id.device) && + !data_cmp) return cur_cm_id_priv; if (cm_id_priv->id.device < cur_cm_id_priv->id.device) @@ -380,6 +409,10 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) link = &(*link)->rb_right; else if (service_id < cur_cm_id_priv->id.service_id) link = &(*link)->rb_left; + else if (service_id > cur_cm_id_priv->id.service_id) + link = &(*link)->rb_right; + else if (data_cmp < 0) + link = &(*link)->rb_left; else link = &(*link)->rb_right; } @@ -389,16 +422,20 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) } static struct cm_id_private * cm_find_listen(struct ib_device *device, - __be64 service_id) + __be64 service_id, + u8 *private_data) { struct rb_node *node = cm.listen_service_table.rb_node; struct cm_id_private *cm_id_priv; + int data_cmp; while (node) { cm_id_priv = rb_entry(node, struct cm_id_private, service_node); + data_cmp = cm_compare_private_data(private_data, + cm_id_priv->compare_data); if ((cm_id_priv->id.service_mask & service_id) == cm_id_priv->id.service_id && - (cm_id_priv->id.device == device)) + (cm_id_priv->id.device == device) && !data_cmp) return cm_id_priv; if (device < cm_id_priv->id.device) @@ -407,6 +444,10 @@ static struct cm_id_private * cm_find_listen(struct ib_device *device, node = node->rb_right; else if (service_id < cm_id_priv->id.service_id) node = node->rb_left; + else if (service_id > cm_id_priv->id.service_id) + node = node->rb_right; + else if (data_cmp < 0) + node = node->rb_left; else node = node->rb_right; } @@ -730,15 +771,14 @@ retest: wait_for_completion(&cm_id_priv->comp); while ((work = cm_dequeue_work(cm_id_priv)) != NULL) cm_free_work(work); - if (cm_id_priv->private_data && cm_id_priv->private_data_len) - kfree(cm_id_priv->private_data); + kfree(cm_id_priv->compare_data); + kfree(cm_id_priv->private_data); kfree(cm_id_priv); } EXPORT_SYMBOL(ib_destroy_cm_id); -int ib_cm_listen(struct ib_cm_id *cm_id, - __be64 service_id, - __be64 service_mask) +int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask, + struct ib_cm_compare_data *compare_data) { struct cm_id_private *cm_id_priv, *cur_cm_id_priv; unsigned long flags; @@ -752,7 +792,19 @@ int ib_cm_listen(struct ib_cm_id *cm_id, return -EINVAL; cm_id_priv = container_of(cm_id, struct cm_id_private, id); - BUG_ON(cm_id->state != IB_CM_IDLE); + if (cm_id->state != IB_CM_IDLE) + return -EINVAL; + + if (compare_data) { + cm_id_priv->compare_data = kzalloc(sizeof *compare_data, + GFP_KERNEL); + if (!cm_id_priv->compare_data) + return -ENOMEM; + cm_mask_copy(cm_id_priv->compare_data->data, + compare_data->data, compare_data->mask); + memcpy(cm_id_priv->compare_data->mask, compare_data->mask, + IB_CM_COMPARE_SIZE); + } cm_id->state = IB_CM_LISTEN; @@ -769,6 +821,8 @@ int ib_cm_listen(struct ib_cm_id *cm_id, if (cur_cm_id_priv) { cm_id->state = IB_CM_IDLE; + kfree(cm_id_priv->compare_data); + cm_id_priv->compare_data = NULL; ret = -EBUSY; } return ret; @@ -1241,7 +1295,8 @@ static struct cm_id_private * cm_match_req(struct cm_work *work, /* Find matching listen request. */ listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device, - req_msg->service_id); + req_msg->service_id, + req_msg->private_data); if (!listen_cm_id_priv) { spin_unlock_irqrestore(&cm.lock, flags); cm_issue_rej(work->port, work->mad_recv_wc, @@ -1276,6 +1331,7 @@ static int cm_req_handler(struct cm_work *work) cm_id_priv = container_of(cm_id, struct cm_id_private, id); cm_id_priv->id.remote_id = req_msg->local_comm_id; cm_init_av_for_response(work->port, work->mad_recv_wc->wc, + work->mad_recv_wc->recv_buf.grh, &cm_id_priv->av); cm_id_priv->timewait_info = cm_create_timewait_info(cm_id_priv-> id.local_id); @@ -2549,7 +2605,7 @@ static void cm_format_sidr_req(struct cm_sidr_req_msg *sidr_req_msg, cm_format_mad_hdr(&sidr_req_msg->hdr, CM_SIDR_REQ_ATTR_ID, cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_SIDR)); sidr_req_msg->request_id = cm_id_priv->id.local_id; - sidr_req_msg->pkey = cpu_to_be16(param->pkey); + sidr_req_msg->pkey = cpu_to_be16(param->path->pkey); sidr_req_msg->service_id = param->service_id; if (param->private_data && param->private_data_len) @@ -2641,6 +2697,7 @@ static int cm_sidr_req_handler(struct cm_work *work) cm_id_priv->av.dgid.global.subnet_prefix = cpu_to_be64(wc->slid); cm_id_priv->av.dgid.global.interface_id = 0; cm_init_av_for_response(work->port, work->mad_recv_wc->wc, + work->mad_recv_wc->recv_buf.grh, &cm_id_priv->av); cm_id_priv->id.remote_id = sidr_req_msg->request_id; cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD; @@ -2654,7 +2711,8 @@ static int cm_sidr_req_handler(struct cm_work *work) goto out; /* Duplicate message. */ } cur_cm_id_priv = cm_find_listen(cm_id->device, - sidr_req_msg->service_id); + sidr_req_msg->service_id, + sidr_req_msg->private_data); if (!cur_cm_id_priv) { rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); spin_unlock_irqrestore(&cm.lock, flags); @@ -3291,7 +3349,6 @@ error: static void __exit ib_cm_cleanup(void) { - flush_workqueue(cm.wq); destroy_workqueue(cm.wq); ib_unregister_client(&cm_client); idr_destroy(&cm.local_id_table); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c new file mode 100644 index 00000000000..a76834edf60 --- /dev/null +++ b/drivers/infiniband/core/cma.c @@ -0,0 +1,1927 @@ +/* + * Copyright (c) 2005 Voltaire Inc. All rights reserved. + * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. + * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved. + * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. + * + * This Software is licensed under one of the following licenses: + * + * 1) under the terms of the "Common Public License 1.0" a copy of which is + * available from the Open Source Initiative, see + * http://www.opensource.org/licenses/cpl.php. + * + * 2) under the terms of the "The BSD License" a copy of which is + * available from the Open Source Initiative, see + * http://www.opensource.org/licenses/bsd-license.php. + * + * 3) under the terms of the "GNU General Public License (GPL) Version 2" a + * copy of which is available from the Open Source Initiative, see + * http://www.opensource.org/licenses/gpl-license.php. + * + * Licensee has the right to choose one of the above licenses. + * + * Redistributions of source code must retain the above copyright + * notice and one of the license notices. + * + * Redistributions in binary form must reproduce both the above copyright + * notice, one of the license notices in the documentation + * and/or other materials provided with the distribution. + * + */ + +#include <linux/completion.h> +#include <linux/in.h> +#include <linux/in6.h> +#include <linux/mutex.h> +#include <linux/random.h> +#include <linux/idr.h> + +#include <net/tcp.h> + +#include <rdma/rdma_cm.h> +#include <rdma/rdma_cm_ib.h> +#include <rdma/ib_cache.h> +#include <rdma/ib_cm.h> +#include <rdma/ib_sa.h> + +MODULE_AUTHOR("Sean Hefty"); +MODULE_DESCRIPTION("Generic RDMA CM Agent"); +MODULE_LICENSE("Dual BSD/GPL"); + +#define CMA_CM_RESPONSE_TIMEOUT 20 +#define CMA_MAX_CM_RETRIES 3 + +static void cma_add_one(struct ib_device *device); +static void cma_remove_one(struct ib_device *device); + +static struct ib_client cma_client = { + .name = "cma", + .add = cma_add_one, + .remove = cma_remove_one +}; + +static LIST_HEAD(dev_list); +static LIST_HEAD(listen_any_list); +static DEFINE_MUTEX(lock); +static struct workqueue_struct *cma_wq; +static DEFINE_IDR(sdp_ps); +static DEFINE_IDR(tcp_ps); + +struct cma_device { + struct list_head list; + struct ib_device *device; + __be64 node_guid; + struct completion comp; + atomic_t refcount; + struct list_head id_list; +}; + +enum cma_state { + CMA_IDLE, + CMA_ADDR_QUERY, + CMA_ADDR_RESOLVED, + CMA_ROUTE_QUERY, + CMA_ROUTE_RESOLVED, + CMA_CONNECT, + CMA_DISCONNECT, + CMA_ADDR_BOUND, + CMA_LISTEN, + CMA_DEVICE_REMOVAL, + CMA_DESTROYING +}; + +struct rdma_bind_list { + struct idr *ps; + struct hlist_head owners; + unsigned short port; +}; + +/* + * Device removal can occur at anytime, so we need extra handling to + * serialize notifying the user of device removal with other callbacks. + * We do this by disabling removal notification while a callback is in process, + * and reporting it after the callback completes. + */ +struct rdma_id_private { + struct rdma_cm_id id; + + struct rdma_bind_list *bind_list; + struct hlist_node node; + struct list_head list; + struct list_head listen_list; + struct cma_device *cma_dev; + + enum cma_state state; + spinlock_t lock; + struct completion comp; + atomic_t refcount; + wait_queue_head_t wait_remove; + atomic_t dev_remove; + + int backlog; + int timeout_ms; + struct ib_sa_query *query; + int query_id; + union { + struct ib_cm_id *ib; + } cm_id; + + u32 seq_num; + u32 qp_num; + enum ib_qp_type qp_type; + u8 srq; +}; + +struct cma_work { + struct work_struct work; + struct rdma_id_private *id; + enum cma_state old_state; + enum cma_state new_state; + struct rdma_cm_event event; +}; + +union cma_ip_addr { + struct in6_addr ip6; + struct { + __u32 pad[3]; + __u32 addr; + } ip4; +}; + +struct cma_hdr { + u8 cma_version; + u8 ip_version; /* IP version: 7:4 */ + __u16 port; + union cma_ip_addr src_addr; + union cma_ip_addr dst_addr; +}; + +struct sdp_hh { + u8 bsdh[16]; + u8 sdp_version; /* Major version: 7:4 */ + u8 ip_version; /* IP version: 7:4 */ + u8 sdp_specific1[10]; + __u16 port; + __u16 sdp_specific2; + union cma_ip_addr src_addr; + union cma_ip_addr dst_addr; +}; + +struct sdp_hah { + u8 bsdh[16]; + u8 sdp_version; +}; + +#define CMA_VERSION 0x00 +#define SDP_MAJ_VERSION 0x2 + +static int cma_comp(struct rdma_id_private *id_priv, enum cma_state comp) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&id_priv->lock, flags); + ret = (id_priv->state == comp); + spin_unlock_irqrestore(&id_priv->lock, flags); + return ret; +} + +static int cma_comp_exch(struct rdma_id_private *id_priv, + enum cma_state comp, enum cma_state exch) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&id_priv->lock, flags); + if ((ret = (id_priv->state == comp))) + id_priv->state = exch; + spin_unlock_irqrestore(&id_priv->lock, flags); + return ret; +} + +static enum cma_state cma_exch(struct rdma_id_private *id_priv, + enum cma_state exch) +{ + unsigned long flags; + enum cma_state old; + + spin_lock_irqsave(&id_priv->lock, flags); + old = id_priv->state; + id_priv->state = exch; + spin_unlock_irqrestore(&id_priv->lock, flags); + return old; +} + +static inline u8 cma_get_ip_ver(struct cma_hdr *hdr) +{ + return hdr->ip_version >> 4; +} + +static inline void cma_set_ip_ver(struct cma_hdr *hdr, u8 ip_ver) +{ + hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF); +} + +static inline u8 sdp_get_majv(u8 sdp_version) +{ + return sdp_version >> 4; +} + +static inline u8 sdp_get_ip_ver(struct sdp_hh *hh) +{ + return hh->ip_version >> 4; +} + +static inline void sdp_set_ip_ver(struct sdp_hh *hh, u8 ip_ver) +{ + hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF); +} + +static void cma_attach_to_dev(struct rdma_id_private *id_priv, + struct cma_device *cma_dev) +{ + atomic_inc(&cma_dev->refcount); + id_priv->cma_dev = cma_dev; + id_priv->id.device = cma_dev->device; + list_add_tail(&id_priv->list, &cma_dev->id_list); +} + +static inline void cma_deref_dev(struct cma_device *cma_dev) +{ + if (atomic_dec_and_test(&cma_dev->refcount)) + complete(&cma_dev->comp); +} + +static void cma_detach_from_dev(struct rdma_id_private *id_priv) +{ + list_del(&id_priv->list); + cma_deref_dev(id_priv->cma_dev); + id_priv->cma_dev = NULL; +} + +static int cma_acquire_ib_dev(struct rdma_id_private *id_priv) +{ + struct cma_device *cma_dev; + union ib_gid *gid; + int ret = -ENODEV; + + gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr); + + mutex_lock(&lock); + list_for_each_entry(cma_dev, &dev_list, list) { + ret = ib_find_cached_gid(cma_dev->device, gid, + &id_priv->id.port_num, NULL); + if (!ret) { + cma_attach_to_dev(id_priv, cma_dev); + break; + } + } + mutex_unlock(&lock); + return ret; +} + +static int cma_acquire_dev(struct rdma_id_private *id_priv) +{ + switch (id_priv->id.route.addr.dev_addr.dev_type) { + case IB_NODE_CA: + return cma_acquire_ib_dev(id_priv); + default: + return -ENODEV; + } +} + +static void cma_deref_id(struct rdma_id_private *id_priv) +{ + if (atomic_dec_and_test(&id_priv->refcount)) + complete(&id_priv->comp); +} + +static void cma_release_remove(struct rdma_id_private *id_priv) +{ + if (atomic_dec_and_test(&id_priv->dev_remove)) + wake_up(&id_priv->wait_remove); +} + +struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler, + void *context, enum rdma_port_space ps) +{ + struct rdma_id_private *id_priv; + + id_priv = kzalloc(sizeof *id_priv, GFP_KERNEL); + if (!id_priv) + return ERR_PTR(-ENOMEM); + + id_priv->state = CMA_IDLE; + id_priv->id.context = context; + id_priv->id.event_handler = event_handler; + id_priv->id.ps = ps; + spin_lock_init(&id_priv->lock); + init_completion(&id_priv->comp); + atomic_set(&id_priv->refcount, 1); + init_waitqueue_head(&id_priv->wait_remove); + atomic_set(&id_priv->dev_remove, 0); + INIT_LIST_HEAD(&id_priv->listen_list); + get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num); + + return &id_priv->id; +} +EXPORT_SYMBOL(rdma_create_id); + +static int cma_init_ib_qp(struct rdma_id_private *id_priv, struct ib_qp *qp) +{ + struct ib_qp_attr qp_attr; + struct rdma_dev_addr *dev_addr; + int ret; + + dev_addr = &id_priv->id.route.addr.dev_addr; + ret = ib_find_cached_pkey(id_priv->id.device, id_priv->id.port_num, + ib_addr_get_pkey(dev_addr), + &qp_attr.pkey_index); + if (ret) + return ret; + + qp_attr.qp_state = IB_QPS_INIT; + qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE; + qp_attr.port_num = id_priv->id.port_num; + return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS | + IB_QP_PKEY_INDEX | IB_QP_PORT); +} + +int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd, + struct ib_qp_init_attr *qp_init_attr) +{ + struct rdma_id_private *id_priv; + struct ib_qp *qp; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (id->device != pd->device) + return -EINVAL; + + qp = ib_create_qp(pd, qp_init_attr); + if (IS_ERR(qp)) + return PTR_ERR(qp); + + switch (id->device->node_type) { + case IB_NODE_CA: + ret = cma_init_ib_qp(id_priv, qp); + break; + default: + ret = -ENOSYS; + break; + } + + if (ret) + goto err; + + id->qp = qp; + id_priv->qp_num = qp->qp_num; + id_priv->qp_type = qp->qp_type; + id_priv->srq = (qp->srq != NULL); + return 0; +err: + ib_destroy_qp(qp); + return ret; +} +EXPORT_SYMBOL(rdma_create_qp); + +void rdma_destroy_qp(struct rdma_cm_id *id) +{ + ib_destroy_qp(id->qp); +} +EXPORT_SYMBOL(rdma_destroy_qp); + +static int cma_modify_qp_rtr(struct rdma_cm_id *id) +{ + struct ib_qp_attr qp_attr; + int qp_attr_mask, ret; + + if (!id->qp) + return 0; + + /* Need to update QP attributes from default values. */ + qp_attr.qp_state = IB_QPS_INIT; + ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask); + if (ret) + return ret; + + ret = ib_modify_qp(id->qp, &qp_attr, qp_attr_mask); + if (ret) + return ret; + + qp_attr.qp_state = IB_QPS_RTR; + ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask); + if (ret) + return ret; + + return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask); +} + +static int cma_modify_qp_rts(struct rdma_cm_id *id) +{ + struct ib_qp_attr qp_attr; + int qp_attr_mask, ret; + + if (!id->qp) + return 0; + + qp_attr.qp_state = IB_QPS_RTS; + ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask); + if (ret) + return ret; + + return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask); +} + +static int cma_modify_qp_err(struct rdma_cm_id *id) +{ + struct ib_qp_attr qp_attr; + + if (!id->qp) + return 0; + + qp_attr.qp_state = IB_QPS_ERR; + return ib_modify_qp(id->qp, &qp_attr, IB_QP_STATE); +} + +int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr, + int *qp_attr_mask) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + switch (id_priv->id.device->node_type) { + case IB_NODE_CA: + ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr, + qp_attr_mask); + if (qp_attr->qp_state == IB_QPS_RTR) + qp_attr->rq_psn = id_priv->seq_num; + break; + default: + ret = -ENOSYS; + break; + } + + return ret; +} +EXPORT_SYMBOL(rdma_init_qp_attr); + +static inline int cma_zero_addr(struct sockaddr *addr) +{ + struct in6_addr *ip6; + + if (addr->sa_family == AF_INET) + return ZERONET(((struct sockaddr_in *) addr)->sin_addr.s_addr); + else { + ip6 = &((struct sockaddr_in6 *) addr)->sin6_addr; + return (ip6->s6_addr32[0] | ip6->s6_addr32[1] | + ip6->s6_addr32[3] | ip6->s6_addr32[4]) == 0; + } +} + +static inline int cma_loopback_addr(struct sockaddr *addr) +{ + return LOOPBACK(((struct sockaddr_in *) addr)->sin_addr.s_addr); +} + +static inline int cma_any_addr(struct sockaddr *addr) +{ + return cma_zero_addr(addr) || cma_loopback_addr(addr); +} + +static inline int cma_any_port(struct sockaddr *addr) +{ + return !((struct sockaddr_in *) addr)->sin_port; +} + +static int cma_get_net_info(void *hdr, enum rdma_port_space ps, + u8 *ip_ver, __u16 *port, + union cma_ip_addr **src, union cma_ip_addr **dst) +{ + switch (ps) { + case RDMA_PS_SDP: + if (sdp_get_majv(((struct sdp_hh *) hdr)->sdp_version) != + SDP_MAJ_VERSION) + return -EINVAL; + + *ip_ver = sdp_get_ip_ver(hdr); + *port = ((struct sdp_hh *) hdr)->port; + *src = &((struct sdp_hh *) hdr)->src_addr; + *dst = &((struct sdp_hh *) hdr)->dst_addr; + break; + default: + if (((struct cma_hdr *) hdr)->cma_version != CMA_VERSION) + return -EINVAL; + + *ip_ver = cma_get_ip_ver(hdr); + *port = ((struct cma_hdr *) hdr)->port; + *src = &((struct cma_hdr *) hdr)->src_addr; + *dst = &((struct cma_hdr *) hdr)->dst_addr; + break; + } + + if (*ip_ver != 4 && *ip_ver != 6) + return -EINVAL; + return 0; +} + +static void cma_save_net_info(struct rdma_addr *addr, + struct rdma_addr *listen_addr, + u8 ip_ver, __u16 port, + union cma_ip_addr *src, union cma_ip_addr *dst) +{ + struct sockaddr_in *listen4, *ip4; + struct sockaddr_in6 *listen6, *ip6; + + switch (ip_ver) { + case 4: + listen4 = (struct sockaddr_in *) &listen_addr->src_addr; + ip4 = (struct sockaddr_in *) &addr->src_addr; + ip4->sin_family = listen4->sin_family; + ip4->sin_addr.s_addr = dst->ip4.addr; + ip4->sin_port = listen4->sin_port; + + ip4 = (struct sockaddr_in *) &addr->dst_addr; + ip4->sin_family = listen4->sin_family; + ip4->sin_addr.s_addr = src->ip4.addr; + ip4->sin_port = port; + break; + case 6: + listen6 = (struct sockaddr_in6 *) &listen_addr->src_addr; + ip6 = (struct sockaddr_in6 *) &addr->src_addr; + ip6->sin6_family = listen6->sin6_family; + ip6->sin6_addr = dst->ip6; + ip6->sin6_port = listen6->sin6_port; + + ip6 = (struct sockaddr_in6 *) &addr->dst_addr; + ip6->sin6_family = listen6->sin6_family; + ip6->sin6_addr = src->ip6; + ip6->sin6_port = port; + break; + default: + break; + } +} + +static inline int cma_user_data_offset(enum rdma_port_space ps) +{ + switch (ps) { + case RDMA_PS_SDP: + return 0; + default: + return sizeof(struct cma_hdr); + } +} + +static int cma_notify_user(struct rdma_id_private *id_priv, + enum rdma_cm_event_type type, int status, + void *data, u8 data_len) +{ + struct rdma_cm_event event; + + event.event = type; + event.status = status; + event.private_data = data; + event.private_data_len = data_len; + + return id_priv->id.event_handler(&id_priv->id, &event); +} + +static void cma_cancel_route(struct rdma_id_private *id_priv) +{ + switch (id_priv->id.device->node_type) { + case IB_NODE_CA: + if (id_priv->query) + ib_sa_cancel_query(id_priv->query_id, id_priv->query); + break; + default: + break; + } +} + +static inline int cma_internal_listen(struct rdma_id_private *id_priv) +{ + return (id_priv->state == CMA_LISTEN) && id_priv->cma_dev && + cma_any_addr(&id_priv->id.route.addr.src_addr); +} + +static void cma_destroy_listen(struct rdma_id_private *id_priv) +{ + cma_exch(id_priv, CMA_DESTROYING); + + if (id_priv->cma_dev) { + switch (id_priv->id.device->node_type) { + case IB_NODE_CA: + if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib)) + ib_destroy_cm_id(id_priv->cm_id.ib); + break; + default: + break; + } + cma_detach_from_dev(id_priv); + } + list_del(&id_priv->listen_list); + + cma_deref_id(id_priv); + wait_for_completion(&id_priv->comp); + + kfree(id_priv); +} + +static void cma_cancel_listens(struct rdma_id_private *id_priv) +{ + struct rdma_id_private *dev_id_priv; + + mutex_lock(&lock); + list_del(&id_priv->list); + + while (!list_empty(&id_priv->listen_list)) { + dev_id_priv = list_entry(id_priv->listen_list.next, + struct rdma_id_private, listen_list); + cma_destroy_listen(dev_id_priv); + } + mutex_unlock(&lock); +} + +static void cma_cancel_operation(struct rdma_id_private *id_priv, + enum cma_state state) +{ + switch (state) { + case CMA_ADDR_QUERY: + rdma_addr_cancel(&id_priv->id.route.addr.dev_addr); + break; + case CMA_ROUTE_QUERY: + cma_cancel_route(id_priv); + break; + case CMA_LISTEN: + if (cma_any_addr(&id_priv->id.route.addr.src_addr) && + !id_priv->cma_dev) + cma_cancel_listens(id_priv); + break; + default: + break; + } +} + +static void cma_release_port(struct rdma_id_private *id_priv) +{ + struct rdma_bind_list *bind_list = id_priv->bind_list; + + if (!bind_list) + return; + + mutex_lock(&lock); + hlist_del(&id_priv->node); + if (hlist_empty(&bind_list->owners)) { + idr_remove(bind_list->ps, bind_list->port); + kfree(bind_list); + } + mutex_unlock(&lock); +} + +void rdma_destroy_id(struct rdma_cm_id *id) +{ + struct rdma_id_private *id_priv; + enum cma_state state; + + id_priv = container_of(id, struct rdma_id_private, id); + state = cma_exch(id_priv, CMA_DESTROYING); + cma_cancel_operation(id_priv, state); + + if (id_priv->cma_dev) { + switch (id->device->node_type) { + case IB_NODE_CA: + if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib)) + ib_destroy_cm_id(id_priv->cm_id.ib); + break; + default: + break; + } + mutex_lock(&lock); + cma_detach_from_dev(id_priv); + mutex_unlock(&lock); + } + + cma_release_port(id_priv); + cma_deref_id(id_priv); + wait_for_completion(&id_priv->comp); + + kfree(id_priv->id.route.path_rec); + kfree(id_priv); +} +EXPORT_SYMBOL(rdma_destroy_id); + +static int cma_rep_recv(struct rdma_id_private *id_priv) +{ + int ret; + + ret = cma_modify_qp_rtr(&id_priv->id); + if (ret) + goto reject; + + ret = cma_modify_qp_rts(&id_priv->id); + if (ret) + goto reject; + + ret = ib_send_cm_rtu(id_priv->cm_id.ib, NULL, 0); + if (ret) + goto reject; + + return 0; +reject: + cma_modify_qp_err(&id_priv->id); + ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED, + NULL, 0, NULL, 0); + return ret; +} + +static int cma_verify_rep(struct rdma_id_private *id_priv, void *data) +{ + if (id_priv->id.ps == RDMA_PS_SDP && + sdp_get_majv(((struct sdp_hah *) data)->sdp_version) != + SDP_MAJ_VERSION) + return -EINVAL; + + return 0; +} + +static int cma_rtu_recv(struct rdma_id_private *id_priv) +{ + int ret; + + ret = cma_modify_qp_rts(&id_priv->id); + if (ret) + goto reject; + + return 0; +reject: + cma_modify_qp_err(&id_priv->id); + ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED, + NULL, 0, NULL, 0); + return ret; +} + +static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) +{ + struct rdma_id_private *id_priv = cm_id->context; + enum rdma_cm_event_type event; + u8 private_data_len = 0; + int ret = 0, status = 0; + + atomic_inc(&id_priv->dev_remove); + if (!cma_comp(id_priv, CMA_CONNECT)) + goto out; + + switch (ib_event->event) { + case IB_CM_REQ_ERROR: + case IB_CM_REP_ERROR: + event = RDMA_CM_EVENT_UNREACHABLE; + status = -ETIMEDOUT; + break; + case IB_CM_REP_RECEIVED: + status = cma_verify_rep(id_priv, ib_event->private_data); + if (status) + event = RDMA_CM_EVENT_CONNECT_ERROR; + else if (id_priv->id.qp && id_priv->id.ps != RDMA_PS_SDP) { + status = cma_rep_recv(id_priv); + event = status ? RDMA_CM_EVENT_CONNECT_ERROR : + RDMA_CM_EVENT_ESTABLISHED; + } else + event = RDMA_CM_EVENT_CONNECT_RESPONSE; + private_data_len = IB_CM_REP_PRIVATE_DATA_SIZE; + break; + case IB_CM_RTU_RECEIVED: + status = cma_rtu_recv(id_priv); + event = status ? RDMA_CM_EVENT_CONNECT_ERROR : + RDMA_CM_EVENT_ESTABLISHED; + break; + case IB_CM_DREQ_ERROR: + status = -ETIMEDOUT; /* fall through */ + case IB_CM_DREQ_RECEIVED: + case IB_CM_DREP_RECEIVED: + if (!cma_comp_exch(id_priv, CMA_CONNECT, CMA_DISCONNECT)) + goto out; + event = RDMA_CM_EVENT_DISCONNECTED; + break; + case IB_CM_TIMEWAIT_EXIT: + case IB_CM_MRA_RECEIVED: + /* ignore event */ + goto out; + case IB_CM_REJ_RECEIVED: + cma_modify_qp_err(&id_priv->id); + status = ib_event->param.rej_rcvd.reason; + event = RDMA_CM_EVENT_REJECTED; + break; + default: + printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d", + ib_event->event); + goto out; + } + + ret = cma_notify_user(id_priv, event, status, ib_event->private_data, + private_data_len); + if (ret) { + /* Destroy the CM ID by returning a non-zero value. */ + id_priv->cm_id.ib = NULL; + cma_exch(id_priv, CMA_DESTROYING); + cma_release_remove(id_priv); + rdma_destroy_id(&id_priv->id); + return ret; + } +out: + cma_release_remove(id_priv); + return ret; +} + +static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id, + struct ib_cm_event *ib_event) +{ + struct rdma_id_private *id_priv; + struct rdma_cm_id *id; + struct rdma_route *rt; + union cma_ip_addr *src, *dst; + __u16 port; + u8 ip_ver; + + id = rdma_create_id(listen_id->event_handler, listen_id->context, + listen_id->ps); + if (IS_ERR(id)) + return NULL; + + rt = &id->route; + rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1; + rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, GFP_KERNEL); + if (!rt->path_rec) + goto err; + + if (cma_get_net_info(ib_event->private_data, listen_id->ps, + &ip_ver, &port, &src, &dst)) + goto err; + + cma_save_net_info(&id->route.addr, &listen_id->route.addr, + ip_ver, port, src, dst); + rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path; + if (rt->num_paths == 2) + rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; + + ib_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); + ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); + ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey)); + rt->addr.dev_addr.dev_type = IB_NODE_CA; + + id_priv = container_of(id, struct rdma_id_private, id); + id_priv->state = CMA_CONNECT; + return id_priv; +err: + rdma_destroy_id(id); + return NULL; +} + +static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) +{ + struct rdma_id_private *listen_id, *conn_id; + int offset, ret; + + listen_id = cm_id->context; + atomic_inc(&listen_id->dev_remove); + if (!cma_comp(listen_id, CMA_LISTEN)) { + ret = -ECONNABORTED; + goto out; + } + + conn_id = cma_new_id(&listen_id->id, ib_event); + if (!conn_id) { + ret = -ENOMEM; + goto out; + } + + atomic_inc(&conn_id->dev_remove); + ret = cma_acquire_ib_dev(conn_id); + if (ret) { + ret = -ENODEV; + cma_release_remove(conn_id); + rdma_destroy_id(&conn_id->id); + goto out; + } + + conn_id->cm_id.ib = cm_id; + cm_id->context = conn_id; + cm_id->cm_handler = cma_ib_handler; + + offset = cma_user_data_offset(listen_id->id.ps); + ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0, + ib_event->private_data + offset, + IB_CM_REQ_PRIVATE_DATA_SIZE - offset); + if (ret) { + /* Destroy the CM ID by returning a non-zero value. */ + conn_id->cm_id.ib = NULL; + cma_exch(conn_id, CMA_DESTROYING); + cma_release_remove(conn_id); + rdma_destroy_id(&conn_id->id); + } +out: + cma_release_remove(listen_id); + return ret; +} + +static __be64 cma_get_service_id(enum rdma_port_space ps, struct sockaddr *addr) +{ + return cpu_to_be64(((u64)ps << 16) + + be16_to_cpu(((struct sockaddr_in *) addr)->sin_port)); +} + +static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr, + struct ib_cm_compare_data *compare) +{ + struct cma_hdr *cma_data, *cma_mask; + struct sdp_hh *sdp_data, *sdp_mask; + __u32 ip4_addr; + struct in6_addr ip6_addr; + + memset(compare, 0, sizeof *compare); + cma_data = (void *) compare->data; + cma_mask = (void *) compare->mask; + sdp_data = (void *) compare->data; + sdp_mask = (void *) compare->mask; + + switch (addr->sa_family) { + case AF_INET: + ip4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; + if (ps == RDMA_PS_SDP) { + sdp_set_ip_ver(sdp_data, 4); + sdp_set_ip_ver(sdp_mask, 0xF); + sdp_data->dst_addr.ip4.addr = ip4_addr; + sdp_mask->dst_addr.ip4.addr = ~0; + } else { + cma_set_ip_ver(cma_data, 4); + cma_set_ip_ver(cma_mask, 0xF); + cma_data->dst_addr.ip4.addr = ip4_addr; + cma_mask->dst_addr.ip4.addr = ~0; + } + break; + case AF_INET6: + ip6_addr = ((struct sockaddr_in6 *) addr)->sin6_addr; + if (ps == RDMA_PS_SDP) { + sdp_set_ip_ver(sdp_data, 6); + sdp_set_ip_ver(sdp_mask, 0xF); + sdp_data->dst_addr.ip6 = ip6_addr; + memset(&sdp_mask->dst_addr.ip6, 0xFF, + sizeof sdp_mask->dst_addr.ip6); + } else { + cma_set_ip_ver(cma_data, 6); + cma_set_ip_ver(cma_mask, 0xF); + cma_data->dst_addr.ip6 = ip6_addr; + memset(&cma_mask->dst_addr.ip6, 0xFF, + sizeof cma_mask->dst_addr.ip6); + } + break; + default: + break; + } +} + +static int cma_ib_listen(struct rdma_id_private *id_priv) +{ + struct ib_cm_compare_data compare_data; + struct sockaddr *addr; + __be64 svc_id; + int ret; + + id_priv->cm_id.ib = ib_create_cm_id(id_priv->id.device, cma_req_handler, + id_priv); + if (IS_ERR(id_priv->cm_id.ib)) + return PTR_ERR(id_priv->cm_id.ib); + + addr = &id_priv->id.route.addr.src_addr; + svc_id = cma_get_service_id(id_priv->id.ps, addr); + if (cma_any_addr(addr)) + ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL); + else { + cma_set_compare_data(id_priv->id.ps, addr, &compare_data); + ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, &compare_data); + } + + if (ret) { + ib_destroy_cm_id(id_priv->cm_id.ib); + id_priv->cm_id.ib = NULL; + } + + return ret; +} + +static int cma_listen_handler(struct rdma_cm_id *id, + struct rdma_cm_event *event) +{ + struct rdma_id_private *id_priv = id->context; + + id->context = id_priv->id.context; + id->event_handler = id_priv->id.event_handler; + return id_priv->id.event_handler(id, event); +} + +static void cma_listen_on_dev(struct rdma_id_private *id_priv, + struct cma_device *cma_dev) +{ + struct rdma_id_private *dev_id_priv; + struct rdma_cm_id *id; + int ret; + + id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps); + if (IS_ERR(id)) + return; + + dev_id_priv = container_of(id, struct rdma_id_private, id); + + dev_id_priv->state = CMA_ADDR_BOUND; + memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr, + ip_addr_size(&id_priv->id.route.addr.src_addr)); + + cma_attach_to_dev(dev_id_priv, cma_dev); + list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list); + + ret = rdma_listen(id, id_priv->backlog); + if (ret) + goto err; + + return; +err: + cma_destroy_listen(dev_id_priv); +} + +static void cma_listen_on_all(struct rdma_id_private *id_priv) +{ + struct cma_device *cma_dev; + + mutex_lock(&lock); + list_add_tail(&id_priv->list, &listen_any_list); + list_for_each_entry(cma_dev, &dev_list, list) + cma_listen_on_dev(id_priv, cma_dev); + mutex_unlock(&lock); +} + +static int cma_bind_any(struct rdma_cm_id *id, sa_family_t af) +{ + struct sockaddr_in addr_in; + + memset(&addr_in, 0, sizeof addr_in); + addr_in.sin_family = af; + return rdma_bind_addr(id, (struct sockaddr *) &addr_in); +} + +int rdma_listen(struct rdma_cm_id *id, int backlog) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (id_priv->state == CMA_IDLE) { + ret = cma_bind_any(id, AF_INET); + if (ret) + return ret; + } + + if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_LISTEN)) + return -EINVAL; + + id_priv->backlog = backlog; + if (id->device) { + switch (id->device->node_type) { + case IB_NODE_CA: + ret = cma_ib_listen(id_priv); + if (ret) + goto err; + break; + default: + ret = -ENOSYS; + goto err; + } + } else + cma_listen_on_all(id_priv); + + return 0; +err: + id_priv->backlog = 0; + cma_comp_exch(id_priv, CMA_LISTEN, CMA_ADDR_BOUND); + return ret; +} +EXPORT_SYMBOL(rdma_listen); + +static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, + void *context) +{ + struct cma_work *work = context; + struct rdma_route *route; + + route = &work->id->id.route; + + if (!status) { + route->num_paths = 1; + *route->path_rec = *path_rec; + } else { + work->old_state = CMA_ROUTE_QUERY; + work->new_state = CMA_ADDR_RESOLVED; + work->event.event = RDMA_CM_EVENT_ROUTE_ERROR; + } + + queue_work(cma_wq, &work->work); +} + +static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, + struct cma_work *work) +{ + struct rdma_dev_addr *addr = &id_priv->id.route.addr.dev_addr; + struct ib_sa_path_rec path_rec; + + memset(&path_rec, 0, sizeof path_rec); + path_rec.sgid = *ib_addr_get_sgid(addr); + path_rec.dgid = *ib_addr_get_dgid(addr); + path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr)); + path_rec.numb_path = 1; + + id_priv->query_id = ib_sa_path_rec_get(id_priv->id.device, + id_priv->id.port_num, &path_rec, + IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | + IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH, + timeout_ms, GFP_KERNEL, + cma_query_handler, work, &id_priv->query); + + return (id_priv->query_id < 0) ? id_priv->query_id : 0; +} + +static void cma_work_handler(void *data) +{ + struct cma_work *work = data; + struct rdma_id_private *id_priv = work->id; + int destroy = 0; + + atomic_inc(&id_priv->dev_remove); + if (!cma_comp_exch(id_priv, work->old_state, work->new_state)) + goto out; + + if (id_priv->id.event_handler(&id_priv->id, &work->event)) { + cma_exch(id_priv, CMA_DESTROYING); + destroy = 1; + } +out: + cma_release_remove(id_priv); + cma_deref_id(id_priv); + if (destroy) + rdma_destroy_id(&id_priv->id); + kfree(work); +} + +static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms) +{ + struct rdma_route *route = &id_priv->id.route; + struct cma_work *work; + int ret; + + work = kzalloc(sizeof *work, GFP_KERNEL); + if (!work) + return -ENOMEM; + + work->id = id_priv; + INIT_WORK(&work->work, cma_work_handler, work); + work->old_state = CMA_ROUTE_QUERY; + work->new_state = CMA_ROUTE_RESOLVED; + work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; + + route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); + if (!route->path_rec) { + ret = -ENOMEM; + goto err1; + } + + ret = cma_query_ib_route(id_priv, timeout_ms, work); + if (ret) + goto err2; + + return 0; +err2: + kfree(route->path_rec); + route->path_rec = NULL; +err1: + kfree(work); + return ret; +} + +int rdma_set_ib_paths(struct rdma_cm_id *id, + struct ib_sa_path_rec *path_rec, int num_paths) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ROUTE_RESOLVED)) + return -EINVAL; + + id->route.path_rec = kmalloc(sizeof *path_rec * num_paths, GFP_KERNEL); + if (!id->route.path_rec) { + ret = -ENOMEM; + goto err; + } + + memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths); + return 0; +err: + cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED); + return ret; +} +EXPORT_SYMBOL(rdma_set_ib_paths); + +int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ROUTE_QUERY)) + return -EINVAL; + + atomic_inc(&id_priv->refcount); + switch (id->device->node_type) { + case IB_NODE_CA: + ret = cma_resolve_ib_route(id_priv, timeout_ms); + break; + default: + ret = -ENOSYS; + break; + } + if (ret) + goto err; + + return 0; +err: + cma_comp_exch(id_priv, CMA_ROUTE_QUERY, CMA_ADDR_RESOLVED); + cma_deref_id(id_priv); + return ret; +} +EXPORT_SYMBOL(rdma_resolve_route); + +static int cma_bind_loopback(struct rdma_id_private *id_priv) +{ + struct cma_device *cma_dev; + struct ib_port_attr port_attr; + union ib_gid *gid; + u16 pkey; + int ret; + u8 p; + + mutex_lock(&lock); + list_for_each_entry(cma_dev, &dev_list, list) + for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p) + if (!ib_query_port (cma_dev->device, p, &port_attr) && + port_attr.state == IB_PORT_ACTIVE) + goto port_found; + + if (!list_empty(&dev_list)) { + p = 1; + cma_dev = list_entry(dev_list.next, struct cma_device, list); + } else { + ret = -ENODEV; + goto out; + } + +port_found: + gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr); + ret = ib_get_cached_gid(cma_dev->device, p, 0, gid); + if (ret) + goto out; + + ret = ib_get_cached_pkey(cma_dev->device, p, 0, &pkey); + if (ret) + goto out; + + ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey); + id_priv->id.port_num = p; + cma_attach_to_dev(id_priv, cma_dev); +out: + mutex_unlock(&lock); + return ret; +} + +static void addr_handler(int status, struct sockaddr *src_addr, + struct rdma_dev_addr *dev_addr, void *context) +{ + struct rdma_id_private *id_priv = context; + enum rdma_cm_event_type event; + + atomic_inc(&id_priv->dev_remove); + if (!id_priv->cma_dev && !status) + status = cma_acquire_dev(id_priv); + + if (status) { + if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_BOUND)) + goto out; + event = RDMA_CM_EVENT_ADDR_ERROR; + } else { + if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED)) + goto out; + memcpy(&id_priv->id.route.addr.src_addr, src_addr, + ip_addr_size(src_addr)); + event = RDMA_CM_EVENT_ADDR_RESOLVED; + } + + if (cma_notify_user(id_priv, event, status, NULL, 0)) { + cma_exch(id_priv, CMA_DESTROYING); + cma_release_remove(id_priv); + cma_deref_id(id_priv); + rdma_destroy_id(&id_priv->id); + return; + } +out: + cma_release_remove(id_priv); + cma_deref_id(id_priv); +} + +static int cma_resolve_loopback(struct rdma_id_private *id_priv) +{ + struct cma_work *work; + struct sockaddr_in *src_in, *dst_in; + int ret; + + work = kzalloc(sizeof *work, GFP_KERNEL); + if (!work) + return -ENOMEM; + + if (!id_priv->cma_dev) { + ret = cma_bind_loopback(id_priv); + if (ret) + goto err; + } + + ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, + ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr)); + + if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) { + src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr; + dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr; + src_in->sin_family = dst_in->sin_family; + src_in->sin_addr.s_addr = dst_in->sin_addr.s_addr; + } + + work->id = id_priv; + INIT_WORK(&work->work, cma_work_handler, work); + work->old_state = CMA_ADDR_QUERY; + work->new_state = CMA_ADDR_RESOLVED; + work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED; + queue_work(cma_wq, &work->work); + return 0; +err: + kfree(work); + return ret; +} + +static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, + struct sockaddr *dst_addr) +{ + if (src_addr && src_addr->sa_family) + return rdma_bind_addr(id, src_addr); + else + return cma_bind_any(id, dst_addr->sa_family); +} + +int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, + struct sockaddr *dst_addr, int timeout_ms) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (id_priv->state == CMA_IDLE) { + ret = cma_bind_addr(id, src_addr, dst_addr); + if (ret) + return ret; + } + + if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_ADDR_QUERY)) + return -EINVAL; + + atomic_inc(&id_priv->refcount); + memcpy(&id->route.addr.dst_addr, dst_addr, ip_addr_size(dst_addr)); + if (cma_any_addr(dst_addr)) + ret = cma_resolve_loopback(id_priv); + else + ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr, + &id->route.addr.dev_addr, + timeout_ms, addr_handler, id_priv); + if (ret) + goto err; + + return 0; +err: + cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_BOUND); + cma_deref_id(id_priv); + return ret; +} +EXPORT_SYMBOL(rdma_resolve_addr); + +static void cma_bind_port(struct rdma_bind_list *bind_list, + struct rdma_id_private *id_priv) +{ + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; + sin->sin_port = htons(bind_list->port); + id_priv->bind_list = bind_list; + hlist_add_head(&id_priv->node, &bind_list->owners); +} + +static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv, + unsigned short snum) +{ + struct rdma_bind_list *bind_list; + int port, start, ret; + + bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL); + if (!bind_list) + return -ENOMEM; + + start = snum ? snum : sysctl_local_port_range[0]; + + do { + ret = idr_get_new_above(ps, bind_list, start, &port); + } while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL)); + + if (ret) + goto err; + + if ((snum && port != snum) || + (!snum && port > sysctl_local_port_range[1])) { + idr_remove(ps, port); + ret = -EADDRNOTAVAIL; + goto err; + } + + bind_list->ps = ps; + bind_list->port = (unsigned short) port; + cma_bind_port(bind_list, id_priv); + return 0; +err: + kfree(bind_list); + return ret; +} + +static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv) +{ + struct rdma_id_private *cur_id; + struct sockaddr_in *sin, *cur_sin; + struct rdma_bind_list *bind_list; + struct hlist_node *node; + unsigned short snum; + + sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; + snum = ntohs(sin->sin_port); + if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) + return -EACCES; + + bind_list = idr_find(ps, snum); + if (!bind_list) + return cma_alloc_port(ps, id_priv, snum); + + /* + * We don't support binding to any address if anyone is bound to + * a specific address on the same port. + */ + if (cma_any_addr(&id_priv->id.route.addr.src_addr)) + return -EADDRNOTAVAIL; + + hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { + if (cma_any_addr(&cur_id->id.route.addr.src_addr)) + return -EADDRNOTAVAIL; + + cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; + if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr) + return -EADDRINUSE; + } + + cma_bind_port(bind_list, id_priv); + return 0; +} + +static int cma_get_port(struct rdma_id_private *id_priv) +{ + struct idr *ps; + int ret; + + switch (id_priv->id.ps) { + case RDMA_PS_SDP: + ps = &sdp_ps; + break; + case RDMA_PS_TCP: + ps = &tcp_ps; + break; + default: + return -EPROTONOSUPPORT; + } + + mutex_lock(&lock); + if (cma_any_port(&id_priv->id.route.addr.src_addr)) + ret = cma_alloc_port(ps, id_priv, 0); + else + ret = cma_use_port(ps, id_priv); + mutex_unlock(&lock); + + return ret; +} + +int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) +{ + struct rdma_id_private *id_priv; + int ret; + + if (addr->sa_family != AF_INET) + return -EAFNOSUPPORT; + + id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp_exch(id_priv, CMA_IDLE, CMA_ADDR_BOUND)) + return -EINVAL; + + if (!cma_any_addr(addr)) { + ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); + if (!ret) + ret = cma_acquire_dev(id_priv); + if (ret) + goto err; + } + + memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); + ret = cma_get_port(id_priv); + if (ret) + goto err; + + return 0; +err: + cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); + return ret; +} +EXPORT_SYMBOL(rdma_bind_addr); + +static int cma_format_hdr(void *hdr, enum rdma_port_space ps, + struct rdma_route *route) +{ + struct sockaddr_in *src4, *dst4; + struct cma_hdr *cma_hdr; + struct sdp_hh *sdp_hdr; + + src4 = (struct sockaddr_in *) &route->addr.src_addr; + dst4 = (struct sockaddr_in *) &route->addr.dst_addr; + + switch (ps) { + case RDMA_PS_SDP: + sdp_hdr = hdr; + if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION) + return -EINVAL; + sdp_set_ip_ver(sdp_hdr, 4); + sdp_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr; + sdp_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr; + sdp_hdr->port = src4->sin_port; + break; + default: + cma_hdr = hdr; + cma_hdr->cma_version = CMA_VERSION; + cma_set_ip_ver(cma_hdr, 4); + cma_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr; + cma_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr; + cma_hdr->port = src4->sin_port; + break; + } + return 0; +} + +static int cma_connect_ib(struct rdma_id_private *id_priv, + struct rdma_conn_param *conn_param) +{ + struct ib_cm_req_param req; + struct rdma_route *route; + void *private_data; + int offset, ret; + + memset(&req, 0, sizeof req); + offset = cma_user_data_offset(id_priv->id.ps); + req.private_data_len = offset + conn_param->private_data_len; + private_data = kzalloc(req.private_data_len, GFP_ATOMIC); + if (!private_data) + return -ENOMEM; + + if (conn_param->private_data && conn_param->private_data_len) + memcpy(private_data + offset, conn_param->private_data, + conn_param->private_data_len); + + id_priv->cm_id.ib = ib_create_cm_id(id_priv->id.device, cma_ib_handler, + id_priv); + if (IS_ERR(id_priv->cm_id.ib)) { + ret = PTR_ERR(id_priv->cm_id.ib); + goto out; + } + + route = &id_priv->id.route; + ret = cma_format_hdr(private_data, id_priv->id.ps, route); + if (ret) + goto out; + req.private_data = private_data; + + req.primary_path = &route->path_rec[0]; + if (route->num_paths == 2) + req.alternate_path = &route->path_rec[1]; + + req.service_id = cma_get_service_id(id_priv->id.ps, + &route->addr.dst_addr); + req.qp_num = id_priv->qp_num; + req.qp_type = id_priv->qp_type; + req.starting_psn = id_priv->seq_num; + req.responder_resources = conn_param->responder_resources; + req.initiator_depth = conn_param->initiator_depth; + req.flow_control = conn_param->flow_control; + req.retry_count = conn_param->retry_count; + req.rnr_retry_count = conn_param->rnr_retry_count; + req.remote_cm_response_timeout = CMA_CM_RESPONSE_TIMEOUT; + req.local_cm_response_timeout = CMA_CM_RESPONSE_TIMEOUT; + req.max_cm_retries = CMA_MAX_CM_RETRIES; + req.srq = id_priv->srq ? 1 : 0; + + ret = ib_send_cm_req(id_priv->cm_id.ib, &req); +out: + kfree(private_data); + return ret; +} + +int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_CONNECT)) + return -EINVAL; + + if (!id->qp) { + id_priv->qp_num = conn_param->qp_num; + id_priv->qp_type = conn_param->qp_type; + id_priv->srq = conn_param->srq; + } + + switch (id->device->node_type) { + case IB_NODE_CA: + ret = cma_connect_ib(id_priv, conn_param); + break; + default: + ret = -ENOSYS; + break; + } + if (ret) + goto err; + + return 0; +err: + cma_comp_exch(id_priv, CMA_CONNECT, CMA_ROUTE_RESOLVED); + return ret; +} +EXPORT_SYMBOL(rdma_connect); + +static int cma_accept_ib(struct rdma_id_private *id_priv, + struct rdma_conn_param *conn_param) +{ + struct ib_cm_rep_param rep; + int ret; + + ret = cma_modify_qp_rtr(&id_priv->id); + if (ret) + return ret; + + memset(&rep, 0, sizeof rep); + rep.qp_num = id_priv->qp_num; + rep.starting_psn = id_priv->seq_num; + rep.private_data = conn_param->private_data; + rep.private_data_len = conn_param->private_data_len; + rep.responder_resources = conn_param->responder_resources; + rep.initiator_depth = conn_param->initiator_depth; + rep.target_ack_delay = CMA_CM_RESPONSE_TIMEOUT; + rep.failover_accepted = 0; + rep.flow_control = conn_param->flow_control; + rep.rnr_retry_count = conn_param->rnr_retry_count; + rep.srq = id_priv->srq ? 1 : 0; + + return ib_send_cm_rep(id_priv->cm_id.ib, &rep); +} + +int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp(id_priv, CMA_CONNECT)) + return -EINVAL; + + if (!id->qp && conn_param) { + id_priv->qp_num = conn_param->qp_num; + id_priv->qp_type = conn_param->qp_type; + id_priv->srq = conn_param->srq; + } + + switch (id->device->node_type) { + case IB_NODE_CA: + if (conn_param) + ret = cma_accept_ib(id_priv, conn_param); + else + ret = cma_rep_recv(id_priv); + break; + default: + ret = -ENOSYS; + break; + } + + if (ret) + goto reject; + + return 0; +reject: + cma_modify_qp_err(id); + rdma_reject(id, NULL, 0); + return ret; +} +EXPORT_SYMBOL(rdma_accept); + +int rdma_reject(struct rdma_cm_id *id, const void *private_data, + u8 private_data_len) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp(id_priv, CMA_CONNECT)) + return -EINVAL; + + switch (id->device->node_type) { + case IB_NODE_CA: + ret = ib_send_cm_rej(id_priv->cm_id.ib, + IB_CM_REJ_CONSUMER_DEFINED, NULL, 0, + private_data, private_data_len); + break; + default: + ret = -ENOSYS; + break; + } + return ret; +} +EXPORT_SYMBOL(rdma_reject); + +int rdma_disconnect(struct rdma_cm_id *id) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp(id_priv, CMA_CONNECT) && + !cma_comp(id_priv, CMA_DISCONNECT)) + return -EINVAL; + + ret = cma_modify_qp_err(id); + if (ret) + goto out; + + switch (id->device->node_type) { + case IB_NODE_CA: + /* Initiate or respond to a disconnect. */ + if (ib_send_cm_dreq(id_priv->cm_id.ib, NULL, 0)) + ib_send_cm_drep(id_priv->cm_id.ib, NULL, 0); + break; + default: + break; + } +out: + return ret; +} +EXPORT_SYMBOL(rdma_disconnect); + +static void cma_add_one(struct ib_device *device) +{ + struct cma_device *cma_dev; + struct rdma_id_private *id_priv; + + cma_dev = kmalloc(sizeof *cma_dev, GFP_KERNEL); + if (!cma_dev) + return; + + cma_dev->device = device; + cma_dev->node_guid = device->node_guid; + if (!cma_dev->node_guid) + goto err; + + init_completion(&cma_dev->comp); + atomic_set(&cma_dev->refcount, 1); + INIT_LIST_HEAD(&cma_dev->id_list); + ib_set_client_data(device, &cma_client, cma_dev); + + mutex_lock(&lock); + list_add_tail(&cma_dev->list, &dev_list); + list_for_each_entry(id_priv, &listen_any_list, list) + cma_listen_on_dev(id_priv, cma_dev); + mutex_unlock(&lock); + return; +err: + kfree(cma_dev); +} + +static int cma_remove_id_dev(struct rdma_id_private *id_priv) +{ + enum cma_state state; + + /* Record that we want to remove the device */ + state = cma_exch(id_priv, CMA_DEVICE_REMOVAL); + if (state == CMA_DESTROYING) + return 0; + + cma_cancel_operation(id_priv, state); + wait_event(id_priv->wait_remove, !atomic_read(&id_priv->dev_remove)); + + /* Check for destruction from another callback. */ + if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL)) + return 0; + + return cma_notify_user(id_priv, RDMA_CM_EVENT_DEVICE_REMOVAL, + 0, NULL, 0); +} + +static void cma_process_remove(struct cma_device *cma_dev) +{ + struct list_head remove_list; + struct rdma_id_private *id_priv; + int ret; + + INIT_LIST_HEAD(&remove_list); + + mutex_lock(&lock); + while (!list_empty(&cma_dev->id_list)) { + id_priv = list_entry(cma_dev->id_list.next, + struct rdma_id_private, list); + + if (cma_internal_listen(id_priv)) { + cma_destroy_listen(id_priv); + continue; + } + + list_del(&id_priv->list); + list_add_tail(&id_priv->list, &remove_list); + atomic_inc(&id_priv->refcount); + mutex_unlock(&lock); + + ret = cma_remove_id_dev(id_priv); + cma_deref_id(id_priv); + if (ret) + rdma_destroy_id(&id_priv->id); + + mutex_lock(&lock); + } + mutex_unlock(&lock); + + cma_deref_dev(cma_dev); + wait_for_completion(&cma_dev->comp); +} + +static void cma_remove_one(struct ib_device *device) +{ + struct cma_device *cma_dev; + + cma_dev = ib_get_client_data(device, &cma_client); + if (!cma_dev) + return; + + mutex_lock(&lock); + list_del(&cma_dev->list); + mutex_unlock(&lock); + + cma_process_remove(cma_dev); + kfree(cma_dev); +} + +static int cma_init(void) +{ + int ret; + + cma_wq = create_singlethread_workqueue("rdma_cm_wq"); + if (!cma_wq) + return -ENOMEM; + + ret = ib_register_client(&cma_client); + if (ret) + goto err; + return 0; + +err: + destroy_workqueue(cma_wq); + return ret; +} + +static void cma_cleanup(void) +{ + ib_unregister_client(&cma_client); + destroy_workqueue(cma_wq); + idr_destroy(&sdp_ps); + idr_destroy(&tcp_ps); +} + +module_init(cma_init); +module_exit(cma_cleanup); diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index 838bf54458d..615fe9cc6c5 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c @@ -54,7 +54,7 @@ enum { /* * If an FMR is not in use, then the list member will point to either * its pool's free_list (if the FMR can be mapped again; that is, - * remap_count < IB_FMR_MAX_REMAPS) or its pool's dirty_list (if the + * remap_count < pool->max_remaps) or its pool's dirty_list (if the * FMR needs to be unmapped before being remapped). In either of * these cases it is a bug if the ref_count is not 0. In other words, * if ref_count is > 0, then the list member must not be linked into @@ -84,6 +84,7 @@ struct ib_fmr_pool { int pool_size; int max_pages; + int max_remaps; int dirty_watermark; int dirty_len; struct list_head free_list; @@ -214,8 +215,10 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, { struct ib_device *device; struct ib_fmr_pool *pool; + struct ib_device_attr *attr; int i; int ret; + int max_remaps; if (!params) return ERR_PTR(-EINVAL); @@ -228,6 +231,26 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, return ERR_PTR(-ENOSYS); } + attr = kmalloc(sizeof *attr, GFP_KERNEL); + if (!attr) { + printk(KERN_WARNING "couldn't allocate device attr struct"); + return ERR_PTR(-ENOMEM); + } + + ret = ib_query_device(device, attr); + if (ret) { + printk(KERN_WARNING "couldn't query device"); + kfree(attr); + return ERR_PTR(ret); + } + + if (!attr->max_map_per_fmr) + max_remaps = IB_FMR_MAX_REMAPS; + else + max_remaps = attr->max_map_per_fmr; + + kfree(attr); + pool = kmalloc(sizeof *pool, GFP_KERNEL); if (!pool) { printk(KERN_WARNING "couldn't allocate pool struct"); @@ -258,6 +281,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, pool->pool_size = 0; pool->max_pages = params->max_pages_per_fmr; + pool->max_remaps = max_remaps; pool->dirty_watermark = params->dirty_watermark; pool->dirty_len = 0; spin_lock_init(&pool->pool_lock); @@ -279,7 +303,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, struct ib_pool_fmr *fmr; struct ib_fmr_attr attr = { .max_pages = params->max_pages_per_fmr, - .max_maps = IB_FMR_MAX_REMAPS, + .max_maps = pool->max_remaps, .page_shift = params->page_shift }; @@ -489,7 +513,7 @@ int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr) --fmr->ref_count; if (!fmr->ref_count) { - if (fmr->remap_count < IB_FMR_MAX_REMAPS) { + if (fmr->remap_count < pool->max_remaps) { list_add_tail(&fmr->list, &pool->free_list); } else { list_add_tail(&fmr->list, &pool->dirty_list); diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 5ad41a64314..b38e02a5db3 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -34,6 +34,7 @@ * $Id: mad.c 5596 2006-03-03 01:00:07Z sean.hefty $ */ #include <linux/dma-mapping.h> +#include <rdma/ib_cache.h> #include "mad_priv.h" #include "mad_rmpp.h" @@ -45,8 +46,7 @@ MODULE_DESCRIPTION("kernel IB MAD API"); MODULE_AUTHOR("Hal Rosenstock"); MODULE_AUTHOR("Sean Hefty"); - -kmem_cache_t *ib_mad_cache; +static kmem_cache_t *ib_mad_cache; static struct list_head ib_mad_port_list; static u32 ib_mad_client_id = 0; @@ -1673,20 +1673,21 @@ static inline int rcv_has_same_class(struct ib_mad_send_wr_private *wr, rwc->recv_buf.mad->mad_hdr.mgmt_class; } -static inline int rcv_has_same_gid(struct ib_mad_send_wr_private *wr, +static inline int rcv_has_same_gid(struct ib_mad_agent_private *mad_agent_priv, + struct ib_mad_send_wr_private *wr, struct ib_mad_recv_wc *rwc ) { struct ib_ah_attr attr; u8 send_resp, rcv_resp; + union ib_gid sgid; + struct ib_device *device = mad_agent_priv->agent.device; + u8 port_num = mad_agent_priv->agent.port_num; + u8 lmc; send_resp = ((struct ib_mad *)(wr->send_buf.mad))-> mad_hdr.method & IB_MGMT_METHOD_RESP; rcv_resp = rwc->recv_buf.mad->mad_hdr.method & IB_MGMT_METHOD_RESP; - if (!send_resp && rcv_resp) - /* is request/response. GID/LIDs are both local (same). */ - return 1; - if (send_resp == rcv_resp) /* both requests, or both responses. GIDs different */ return 0; @@ -1695,48 +1696,78 @@ static inline int rcv_has_same_gid(struct ib_mad_send_wr_private *wr, /* Assume not equal, to avoid false positives. */ return 0; - if (!(attr.ah_flags & IB_AH_GRH) && !(rwc->wc->wc_flags & IB_WC_GRH)) - return attr.dlid == rwc->wc->slid; - else if ((attr.ah_flags & IB_AH_GRH) && - (rwc->wc->wc_flags & IB_WC_GRH)) - return memcmp(attr.grh.dgid.raw, - rwc->recv_buf.grh->sgid.raw, 16) == 0; - else + if (!!(attr.ah_flags & IB_AH_GRH) != + !!(rwc->wc->wc_flags & IB_WC_GRH)) /* one has GID, other does not. Assume different */ return 0; + + if (!send_resp && rcv_resp) { + /* is request/response. */ + if (!(attr.ah_flags & IB_AH_GRH)) { + if (ib_get_cached_lmc(device, port_num, &lmc)) + return 0; + return (!lmc || !((attr.src_path_bits ^ + rwc->wc->dlid_path_bits) & + ((1 << lmc) - 1))); + } else { + if (ib_get_cached_gid(device, port_num, + attr.grh.sgid_index, &sgid)) + return 0; + return !memcmp(sgid.raw, rwc->recv_buf.grh->dgid.raw, + 16); + } + } + + if (!(attr.ah_flags & IB_AH_GRH)) + return attr.dlid == rwc->wc->slid; + else + return !memcmp(attr.grh.dgid.raw, rwc->recv_buf.grh->sgid.raw, + 16); +} + +static inline int is_direct(u8 class) +{ + return (class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE); } + struct ib_mad_send_wr_private* ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, - struct ib_mad_recv_wc *mad_recv_wc) + struct ib_mad_recv_wc *wc) { - struct ib_mad_send_wr_private *mad_send_wr; + struct ib_mad_send_wr_private *wr; struct ib_mad *mad; - mad = (struct ib_mad *)mad_recv_wc->recv_buf.mad; + mad = (struct ib_mad *)wc->recv_buf.mad; - list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list, - agent_list) { - if ((mad_send_wr->tid == mad->mad_hdr.tid) && - rcv_has_same_class(mad_send_wr, mad_recv_wc) && - rcv_has_same_gid(mad_send_wr, mad_recv_wc)) - return mad_send_wr; + list_for_each_entry(wr, &mad_agent_priv->wait_list, agent_list) { + if ((wr->tid == mad->mad_hdr.tid) && + rcv_has_same_class(wr, wc) && + /* + * Don't check GID for direct routed MADs. + * These might have permissive LIDs. + */ + (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || + rcv_has_same_gid(mad_agent_priv, wr, wc))) + return wr; } /* * It's possible to receive the response before we've * been notified that the send has completed */ - list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list, - agent_list) { - if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) && - mad_send_wr->tid == mad->mad_hdr.tid && - mad_send_wr->timeout && - rcv_has_same_class(mad_send_wr, mad_recv_wc) && - rcv_has_same_gid(mad_send_wr, mad_recv_wc)) { + list_for_each_entry(wr, &mad_agent_priv->send_list, agent_list) { + if (is_data_mad(mad_agent_priv, wr->send_buf.mad) && + wr->tid == mad->mad_hdr.tid && + wr->timeout && + rcv_has_same_class(wr, wc) && + /* + * Don't check GID for direct routed MADs. + * These might have permissive LIDs. + */ + (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || + rcv_has_same_gid(mad_agent_priv, wr, wc))) /* Verify request has not been canceled */ - return (mad_send_wr->status == IB_WC_SUCCESS) ? - mad_send_wr : NULL; - } + return (wr->status == IB_WC_SUCCESS) ? wr : NULL; } return NULL; } diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index b4fa28d3160..d147f3bad2c 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h @@ -212,8 +212,6 @@ struct ib_mad_port_private { struct ib_mad_qp_info qp_info[IB_MAD_QPS_CORE]; }; -extern kmem_cache_t *ib_mad_cache; - int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); struct ib_mad_send_wr_private * diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 501cc054cb3..e911c99ff84 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -47,6 +47,7 @@ #include <rdma/ib_pack.h> #include <rdma/ib_sa.h> +#include <rdma/ib_cache.h> MODULE_AUTHOR("Roland Dreier"); MODULE_DESCRIPTION("InfiniBand subnet administration query support"); @@ -441,6 +442,36 @@ void ib_sa_cancel_query(int id, struct ib_sa_query *query) } EXPORT_SYMBOL(ib_sa_cancel_query); +int ib_init_ah_from_path(struct ib_device *device, u8 port_num, + struct ib_sa_path_rec *rec, struct ib_ah_attr *ah_attr) +{ + int ret; + u16 gid_index; + + memset(ah_attr, 0, sizeof *ah_attr); + ah_attr->dlid = be16_to_cpu(rec->dlid); + ah_attr->sl = rec->sl; + ah_attr->src_path_bits = be16_to_cpu(rec->slid) & 0x7f; + ah_attr->port_num = port_num; + + if (rec->hop_limit > 1) { + ah_attr->ah_flags = IB_AH_GRH; + ah_attr->grh.dgid = rec->dgid; + + ret = ib_find_cached_gid(device, &rec->sgid, &port_num, + &gid_index); + if (ret) + return ret; + + ah_attr->grh.sgid_index = gid_index; + ah_attr->grh.flow_label = be32_to_cpu(rec->flow_label); + ah_attr->grh.hop_limit = rec->hop_limit; + ah_attr->grh.traffic_class = rec->traffic_class; + } + return 0; +} +EXPORT_SYMBOL(ib_init_ah_from_path); + static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent) { unsigned long flags; diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 9164a09b6cc..c1c6fda9452 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -30,7 +30,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * $Id: ucm.c 2594 2005-06-13 19:46:02Z libor $ + * $Id: ucm.c 4311 2005-12-05 18:42:01Z sean.hefty $ */ #include <linux/completion.h> @@ -50,6 +50,7 @@ #include <rdma/ib_cm.h> #include <rdma/ib_user_cm.h> +#include <rdma/ib_marshall.h> MODULE_AUTHOR("Libor Michalek"); MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); @@ -63,7 +64,7 @@ struct ib_ucm_device { }; struct ib_ucm_file { - struct semaphore mutex; + struct mutex file_mutex; struct file *filp; struct ib_ucm_device *device; @@ -152,7 +153,7 @@ static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx) { struct ib_ucm_event *uevent; - down(&ctx->file->mutex); + mutex_lock(&ctx->file->file_mutex); list_del(&ctx->file_list); while (!list_empty(&ctx->events)) { @@ -167,7 +168,7 @@ static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx) kfree(uevent); } - up(&ctx->file->mutex); + mutex_unlock(&ctx->file->file_mutex); } static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) @@ -205,36 +206,6 @@ error: return NULL; } -static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath, - struct ib_sa_path_rec *kpath) -{ - if (!kpath || !upath) - return; - - memcpy(upath->dgid, kpath->dgid.raw, sizeof *upath->dgid); - memcpy(upath->sgid, kpath->sgid.raw, sizeof *upath->sgid); - - upath->dlid = kpath->dlid; - upath->slid = kpath->slid; - upath->raw_traffic = kpath->raw_traffic; - upath->flow_label = kpath->flow_label; - upath->hop_limit = kpath->hop_limit; - upath->traffic_class = kpath->traffic_class; - upath->reversible = kpath->reversible; - upath->numb_path = kpath->numb_path; - upath->pkey = kpath->pkey; - upath->sl = kpath->sl; - upath->mtu_selector = kpath->mtu_selector; - upath->mtu = kpath->mtu; - upath->rate_selector = kpath->rate_selector; - upath->rate = kpath->rate; - upath->packet_life_time = kpath->packet_life_time; - upath->preference = kpath->preference; - - upath->packet_life_time_selector = - kpath->packet_life_time_selector; -} - static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, struct ib_cm_req_event_param *kreq) { @@ -253,8 +224,10 @@ static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, ureq->srq = kreq->srq; ureq->port = kreq->port; - ib_ucm_event_path_get(&ureq->primary_path, kreq->primary_path); - ib_ucm_event_path_get(&ureq->alternate_path, kreq->alternate_path); + ib_copy_path_rec_to_user(&ureq->primary_path, kreq->primary_path); + if (kreq->alternate_path) + ib_copy_path_rec_to_user(&ureq->alternate_path, + kreq->alternate_path); } static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep, @@ -324,8 +297,8 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, info = evt->param.rej_rcvd.ari; break; case IB_CM_LAP_RECEIVED: - ib_ucm_event_path_get(&uvt->resp.u.lap_resp.path, - evt->param.lap_rcvd.alternate_path); + ib_copy_path_rec_to_user(&uvt->resp.u.lap_resp.path, + evt->param.lap_rcvd.alternate_path); uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; uvt->resp.present = IB_UCM_PRES_ALTERNATE; break; @@ -402,11 +375,11 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id, if (result) goto err2; - down(&ctx->file->mutex); + mutex_lock(&ctx->file->file_mutex); list_add_tail(&uevent->file_list, &ctx->file->events); list_add_tail(&uevent->ctx_list, &ctx->events); wake_up_interruptible(&ctx->file->poll_wait); - up(&ctx->file->mutex); + mutex_unlock(&ctx->file->file_mutex); return 0; err2: @@ -432,7 +405,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - down(&file->mutex); + mutex_lock(&file->file_mutex); while (list_empty(&file->events)) { if (file->filp->f_flags & O_NONBLOCK) { @@ -447,9 +420,9 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, prepare_to_wait(&file->poll_wait, &wait, TASK_INTERRUPTIBLE); - up(&file->mutex); + mutex_unlock(&file->file_mutex); schedule(); - down(&file->mutex); + mutex_lock(&file->file_mutex); finish_wait(&file->poll_wait, &wait); } @@ -509,7 +482,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, kfree(uevent->info); kfree(uevent); done: - up(&file->mutex); + mutex_unlock(&file->file_mutex); return result; } @@ -528,9 +501,9 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - down(&file->mutex); + mutex_lock(&file->file_mutex); ctx = ib_ucm_ctx_alloc(file); - up(&file->mutex); + mutex_unlock(&file->file_mutex); if (!ctx) return -ENOMEM; @@ -637,65 +610,11 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, return result; } -static void ib_ucm_copy_ah_attr(struct ib_ucm_ah_attr *dest_attr, - struct ib_ah_attr *src_attr) -{ - memcpy(dest_attr->grh_dgid, src_attr->grh.dgid.raw, - sizeof src_attr->grh.dgid); - dest_attr->grh_flow_label = src_attr->grh.flow_label; - dest_attr->grh_sgid_index = src_attr->grh.sgid_index; - dest_attr->grh_hop_limit = src_attr->grh.hop_limit; - dest_attr->grh_traffic_class = src_attr->grh.traffic_class; - - dest_attr->dlid = src_attr->dlid; - dest_attr->sl = src_attr->sl; - dest_attr->src_path_bits = src_attr->src_path_bits; - dest_attr->static_rate = src_attr->static_rate; - dest_attr->is_global = (src_attr->ah_flags & IB_AH_GRH); - dest_attr->port_num = src_attr->port_num; -} - -static void ib_ucm_copy_qp_attr(struct ib_ucm_init_qp_attr_resp *dest_attr, - struct ib_qp_attr *src_attr) -{ - dest_attr->cur_qp_state = src_attr->cur_qp_state; - dest_attr->path_mtu = src_attr->path_mtu; - dest_attr->path_mig_state = src_attr->path_mig_state; - dest_attr->qkey = src_attr->qkey; - dest_attr->rq_psn = src_attr->rq_psn; - dest_attr->sq_psn = src_attr->sq_psn; - dest_attr->dest_qp_num = src_attr->dest_qp_num; - dest_attr->qp_access_flags = src_attr->qp_access_flags; - - dest_attr->max_send_wr = src_attr->cap.max_send_wr; - dest_attr->max_recv_wr = src_attr->cap.max_recv_wr; - dest_attr->max_send_sge = src_attr->cap.max_send_sge; - dest_attr->max_recv_sge = src_attr->cap.max_recv_sge; - dest_attr->max_inline_data = src_attr->cap.max_inline_data; - - ib_ucm_copy_ah_attr(&dest_attr->ah_attr, &src_attr->ah_attr); - ib_ucm_copy_ah_attr(&dest_attr->alt_ah_attr, &src_attr->alt_ah_attr); - - dest_attr->pkey_index = src_attr->pkey_index; - dest_attr->alt_pkey_index = src_attr->alt_pkey_index; - dest_attr->en_sqd_async_notify = src_attr->en_sqd_async_notify; - dest_attr->sq_draining = src_attr->sq_draining; - dest_attr->max_rd_atomic = src_attr->max_rd_atomic; - dest_attr->max_dest_rd_atomic = src_attr->max_dest_rd_atomic; - dest_attr->min_rnr_timer = src_attr->min_rnr_timer; - dest_attr->port_num = src_attr->port_num; - dest_attr->timeout = src_attr->timeout; - dest_attr->retry_cnt = src_attr->retry_cnt; - dest_attr->rnr_retry = src_attr->rnr_retry; - dest_attr->alt_port_num = src_attr->alt_port_num; - dest_attr->alt_timeout = src_attr->alt_timeout; -} - static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, const char __user *inbuf, int in_len, int out_len) { - struct ib_ucm_init_qp_attr_resp resp; + struct ib_uverbs_qp_attr resp; struct ib_ucm_init_qp_attr cmd; struct ib_ucm_context *ctx; struct ib_qp_attr qp_attr; @@ -718,7 +637,7 @@ static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, if (result) goto out; - ib_ucm_copy_qp_attr(&resp, &qp_attr); + ib_copy_qp_attr_to_user(&resp, &qp_attr); if (copy_to_user((void __user *)(unsigned long)cmd.response, &resp, sizeof(resp))) @@ -729,6 +648,17 @@ out: return result; } +static int ucm_validate_listen(__be64 service_id, __be64 service_mask) +{ + service_id &= service_mask; + + if (((service_id & IB_CMA_SERVICE_ID_MASK) == IB_CMA_SERVICE_ID) || + ((service_id & IB_SDP_SERVICE_ID_MASK) == IB_SDP_SERVICE_ID)) + return -EINVAL; + + return 0; +} + static ssize_t ib_ucm_listen(struct ib_ucm_file *file, const char __user *inbuf, int in_len, int out_len) @@ -744,7 +674,13 @@ static ssize_t ib_ucm_listen(struct ib_ucm_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx); - result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask); + result = ucm_validate_listen(cmd.service_id, cmd.service_mask); + if (result) + goto out; + + result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask, + NULL); +out: ib_ucm_ctx_put(ctx); return result; } @@ -793,7 +729,7 @@ static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len) static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) { - struct ib_ucm_path_rec ucm_path; + struct ib_user_path_rec upath; struct ib_sa_path_rec *sa_path; *path = NULL; @@ -805,36 +741,14 @@ static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) if (!sa_path) return -ENOMEM; - if (copy_from_user(&ucm_path, (void __user *)(unsigned long)src, - sizeof(ucm_path))) { + if (copy_from_user(&upath, (void __user *)(unsigned long)src, + sizeof(upath))) { kfree(sa_path); return -EFAULT; } - memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof sa_path->dgid); - memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof sa_path->sgid); - - sa_path->dlid = ucm_path.dlid; - sa_path->slid = ucm_path.slid; - sa_path->raw_traffic = ucm_path.raw_traffic; - sa_path->flow_label = ucm_path.flow_label; - sa_path->hop_limit = ucm_path.hop_limit; - sa_path->traffic_class = ucm_path.traffic_class; - sa_path->reversible = ucm_path.reversible; - sa_path->numb_path = ucm_path.numb_path; - sa_path->pkey = ucm_path.pkey; - sa_path->sl = ucm_path.sl; - sa_path->mtu_selector = ucm_path.mtu_selector; - sa_path->mtu = ucm_path.mtu; - sa_path->rate_selector = ucm_path.rate_selector; - sa_path->rate = ucm_path.rate; - sa_path->packet_life_time = ucm_path.packet_life_time; - sa_path->preference = ucm_path.preference; - - sa_path->packet_life_time_selector = - ucm_path.packet_life_time_selector; - + ib_copy_path_rec_from_user(sa_path, &upath); *path = sa_path; return 0; } @@ -1130,7 +1044,6 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file, param.service_id = cmd.sid; param.timeout_ms = cmd.timeout; param.max_cm_retries = cmd.max_cm_retries; - param.pkey = cmd.pkey; ctx = ib_ucm_ctx_get(file, cmd.id); if (!IS_ERR(ctx)) { @@ -1263,7 +1176,7 @@ static int ib_ucm_open(struct inode *inode, struct file *filp) INIT_LIST_HEAD(&file->ctxs); init_waitqueue_head(&file->poll_wait); - init_MUTEX(&file->mutex); + mutex_init(&file->file_mutex); filp->private_data = file; file->filp = filp; @@ -1277,11 +1190,11 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) struct ib_ucm_file *file = filp->private_data; struct ib_ucm_context *ctx; - down(&file->mutex); + mutex_lock(&file->file_mutex); while (!list_empty(&file->ctxs)) { ctx = list_entry(file->ctxs.next, struct ib_ucm_context, file_list); - up(&file->mutex); + mutex_unlock(&file->file_mutex); mutex_lock(&ctx_id_mutex); idr_remove(&ctx_id_table, ctx->id); @@ -1291,9 +1204,9 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) ib_ucm_cleanup_events(ctx); kfree(ctx); - down(&file->mutex); + mutex_lock(&file->file_mutex); } - up(&file->mutex); + mutex_unlock(&file->file_mutex); kfree(file); return 0; } diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 3372d67ff13..bb9bee56a82 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -132,7 +132,7 @@ struct ib_ucq_object { u32 async_events_reported; }; -extern struct mutex ib_uverbs_idr_mutex; +extern spinlock_t ib_uverbs_idr_lock; extern struct idr ib_uverbs_pd_idr; extern struct idr ib_uverbs_mr_idr; extern struct idr ib_uverbs_mw_idr; @@ -141,6 +141,8 @@ extern struct idr ib_uverbs_cq_idr; extern struct idr ib_uverbs_qp_idr; extern struct idr ib_uverbs_srq_idr; +void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); + struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, int is_async, int *fd); void ib_uverbs_release_event_file(struct kref *ref); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 9f69bd48eb1..76bf61e9b55 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -50,6 +50,196 @@ (udata)->outlen = (olen); \ } while (0) +/* + * The ib_uobject locking scheme is as follows: + * + * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it + * needs to be held during all idr operations. When an object is + * looked up, a reference must be taken on the object's kref before + * dropping this lock. + * + * - Each object also has an rwsem. This rwsem must be held for + * reading while an operation that uses the object is performed. + * For example, while registering an MR, the associated PD's + * uobject.mutex must be held for reading. The rwsem must be held + * for writing while initializing or destroying an object. + * + * - In addition, each object has a "live" flag. If this flag is not + * set, then lookups of the object will fail even if it is found in + * the idr. This handles a reader that blocks and does not acquire + * the rwsem until after the object is destroyed. The destroy + * operation will set the live flag to 0 and then drop the rwsem; + * this will allow the reader to acquire the rwsem, see that the + * live flag is 0, and then drop the rwsem and its reference to + * object. The underlying storage will not be freed until the last + * reference to the object is dropped. + */ + +static void init_uobj(struct ib_uobject *uobj, u64 user_handle, + struct ib_ucontext *context) +{ + uobj->user_handle = user_handle; + uobj->context = context; + kref_init(&uobj->ref); + init_rwsem(&uobj->mutex); + uobj->live = 0; +} + +static void release_uobj(struct kref *kref) +{ + kfree(container_of(kref, struct ib_uobject, ref)); +} + +static void put_uobj(struct ib_uobject *uobj) +{ + kref_put(&uobj->ref, release_uobj); +} + +static void put_uobj_read(struct ib_uobject *uobj) +{ + up_read(&uobj->mutex); + put_uobj(uobj); +} + +static void put_uobj_write(struct ib_uobject *uobj) +{ + up_write(&uobj->mutex); + put_uobj(uobj); +} + +static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj) +{ + int ret; + +retry: + if (!idr_pre_get(idr, GFP_KERNEL)) + return -ENOMEM; + + spin_lock(&ib_uverbs_idr_lock); + ret = idr_get_new(idr, uobj, &uobj->id); + spin_unlock(&ib_uverbs_idr_lock); + + if (ret == -EAGAIN) + goto retry; + + return ret; +} + +void idr_remove_uobj(struct idr *idr, struct ib_uobject *uobj) +{ + spin_lock(&ib_uverbs_idr_lock); + idr_remove(idr, uobj->id); + spin_unlock(&ib_uverbs_idr_lock); +} + +static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id, + struct ib_ucontext *context) +{ + struct ib_uobject *uobj; + + spin_lock(&ib_uverbs_idr_lock); + uobj = idr_find(idr, id); + if (uobj) + kref_get(&uobj->ref); + spin_unlock(&ib_uverbs_idr_lock); + + return uobj; +} + +static struct ib_uobject *idr_read_uobj(struct idr *idr, int id, + struct ib_ucontext *context) +{ + struct ib_uobject *uobj; + + uobj = __idr_get_uobj(idr, id, context); + if (!uobj) + return NULL; + + down_read(&uobj->mutex); + if (!uobj->live) { + put_uobj_read(uobj); + return NULL; + } + + return uobj; +} + +static struct ib_uobject *idr_write_uobj(struct idr *idr, int id, + struct ib_ucontext *context) +{ + struct ib_uobject *uobj; + + uobj = __idr_get_uobj(idr, id, context); + if (!uobj) + return NULL; + + down_write(&uobj->mutex); + if (!uobj->live) { + put_uobj_write(uobj); + return NULL; + } + + return uobj; +} + +static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context) +{ + struct ib_uobject *uobj; + + uobj = idr_read_uobj(idr, id, context); + return uobj ? uobj->object : NULL; +} + +static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context) +{ + return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context); +} + +static void put_pd_read(struct ib_pd *pd) +{ + put_uobj_read(pd->uobject); +} + +static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context) +{ + return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context); +} + +static void put_cq_read(struct ib_cq *cq) +{ + put_uobj_read(cq->uobject); +} + +static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context) +{ + return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context); +} + +static void put_ah_read(struct ib_ah *ah) +{ + put_uobj_read(ah->uobject); +} + +static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context) +{ + return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context); +} + +static void put_qp_read(struct ib_qp *qp) +{ + put_uobj_read(qp->uobject); +} + +static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context) +{ + return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context); +} + +static void put_srq_read(struct ib_srq *srq) +{ + put_uobj_read(srq->uobject); +} + ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) @@ -80,8 +270,10 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, in_len - sizeof cmd, out_len - sizeof resp); ucontext = ibdev->alloc_ucontext(ibdev, &udata); - if (IS_ERR(ucontext)) - return PTR_ERR(file->ucontext); + if (IS_ERR(ucontext)) { + ret = PTR_ERR(file->ucontext); + goto err; + } ucontext->device = ibdev; INIT_LIST_HEAD(&ucontext->pd_list); @@ -278,7 +470,8 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - uobj->context = file->ucontext; + init_uobj(uobj, 0, file->ucontext); + down_write(&uobj->mutex); pd = file->device->ib_dev->alloc_pd(file->device->ib_dev, file->ucontext, &udata); @@ -291,20 +484,10 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, pd->uobject = uobj; atomic_set(&pd->usecnt, 0); - mutex_lock(&ib_uverbs_idr_mutex); - -retry: - if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) { - ret = -ENOMEM; - goto err_up; - } - - ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id); - - if (ret == -EAGAIN) - goto retry; + uobj->object = pd; + ret = idr_add_uobj(&ib_uverbs_pd_idr, uobj); if (ret) - goto err_up; + goto err_idr; memset(&resp, 0, sizeof resp); resp.pd_handle = uobj->id; @@ -312,26 +495,27 @@ retry: if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_idr; + goto err_copy; } mutex_lock(&file->mutex); list_add_tail(&uobj->list, &file->ucontext->pd_list); mutex_unlock(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + uobj->live = 1; + + up_write(&uobj->mutex); return in_len; -err_idr: - idr_remove(&ib_uverbs_pd_idr, uobj->id); +err_copy: + idr_remove_uobj(&ib_uverbs_pd_idr, uobj); -err_up: - mutex_unlock(&ib_uverbs_idr_mutex); +err_idr: ib_dealloc_pd(pd); err: - kfree(uobj); + put_uobj_write(uobj); return ret; } @@ -340,37 +524,34 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, int in_len, int out_len) { struct ib_uverbs_dealloc_pd cmd; - struct ib_pd *pd; struct ib_uobject *uobj; - int ret = -EINVAL; + int ret; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + uobj = idr_write_uobj(&ib_uverbs_pd_idr, cmd.pd_handle, file->ucontext); + if (!uobj) + return -EINVAL; - pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); - if (!pd || pd->uobject->context != file->ucontext) - goto out; + ret = ib_dealloc_pd(uobj->object); + if (!ret) + uobj->live = 0; - uobj = pd->uobject; + put_uobj_write(uobj); - ret = ib_dealloc_pd(pd); if (ret) - goto out; + return ret; - idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); + idr_remove_uobj(&ib_uverbs_pd_idr, uobj); mutex_lock(&file->mutex); list_del(&uobj->list); mutex_unlock(&file->mutex); - kfree(uobj); - -out: - mutex_unlock(&ib_uverbs_idr_mutex); + put_uobj(uobj); - return ret ? ret : in_len; + return in_len; } ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, @@ -410,7 +591,8 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, if (!obj) return -ENOMEM; - obj->uobject.context = file->ucontext; + init_uobj(&obj->uobject, 0, file->ucontext); + down_write(&obj->uobject.mutex); /* * We ask for writable memory if any access flags other than @@ -427,23 +609,14 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, obj->umem.virt_base = cmd.hca_va; - mutex_lock(&ib_uverbs_idr_mutex); - - pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); - if (!pd || pd->uobject->context != file->ucontext) { - ret = -EINVAL; - goto err_up; - } - - if (!pd->device->reg_user_mr) { - ret = -ENOSYS; - goto err_up; - } + pd = idr_read_pd(cmd.pd_handle, file->ucontext); + if (!pd) + goto err_release; mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata); if (IS_ERR(mr)) { ret = PTR_ERR(mr); - goto err_up; + goto err_put; } mr->device = pd->device; @@ -452,53 +625,48 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, atomic_inc(&pd->usecnt); atomic_set(&mr->usecnt, 0); - memset(&resp, 0, sizeof resp); - resp.lkey = mr->lkey; - resp.rkey = mr->rkey; - -retry: - if (!idr_pre_get(&ib_uverbs_mr_idr, GFP_KERNEL)) { - ret = -ENOMEM; - goto err_unreg; - } - - ret = idr_get_new(&ib_uverbs_mr_idr, mr, &obj->uobject.id); - - if (ret == -EAGAIN) - goto retry; + obj->uobject.object = mr; + ret = idr_add_uobj(&ib_uverbs_mr_idr, &obj->uobject); if (ret) goto err_unreg; + memset(&resp, 0, sizeof resp); + resp.lkey = mr->lkey; + resp.rkey = mr->rkey; resp.mr_handle = obj->uobject.id; if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_idr; + goto err_copy; } + put_pd_read(pd); + mutex_lock(&file->mutex); list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); mutex_unlock(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + obj->uobject.live = 1; + + up_write(&obj->uobject.mutex); return in_len; -err_idr: - idr_remove(&ib_uverbs_mr_idr, obj->uobject.id); +err_copy: + idr_remove_uobj(&ib_uverbs_mr_idr, &obj->uobject); err_unreg: ib_dereg_mr(mr); - atomic_dec(&pd->usecnt); -err_up: - mutex_unlock(&ib_uverbs_idr_mutex); +err_put: + put_pd_read(pd); +err_release: ib_umem_release(file->device->ib_dev, &obj->umem); err_free: - kfree(obj); + put_uobj_write(&obj->uobject); return ret; } @@ -508,37 +676,40 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, { struct ib_uverbs_dereg_mr cmd; struct ib_mr *mr; + struct ib_uobject *uobj; struct ib_umem_object *memobj; int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); - - mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle); - if (!mr || mr->uobject->context != file->ucontext) - goto out; + uobj = idr_write_uobj(&ib_uverbs_mr_idr, cmd.mr_handle, file->ucontext); + if (!uobj) + return -EINVAL; - memobj = container_of(mr->uobject, struct ib_umem_object, uobject); + memobj = container_of(uobj, struct ib_umem_object, uobject); + mr = uobj->object; ret = ib_dereg_mr(mr); + if (!ret) + uobj->live = 0; + + put_uobj_write(uobj); + if (ret) - goto out; + return ret; - idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); + idr_remove_uobj(&ib_uverbs_mr_idr, uobj); mutex_lock(&file->mutex); - list_del(&memobj->uobject.list); + list_del(&uobj->list); mutex_unlock(&file->mutex); ib_umem_release(file->device->ib_dev, &memobj->umem); - kfree(memobj); -out: - mutex_unlock(&ib_uverbs_idr_mutex); + put_uobj(uobj); - return ret ? ret : in_len; + return in_len; } ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, @@ -577,7 +748,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, struct ib_uverbs_create_cq cmd; struct ib_uverbs_create_cq_resp resp; struct ib_udata udata; - struct ib_ucq_object *uobj; + struct ib_ucq_object *obj; struct ib_uverbs_event_file *ev_file = NULL; struct ib_cq *cq; int ret; @@ -595,10 +766,13 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, if (cmd.comp_vector >= file->device->num_comp_vectors) return -EINVAL; - uobj = kmalloc(sizeof *uobj, GFP_KERNEL); - if (!uobj) + obj = kmalloc(sizeof *obj, GFP_KERNEL); + if (!obj) return -ENOMEM; + init_uobj(&obj->uobject, cmd.user_handle, file->ucontext); + down_write(&obj->uobject.mutex); + if (cmd.comp_channel >= 0) { ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); if (!ev_file) { @@ -607,72 +781,64 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, } } - uobj->uobject.user_handle = cmd.user_handle; - uobj->uobject.context = file->ucontext; - uobj->uverbs_file = file; - uobj->comp_events_reported = 0; - uobj->async_events_reported = 0; - INIT_LIST_HEAD(&uobj->comp_list); - INIT_LIST_HEAD(&uobj->async_list); + obj->uverbs_file = file; + obj->comp_events_reported = 0; + obj->async_events_reported = 0; + INIT_LIST_HEAD(&obj->comp_list); + INIT_LIST_HEAD(&obj->async_list); cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe, file->ucontext, &udata); if (IS_ERR(cq)) { ret = PTR_ERR(cq); - goto err; + goto err_file; } cq->device = file->device->ib_dev; - cq->uobject = &uobj->uobject; + cq->uobject = &obj->uobject; cq->comp_handler = ib_uverbs_comp_handler; cq->event_handler = ib_uverbs_cq_event_handler; cq->cq_context = ev_file; atomic_set(&cq->usecnt, 0); - mutex_lock(&ib_uverbs_idr_mutex); - -retry: - if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) { - ret = -ENOMEM; - goto err_up; - } - - ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id); - - if (ret == -EAGAIN) - goto retry; + obj->uobject.object = cq; + ret = idr_add_uobj(&ib_uverbs_cq_idr, &obj->uobject); if (ret) - goto err_up; + goto err_free; memset(&resp, 0, sizeof resp); - resp.cq_handle = uobj->uobject.id; + resp.cq_handle = obj->uobject.id; resp.cqe = cq->cqe; if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_idr; + goto err_copy; } mutex_lock(&file->mutex); - list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); + list_add_tail(&obj->uobject.list, &file->ucontext->cq_list); mutex_unlock(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + obj->uobject.live = 1; + + up_write(&obj->uobject.mutex); return in_len; -err_idr: - idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); +err_copy: + idr_remove_uobj(&ib_uverbs_cq_idr, &obj->uobject); + -err_up: - mutex_unlock(&ib_uverbs_idr_mutex); +err_free: ib_destroy_cq(cq); -err: +err_file: if (ev_file) - ib_uverbs_release_ucq(file, ev_file, uobj); - kfree(uobj); + ib_uverbs_release_ucq(file, ev_file, obj); + +err: + put_uobj_write(&obj->uobject); return ret; } @@ -693,11 +859,9 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file, (unsigned long) cmd.response + sizeof resp, in_len - sizeof cmd, out_len - sizeof resp); - mutex_lock(&ib_uverbs_idr_mutex); - - cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); - if (!cq || cq->uobject->context != file->ucontext || !cq->device->resize_cq) - goto out; + cq = idr_read_cq(cmd.cq_handle, file->ucontext); + if (!cq) + return -EINVAL; ret = cq->device->resize_cq(cq, cmd.cqe, &udata); if (ret) @@ -711,7 +875,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + put_cq_read(cq); return ret ? ret : in_len; } @@ -722,6 +886,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, { struct ib_uverbs_poll_cq cmd; struct ib_uverbs_poll_cq_resp *resp; + struct ib_uobject *uobj; struct ib_cq *cq; struct ib_wc *wc; int ret = 0; @@ -742,15 +907,17 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, goto out_wc; } - mutex_lock(&ib_uverbs_idr_mutex); - cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); - if (!cq || cq->uobject->context != file->ucontext) { + uobj = idr_read_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext); + if (!uobj) { ret = -EINVAL; goto out; } + cq = uobj->object; resp->count = ib_poll_cq(cq, cmd.ne, wc); + put_uobj_read(uobj); + for (i = 0; i < resp->count; i++) { resp->wc[i].wr_id = wc[i].wr_id; resp->wc[i].status = wc[i].status; @@ -772,7 +939,6 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); kfree(resp); out_wc: @@ -785,22 +951,23 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, int out_len) { struct ib_uverbs_req_notify_cq cmd; + struct ib_uobject *uobj; struct ib_cq *cq; - int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); - cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); - if (cq && cq->uobject->context == file->ucontext) { - ib_req_notify_cq(cq, cmd.solicited_only ? - IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); - ret = in_len; - } - mutex_unlock(&ib_uverbs_idr_mutex); + uobj = idr_read_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext); + if (!uobj) + return -EINVAL; + cq = uobj->object; - return ret; + ib_req_notify_cq(cq, cmd.solicited_only ? + IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); + + put_uobj_read(uobj); + + return in_len; } ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, @@ -809,52 +976,50 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, { struct ib_uverbs_destroy_cq cmd; struct ib_uverbs_destroy_cq_resp resp; + struct ib_uobject *uobj; struct ib_cq *cq; - struct ib_ucq_object *uobj; + struct ib_ucq_object *obj; struct ib_uverbs_event_file *ev_file; - u64 user_handle; int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - memset(&resp, 0, sizeof resp); - - mutex_lock(&ib_uverbs_idr_mutex); + uobj = idr_write_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext); + if (!uobj) + return -EINVAL; + cq = uobj->object; + ev_file = cq->cq_context; + obj = container_of(cq->uobject, struct ib_ucq_object, uobject); - cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); - if (!cq || cq->uobject->context != file->ucontext) - goto out; + ret = ib_destroy_cq(cq); + if (!ret) + uobj->live = 0; - user_handle = cq->uobject->user_handle; - uobj = container_of(cq->uobject, struct ib_ucq_object, uobject); - ev_file = cq->cq_context; + put_uobj_write(uobj); - ret = ib_destroy_cq(cq); if (ret) - goto out; + return ret; - idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); + idr_remove_uobj(&ib_uverbs_cq_idr, uobj); mutex_lock(&file->mutex); - list_del(&uobj->uobject.list); + list_del(&uobj->list); mutex_unlock(&file->mutex); - ib_uverbs_release_ucq(file, ev_file, uobj); + ib_uverbs_release_ucq(file, ev_file, obj); - resp.comp_events_reported = uobj->comp_events_reported; - resp.async_events_reported = uobj->async_events_reported; + memset(&resp, 0, sizeof resp); + resp.comp_events_reported = obj->comp_events_reported; + resp.async_events_reported = obj->async_events_reported; - kfree(uobj); + put_uobj(uobj); if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) - ret = -EFAULT; - -out: - mutex_unlock(&ib_uverbs_idr_mutex); + return -EFAULT; - return ret ? ret : in_len; + return in_len; } ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, @@ -864,7 +1029,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, struct ib_uverbs_create_qp cmd; struct ib_uverbs_create_qp_resp resp; struct ib_udata udata; - struct ib_uqp_object *uobj; + struct ib_uqp_object *obj; struct ib_pd *pd; struct ib_cq *scq, *rcq; struct ib_srq *srq; @@ -882,23 +1047,21 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, (unsigned long) cmd.response + sizeof resp, in_len - sizeof cmd, out_len - sizeof resp); - uobj = kmalloc(sizeof *uobj, GFP_KERNEL); - if (!uobj) + obj = kmalloc(sizeof *obj, GFP_KERNEL); + if (!obj) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext); + down_write(&obj->uevent.uobject.mutex); - pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); - scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); - rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle); - srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL; + pd = idr_read_pd(cmd.pd_handle, file->ucontext); + scq = idr_read_cq(cmd.send_cq_handle, file->ucontext); + rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext); + srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL; - if (!pd || pd->uobject->context != file->ucontext || - !scq || scq->uobject->context != file->ucontext || - !rcq || rcq->uobject->context != file->ucontext || - (cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) { + if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { ret = -EINVAL; - goto err_up; + goto err_put; } attr.event_handler = ib_uverbs_qp_event_handler; @@ -915,16 +1078,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, attr.cap.max_recv_sge = cmd.max_recv_sge; attr.cap.max_inline_data = cmd.max_inline_data; - uobj->uevent.uobject.user_handle = cmd.user_handle; - uobj->uevent.uobject.context = file->ucontext; - uobj->uevent.events_reported = 0; - INIT_LIST_HEAD(&uobj->uevent.event_list); - INIT_LIST_HEAD(&uobj->mcast_list); + obj->uevent.events_reported = 0; + INIT_LIST_HEAD(&obj->uevent.event_list); + INIT_LIST_HEAD(&obj->mcast_list); qp = pd->device->create_qp(pd, &attr, &udata); if (IS_ERR(qp)) { ret = PTR_ERR(qp); - goto err_up; + goto err_put; } qp->device = pd->device; @@ -932,7 +1093,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, qp->send_cq = attr.send_cq; qp->recv_cq = attr.recv_cq; qp->srq = attr.srq; - qp->uobject = &uobj->uevent.uobject; + qp->uobject = &obj->uevent.uobject; qp->event_handler = attr.event_handler; qp->qp_context = attr.qp_context; qp->qp_type = attr.qp_type; @@ -942,23 +1103,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, if (attr.srq) atomic_inc(&attr.srq->usecnt); - memset(&resp, 0, sizeof resp); - resp.qpn = qp->qp_num; - -retry: - if (!idr_pre_get(&ib_uverbs_qp_idr, GFP_KERNEL)) { - ret = -ENOMEM; - goto err_destroy; - } - - ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->uevent.uobject.id); - - if (ret == -EAGAIN) - goto retry; + obj->uevent.uobject.object = qp; + ret = idr_add_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); if (ret) goto err_destroy; - resp.qp_handle = uobj->uevent.uobject.id; + memset(&resp, 0, sizeof resp); + resp.qpn = qp->qp_num; + resp.qp_handle = obj->uevent.uobject.id; resp.max_recv_sge = attr.cap.max_recv_sge; resp.max_send_sge = attr.cap.max_send_sge; resp.max_recv_wr = attr.cap.max_recv_wr; @@ -968,32 +1120,42 @@ retry: if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_idr; + goto err_copy; } + put_pd_read(pd); + put_cq_read(scq); + put_cq_read(rcq); + if (srq) + put_srq_read(srq); + mutex_lock(&file->mutex); - list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list); + list_add_tail(&obj->uevent.uobject.list, &file->ucontext->qp_list); mutex_unlock(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + obj->uevent.uobject.live = 1; + + up_write(&obj->uevent.uobject.mutex); return in_len; -err_idr: - idr_remove(&ib_uverbs_qp_idr, uobj->uevent.uobject.id); +err_copy: + idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); err_destroy: ib_destroy_qp(qp); - atomic_dec(&pd->usecnt); - atomic_dec(&attr.send_cq->usecnt); - atomic_dec(&attr.recv_cq->usecnt); - if (attr.srq) - atomic_dec(&attr.srq->usecnt); - -err_up: - mutex_unlock(&ib_uverbs_idr_mutex); - kfree(uobj); +err_put: + if (pd) + put_pd_read(pd); + if (scq) + put_cq_read(scq); + if (rcq) + put_cq_read(rcq); + if (srq) + put_srq_read(srq); + + put_uobj_write(&obj->uevent.uobject); return ret; } @@ -1018,15 +1180,15 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file, goto out; } - mutex_lock(&ib_uverbs_idr_mutex); - - qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); - if (qp && qp->uobject->context == file->ucontext) - ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr); - else + qp = idr_read_qp(cmd.qp_handle, file->ucontext); + if (!qp) { ret = -EINVAL; + goto out; + } - mutex_unlock(&ib_uverbs_idr_mutex); + ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr); + + put_qp_read(qp); if (ret) goto out; @@ -1113,10 +1275,8 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, if (!attr) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); - - qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); - if (!qp || qp->uobject->context != file->ucontext) { + qp = idr_read_qp(cmd.qp_handle, file->ucontext); + if (!qp) { ret = -EINVAL; goto out; } @@ -1168,13 +1328,15 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, attr->alt_ah_attr.port_num = cmd.alt_dest.port_num; ret = ib_modify_qp(qp, attr, cmd.attr_mask); + + put_qp_read(qp); + if (ret) goto out; ret = in_len; out: - mutex_unlock(&ib_uverbs_idr_mutex); kfree(attr); return ret; @@ -1186,8 +1348,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, { struct ib_uverbs_destroy_qp cmd; struct ib_uverbs_destroy_qp_resp resp; + struct ib_uobject *uobj; struct ib_qp *qp; - struct ib_uqp_object *uobj; + struct ib_uqp_object *obj; int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) @@ -1195,43 +1358,43 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, memset(&resp, 0, sizeof resp); - mutex_lock(&ib_uverbs_idr_mutex); - - qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); - if (!qp || qp->uobject->context != file->ucontext) - goto out; - - uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); + uobj = idr_write_uobj(&ib_uverbs_qp_idr, cmd.qp_handle, file->ucontext); + if (!uobj) + return -EINVAL; + qp = uobj->object; + obj = container_of(uobj, struct ib_uqp_object, uevent.uobject); - if (!list_empty(&uobj->mcast_list)) { - ret = -EBUSY; - goto out; + if (!list_empty(&obj->mcast_list)) { + put_uobj_write(uobj); + return -EBUSY; } ret = ib_destroy_qp(qp); + if (!ret) + uobj->live = 0; + + put_uobj_write(uobj); + if (ret) - goto out; + return ret; - idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); + idr_remove_uobj(&ib_uverbs_qp_idr, uobj); mutex_lock(&file->mutex); - list_del(&uobj->uevent.uobject.list); + list_del(&uobj->list); mutex_unlock(&file->mutex); - ib_uverbs_release_uevent(file, &uobj->uevent); + ib_uverbs_release_uevent(file, &obj->uevent); - resp.events_reported = uobj->uevent.events_reported; + resp.events_reported = obj->uevent.events_reported; - kfree(uobj); + put_uobj(uobj); if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) - ret = -EFAULT; - -out: - mutex_unlock(&ib_uverbs_idr_mutex); + return -EFAULT; - return ret ? ret : in_len; + return in_len; } ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, @@ -1244,6 +1407,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, struct ib_send_wr *wr = NULL, *last, *next, *bad_wr; struct ib_qp *qp; int i, sg_ind; + int is_ud; ssize_t ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) @@ -1260,12 +1424,11 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, if (!user_wr) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); - - qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); - if (!qp || qp->uobject->context != file->ucontext) + qp = idr_read_qp(cmd.qp_handle, file->ucontext); + if (!qp) goto out; + is_ud = qp->qp_type == IB_QPT_UD; sg_ind = 0; last = NULL; for (i = 0; i < cmd.wr_count; ++i) { @@ -1273,12 +1436,12 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, buf + sizeof cmd + i * cmd.wqe_size, cmd.wqe_size)) { ret = -EFAULT; - goto out; + goto out_put; } if (user_wr->num_sge + sg_ind > cmd.sge_count) { ret = -EINVAL; - goto out; + goto out_put; } next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) + @@ -1286,7 +1449,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, GFP_KERNEL); if (!next) { ret = -ENOMEM; - goto out; + goto out_put; } if (!last) @@ -1302,12 +1465,12 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, next->send_flags = user_wr->send_flags; next->imm_data = (__be32 __force) user_wr->imm_data; - if (qp->qp_type == IB_QPT_UD) { - next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, - user_wr->wr.ud.ah); + if (is_ud) { + next->wr.ud.ah = idr_read_ah(user_wr->wr.ud.ah, + file->ucontext); if (!next->wr.ud.ah) { ret = -EINVAL; - goto out; + goto out_put; } next->wr.ud.remote_qpn = user_wr->wr.ud.remote_qpn; next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey; @@ -1344,7 +1507,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, sg_ind * sizeof (struct ib_sge), next->num_sge * sizeof (struct ib_sge))) { ret = -EFAULT; - goto out; + goto out_put; } sg_ind += next->num_sge; } else @@ -1364,10 +1527,13 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, &resp, sizeof resp)) ret = -EFAULT; -out: - mutex_unlock(&ib_uverbs_idr_mutex); +out_put: + put_qp_read(qp); +out: while (wr) { + if (is_ud && wr->wr.ud.ah) + put_ah_read(wr->wr.ud.ah); next = wr->next; kfree(wr); wr = next; @@ -1482,14 +1648,15 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, if (IS_ERR(wr)) return PTR_ERR(wr); - mutex_lock(&ib_uverbs_idr_mutex); - - qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); - if (!qp || qp->uobject->context != file->ucontext) + qp = idr_read_qp(cmd.qp_handle, file->ucontext); + if (!qp) goto out; resp.bad_wr = 0; ret = qp->device->post_recv(qp, wr, &bad_wr); + + put_qp_read(qp); + if (ret) for (next = wr; next; next = next->next) { ++resp.bad_wr; @@ -1503,8 +1670,6 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); - while (wr) { next = wr->next; kfree(wr); @@ -1533,14 +1698,15 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, if (IS_ERR(wr)) return PTR_ERR(wr); - mutex_lock(&ib_uverbs_idr_mutex); - - srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); - if (!srq || srq->uobject->context != file->ucontext) + srq = idr_read_srq(cmd.srq_handle, file->ucontext); + if (!srq) goto out; resp.bad_wr = 0; ret = srq->device->post_srq_recv(srq, wr, &bad_wr); + + put_srq_read(srq); + if (ret) for (next = wr; next; next = next->next) { ++resp.bad_wr; @@ -1554,8 +1720,6 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); - while (wr) { next = wr->next; kfree(wr); @@ -1587,17 +1751,15 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + init_uobj(uobj, cmd.user_handle, file->ucontext); + down_write(&uobj->mutex); - pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); - if (!pd || pd->uobject->context != file->ucontext) { + pd = idr_read_pd(cmd.pd_handle, file->ucontext); + if (!pd) { ret = -EINVAL; - goto err_up; + goto err; } - uobj->user_handle = cmd.user_handle; - uobj->context = file->ucontext; - attr.dlid = cmd.attr.dlid; attr.sl = cmd.attr.sl; attr.src_path_bits = cmd.attr.src_path_bits; @@ -1613,21 +1775,13 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, ah = ib_create_ah(pd, &attr); if (IS_ERR(ah)) { ret = PTR_ERR(ah); - goto err_up; - } - - ah->uobject = uobj; - -retry: - if (!idr_pre_get(&ib_uverbs_ah_idr, GFP_KERNEL)) { - ret = -ENOMEM; - goto err_destroy; + goto err; } - ret = idr_get_new(&ib_uverbs_ah_idr, ah, &uobj->id); + ah->uobject = uobj; + uobj->object = ah; - if (ret == -EAGAIN) - goto retry; + ret = idr_add_uobj(&ib_uverbs_ah_idr, uobj); if (ret) goto err_destroy; @@ -1636,27 +1790,29 @@ retry: if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_idr; + goto err_copy; } + put_pd_read(pd); + mutex_lock(&file->mutex); list_add_tail(&uobj->list, &file->ucontext->ah_list); mutex_unlock(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + uobj->live = 1; + + up_write(&uobj->mutex); return in_len; -err_idr: - idr_remove(&ib_uverbs_ah_idr, uobj->id); +err_copy: + idr_remove_uobj(&ib_uverbs_ah_idr, uobj); err_destroy: ib_destroy_ah(ah); -err_up: - mutex_unlock(&ib_uverbs_idr_mutex); - - kfree(uobj); +err: + put_uobj_write(uobj); return ret; } @@ -1666,35 +1822,34 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, struct ib_uverbs_destroy_ah cmd; struct ib_ah *ah; struct ib_uobject *uobj; - int ret = -EINVAL; + int ret; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + uobj = idr_write_uobj(&ib_uverbs_ah_idr, cmd.ah_handle, file->ucontext); + if (!uobj) + return -EINVAL; + ah = uobj->object; - ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle); - if (!ah || ah->uobject->context != file->ucontext) - goto out; + ret = ib_destroy_ah(ah); + if (!ret) + uobj->live = 0; - uobj = ah->uobject; + put_uobj_write(uobj); - ret = ib_destroy_ah(ah); if (ret) - goto out; + return ret; - idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle); + idr_remove_uobj(&ib_uverbs_ah_idr, uobj); mutex_lock(&file->mutex); list_del(&uobj->list); mutex_unlock(&file->mutex); - kfree(uobj); + put_uobj(uobj); -out: - mutex_unlock(&ib_uverbs_idr_mutex); - - return ret ? ret : in_len; + return in_len; } ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, @@ -1703,47 +1858,43 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, { struct ib_uverbs_attach_mcast cmd; struct ib_qp *qp; - struct ib_uqp_object *uobj; + struct ib_uqp_object *obj; struct ib_uverbs_mcast_entry *mcast; - int ret = -EINVAL; + int ret; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); - - qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); - if (!qp || qp->uobject->context != file->ucontext) - goto out; + qp = idr_read_qp(cmd.qp_handle, file->ucontext); + if (!qp) + return -EINVAL; - uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); + obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); - list_for_each_entry(mcast, &uobj->mcast_list, list) + list_for_each_entry(mcast, &obj->mcast_list, list) if (cmd.mlid == mcast->lid && !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { ret = 0; - goto out; + goto out_put; } mcast = kmalloc(sizeof *mcast, GFP_KERNEL); if (!mcast) { ret = -ENOMEM; - goto out; + goto out_put; } mcast->lid = cmd.mlid; memcpy(mcast->gid.raw, cmd.gid, sizeof mcast->gid.raw); ret = ib_attach_mcast(qp, &mcast->gid, cmd.mlid); - if (!ret) { - uobj = container_of(qp->uobject, struct ib_uqp_object, - uevent.uobject); - list_add_tail(&mcast->list, &uobj->mcast_list); - } else + if (!ret) + list_add_tail(&mcast->list, &obj->mcast_list); + else kfree(mcast); -out: - mutex_unlock(&ib_uverbs_idr_mutex); +out_put: + put_qp_read(qp); return ret ? ret : in_len; } @@ -1753,7 +1904,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, int out_len) { struct ib_uverbs_detach_mcast cmd; - struct ib_uqp_object *uobj; + struct ib_uqp_object *obj; struct ib_qp *qp; struct ib_uverbs_mcast_entry *mcast; int ret = -EINVAL; @@ -1761,19 +1912,17 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); - - qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); - if (!qp || qp->uobject->context != file->ucontext) - goto out; + qp = idr_read_qp(cmd.qp_handle, file->ucontext); + if (!qp) + return -EINVAL; ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid); if (ret) - goto out; + goto out_put; - uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); + obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); - list_for_each_entry(mcast, &uobj->mcast_list, list) + list_for_each_entry(mcast, &obj->mcast_list, list) if (cmd.mlid == mcast->lid && !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { list_del(&mcast->list); @@ -1781,8 +1930,8 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, break; } -out: - mutex_unlock(&ib_uverbs_idr_mutex); +out_put: + put_qp_read(qp); return ret ? ret : in_len; } @@ -1794,7 +1943,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, struct ib_uverbs_create_srq cmd; struct ib_uverbs_create_srq_resp resp; struct ib_udata udata; - struct ib_uevent_object *uobj; + struct ib_uevent_object *obj; struct ib_pd *pd; struct ib_srq *srq; struct ib_srq_init_attr attr; @@ -1810,17 +1959,17 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, (unsigned long) cmd.response + sizeof resp, in_len - sizeof cmd, out_len - sizeof resp); - uobj = kmalloc(sizeof *uobj, GFP_KERNEL); - if (!uobj) + obj = kmalloc(sizeof *obj, GFP_KERNEL); + if (!obj) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + init_uobj(&obj->uobject, 0, file->ucontext); + down_write(&obj->uobject.mutex); - pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); - - if (!pd || pd->uobject->context != file->ucontext) { + pd = idr_read_pd(cmd.pd_handle, file->ucontext); + if (!pd) { ret = -EINVAL; - goto err_up; + goto err; } attr.event_handler = ib_uverbs_srq_event_handler; @@ -1829,69 +1978,59 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, attr.attr.max_sge = cmd.max_sge; attr.attr.srq_limit = cmd.srq_limit; - uobj->uobject.user_handle = cmd.user_handle; - uobj->uobject.context = file->ucontext; - uobj->events_reported = 0; - INIT_LIST_HEAD(&uobj->event_list); + obj->events_reported = 0; + INIT_LIST_HEAD(&obj->event_list); srq = pd->device->create_srq(pd, &attr, &udata); if (IS_ERR(srq)) { ret = PTR_ERR(srq); - goto err_up; + goto err; } srq->device = pd->device; srq->pd = pd; - srq->uobject = &uobj->uobject; + srq->uobject = &obj->uobject; srq->event_handler = attr.event_handler; srq->srq_context = attr.srq_context; atomic_inc(&pd->usecnt); atomic_set(&srq->usecnt, 0); - memset(&resp, 0, sizeof resp); - -retry: - if (!idr_pre_get(&ib_uverbs_srq_idr, GFP_KERNEL)) { - ret = -ENOMEM; - goto err_destroy; - } - - ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->uobject.id); - - if (ret == -EAGAIN) - goto retry; + obj->uobject.object = srq; + ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uobject); if (ret) goto err_destroy; - resp.srq_handle = uobj->uobject.id; + memset(&resp, 0, sizeof resp); + resp.srq_handle = obj->uobject.id; resp.max_wr = attr.attr.max_wr; resp.max_sge = attr.attr.max_sge; if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) { ret = -EFAULT; - goto err_idr; + goto err_copy; } + put_pd_read(pd); + mutex_lock(&file->mutex); - list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); + list_add_tail(&obj->uobject.list, &file->ucontext->srq_list); mutex_unlock(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + obj->uobject.live = 1; + + up_write(&obj->uobject.mutex); return in_len; -err_idr: - idr_remove(&ib_uverbs_srq_idr, uobj->uobject.id); +err_copy: + idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uobject); err_destroy: ib_destroy_srq(srq); - atomic_dec(&pd->usecnt); - -err_up: - mutex_unlock(&ib_uverbs_idr_mutex); - kfree(uobj); +err: + put_uobj_write(&obj->uobject); return ret; } @@ -1907,21 +2046,16 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); - - srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); - if (!srq || srq->uobject->context != file->ucontext) { - ret = -EINVAL; - goto out; - } + srq = idr_read_srq(cmd.srq_handle, file->ucontext); + if (!srq) + return -EINVAL; attr.max_wr = cmd.max_wr; attr.srq_limit = cmd.srq_limit; ret = ib_modify_srq(srq, &attr, cmd.attr_mask); -out: - mutex_unlock(&ib_uverbs_idr_mutex); + put_srq_read(srq); return ret ? ret : in_len; } @@ -1942,18 +2076,16 @@ ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + srq = idr_read_srq(cmd.srq_handle, file->ucontext); + if (!srq) + return -EINVAL; - srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); - if (srq && srq->uobject->context == file->ucontext) - ret = ib_query_srq(srq, &attr); - else - ret = -EINVAL; + ret = ib_query_srq(srq, &attr); - mutex_unlock(&ib_uverbs_idr_mutex); + put_srq_read(srq); if (ret) - goto out; + return ret; memset(&resp, 0, sizeof resp); @@ -1963,10 +2095,9 @@ ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file, if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) - ret = -EFAULT; + return -EFAULT; -out: - return ret ? ret : in_len; + return in_len; } ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, @@ -1975,45 +2106,45 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, { struct ib_uverbs_destroy_srq cmd; struct ib_uverbs_destroy_srq_resp resp; + struct ib_uobject *uobj; struct ib_srq *srq; - struct ib_uevent_object *uobj; + struct ib_uevent_object *obj; int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); - - memset(&resp, 0, sizeof resp); + uobj = idr_write_uobj(&ib_uverbs_srq_idr, cmd.srq_handle, file->ucontext); + if (!uobj) + return -EINVAL; + srq = uobj->object; + obj = container_of(uobj, struct ib_uevent_object, uobject); - srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); - if (!srq || srq->uobject->context != file->ucontext) - goto out; + ret = ib_destroy_srq(srq); + if (!ret) + uobj->live = 0; - uobj = container_of(srq->uobject, struct ib_uevent_object, uobject); + put_uobj_write(uobj); - ret = ib_destroy_srq(srq); if (ret) - goto out; + return ret; - idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); + idr_remove_uobj(&ib_uverbs_srq_idr, uobj); mutex_lock(&file->mutex); - list_del(&uobj->uobject.list); + list_del(&uobj->list); mutex_unlock(&file->mutex); - ib_uverbs_release_uevent(file, uobj); + ib_uverbs_release_uevent(file, obj); - resp.events_reported = uobj->events_reported; + memset(&resp, 0, sizeof resp); + resp.events_reported = obj->events_reported; - kfree(uobj); + put_uobj(uobj); if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) ret = -EFAULT; -out: - mutex_unlock(&ib_uverbs_idr_mutex); - return ret ? ret : in_len; } diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index ff092a0a94d..5ec2d49e9bb 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -66,7 +66,7 @@ enum { static struct class *uverbs_class; -DEFINE_MUTEX(ib_uverbs_idr_mutex); +DEFINE_SPINLOCK(ib_uverbs_idr_lock); DEFINE_IDR(ib_uverbs_pd_idr); DEFINE_IDR(ib_uverbs_mr_idr); DEFINE_IDR(ib_uverbs_mw_idr); @@ -183,21 +183,21 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, if (!context) return 0; - mutex_lock(&ib_uverbs_idr_mutex); - list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { - struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id); - idr_remove(&ib_uverbs_ah_idr, uobj->id); + struct ib_ah *ah = uobj->object; + + idr_remove_uobj(&ib_uverbs_ah_idr, uobj); ib_destroy_ah(ah); list_del(&uobj->list); kfree(uobj); } list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { - struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id); + struct ib_qp *qp = uobj->object; struct ib_uqp_object *uqp = container_of(uobj, struct ib_uqp_object, uevent.uobject); - idr_remove(&ib_uverbs_qp_idr, uobj->id); + + idr_remove_uobj(&ib_uverbs_qp_idr, uobj); ib_uverbs_detach_umcast(qp, uqp); ib_destroy_qp(qp); list_del(&uobj->list); @@ -206,11 +206,12 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, } list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) { - struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id); + struct ib_cq *cq = uobj->object; struct ib_uverbs_event_file *ev_file = cq->cq_context; struct ib_ucq_object *ucq = container_of(uobj, struct ib_ucq_object, uobject); - idr_remove(&ib_uverbs_cq_idr, uobj->id); + + idr_remove_uobj(&ib_uverbs_cq_idr, uobj); ib_destroy_cq(cq); list_del(&uobj->list); ib_uverbs_release_ucq(file, ev_file, ucq); @@ -218,10 +219,11 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, } list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { - struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id); + struct ib_srq *srq = uobj->object; struct ib_uevent_object *uevent = container_of(uobj, struct ib_uevent_object, uobject); - idr_remove(&ib_uverbs_srq_idr, uobj->id); + + idr_remove_uobj(&ib_uverbs_srq_idr, uobj); ib_destroy_srq(srq); list_del(&uobj->list); ib_uverbs_release_uevent(file, uevent); @@ -231,11 +233,11 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, /* XXX Free MWs */ list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { - struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id); + struct ib_mr *mr = uobj->object; struct ib_device *mrdev = mr->device; struct ib_umem_object *memobj; - idr_remove(&ib_uverbs_mr_idr, uobj->id); + idr_remove_uobj(&ib_uverbs_mr_idr, uobj); ib_dereg_mr(mr); memobj = container_of(uobj, struct ib_umem_object, uobject); @@ -246,15 +248,14 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, } list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) { - struct ib_pd *pd = idr_find(&ib_uverbs_pd_idr, uobj->id); - idr_remove(&ib_uverbs_pd_idr, uobj->id); + struct ib_pd *pd = uobj->object; + + idr_remove_uobj(&ib_uverbs_pd_idr, uobj); ib_dealloc_pd(pd); list_del(&uobj->list); kfree(uobj); } - mutex_unlock(&ib_uverbs_idr_mutex); - return context->device->dealloc_ucontext(context); } diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c new file mode 100644 index 00000000000..ce46b13ae02 --- /dev/null +++ b/drivers/infiniband/core/uverbs_marshall.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2005 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <rdma/ib_marshall.h> + +static void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst, + struct ib_ah_attr *src) +{ + memcpy(dst->grh.dgid, src->grh.dgid.raw, sizeof src->grh.dgid); + dst->grh.flow_label = src->grh.flow_label; + dst->grh.sgid_index = src->grh.sgid_index; + dst->grh.hop_limit = src->grh.hop_limit; + dst->grh.traffic_class = src->grh.traffic_class; + dst->dlid = src->dlid; + dst->sl = src->sl; + dst->src_path_bits = src->src_path_bits; + dst->static_rate = src->static_rate; + dst->is_global = src->ah_flags & IB_AH_GRH ? 1 : 0; + dst->port_num = src->port_num; +} + +void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst, + struct ib_qp_attr *src) +{ + dst->cur_qp_state = src->cur_qp_state; + dst->path_mtu = src->path_mtu; + dst->path_mig_state = src->path_mig_state; + dst->qkey = src->qkey; + dst->rq_psn = src->rq_psn; + dst->sq_psn = src->sq_psn; + dst->dest_qp_num = src->dest_qp_num; + dst->qp_access_flags = src->qp_access_flags; + + dst->max_send_wr = src->cap.max_send_wr; + dst->max_recv_wr = src->cap.max_recv_wr; + dst->max_send_sge = src->cap.max_send_sge; + dst->max_recv_sge = src->cap.max_recv_sge; + dst->max_inline_data = src->cap.max_inline_data; + + ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr); + ib_copy_ah_attr_to_user(&dst->alt_ah_attr, &src->alt_ah_attr); + + dst->pkey_index = src->pkey_index; + dst->alt_pkey_index = src->alt_pkey_index; + dst->en_sqd_async_notify = src->en_sqd_async_notify; + dst->sq_draining = src->sq_draining; + dst->max_rd_atomic = src->max_rd_atomic; + dst->max_dest_rd_atomic = src->max_dest_rd_atomic; + dst->min_rnr_timer = src->min_rnr_timer; + dst->port_num = src->port_num; + dst->timeout = src->timeout; + dst->retry_cnt = src->retry_cnt; + dst->rnr_retry = src->rnr_retry; + dst->alt_port_num = src->alt_port_num; + dst->alt_timeout = src->alt_timeout; +} +EXPORT_SYMBOL(ib_copy_qp_attr_to_user); + +void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, + struct ib_sa_path_rec *src) +{ + memcpy(dst->dgid, src->dgid.raw, sizeof src->dgid); + memcpy(dst->sgid, src->sgid.raw, sizeof src->sgid); + + dst->dlid = src->dlid; + dst->slid = src->slid; + dst->raw_traffic = src->raw_traffic; + dst->flow_label = src->flow_label; + dst->hop_limit = src->hop_limit; + dst->traffic_class = src->traffic_class; + dst->reversible = src->reversible; + dst->numb_path = src->numb_path; + dst->pkey = src->pkey; + dst->sl = src->sl; + dst->mtu_selector = src->mtu_selector; + dst->mtu = src->mtu; + dst->rate_selector = src->rate_selector; + dst->rate = src->rate; + dst->packet_life_time = src->packet_life_time; + dst->preference = src->preference; + dst->packet_life_time_selector = src->packet_life_time_selector; +} +EXPORT_SYMBOL(ib_copy_path_rec_to_user); + +void ib_copy_path_rec_from_user(struct ib_sa_path_rec *dst, + struct ib_user_path_rec *src) +{ + memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid); + memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid); + + dst->dlid = src->dlid; + dst->slid = src->slid; + dst->raw_traffic = src->raw_traffic; + dst->flow_label = src->flow_label; + dst->hop_limit = src->hop_limit; + dst->traffic_class = src->traffic_class; + dst->reversible = src->reversible; + dst->numb_path = src->numb_path; + dst->pkey = src->pkey; + dst->sl = src->sl; + dst->mtu_selector = src->mtu_selector; + dst->mtu = src->mtu; + dst->rate_selector = src->rate_selector; + dst->rate = src->rate; + dst->packet_life_time = src->packet_life_time; + dst->preference = src->preference; + dst->packet_life_time_selector = src->packet_life_time_selector; +} +EXPORT_SYMBOL(ib_copy_path_rec_from_user); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index b78e7dc6933..468999c3880 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -125,35 +125,47 @@ struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) } EXPORT_SYMBOL(ib_create_ah); -struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, - struct ib_grh *grh, u8 port_num) +int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc, + struct ib_grh *grh, struct ib_ah_attr *ah_attr) { - struct ib_ah_attr ah_attr; u32 flow_class; u16 gid_index; int ret; - memset(&ah_attr, 0, sizeof ah_attr); - ah_attr.dlid = wc->slid; - ah_attr.sl = wc->sl; - ah_attr.src_path_bits = wc->dlid_path_bits; - ah_attr.port_num = port_num; + memset(ah_attr, 0, sizeof *ah_attr); + ah_attr->dlid = wc->slid; + ah_attr->sl = wc->sl; + ah_attr->src_path_bits = wc->dlid_path_bits; + ah_attr->port_num = port_num; if (wc->wc_flags & IB_WC_GRH) { - ah_attr.ah_flags = IB_AH_GRH; - ah_attr.grh.dgid = grh->sgid; + ah_attr->ah_flags = IB_AH_GRH; + ah_attr->grh.dgid = grh->sgid; - ret = ib_find_cached_gid(pd->device, &grh->dgid, &port_num, + ret = ib_find_cached_gid(device, &grh->dgid, &port_num, &gid_index); if (ret) - return ERR_PTR(ret); + return ret; - ah_attr.grh.sgid_index = (u8) gid_index; + ah_attr->grh.sgid_index = (u8) gid_index; flow_class = be32_to_cpu(grh->version_tclass_flow); - ah_attr.grh.flow_label = flow_class & 0xFFFFF; - ah_attr.grh.traffic_class = (flow_class >> 20) & 0xFF; - ah_attr.grh.hop_limit = grh->hop_limit; + ah_attr->grh.flow_label = flow_class & 0xFFFFF; + ah_attr->grh.hop_limit = grh->hop_limit; + ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF; } + return 0; +} +EXPORT_SYMBOL(ib_init_ah_from_wc); + +struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, + struct ib_grh *grh, u8 port_num) +{ + struct ib_ah_attr ah_attr; + int ret; + + ret = ib_init_ah_from_wc(pd->device, port_num, wc, grh, &ah_attr); + if (ret) + return ERR_PTR(ret); return ib_create_ah(pd, &ah_attr); } diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index f7f8391fe43..1a9d0a2c33c 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c @@ -137,47 +137,11 @@ static int recv_subn_get_guidinfo(struct ib_smp *smp, return reply(smp); } -struct port_info { - __be64 mkey; - __be64 gid_prefix; - __be16 lid; - __be16 sm_lid; - __be32 cap_mask; - __be16 diag_code; - __be16 mkey_lease_period; - u8 local_port_num; - u8 link_width_enabled; - u8 link_width_supported; - u8 link_width_active; - u8 linkspeed_portstate; /* 4 bits, 4 bits */ - u8 portphysstate_linkdown; /* 4 bits, 4 bits */ - u8 mkeyprot_resv_lmc; /* 2 bits, 3, 3 */ - u8 linkspeedactive_enabled; /* 4 bits, 4 bits */ - u8 neighbormtu_mastersmsl; /* 4 bits, 4 bits */ - u8 vlcap_inittype; /* 4 bits, 4 bits */ - u8 vl_high_limit; - u8 vl_arb_high_cap; - u8 vl_arb_low_cap; - u8 inittypereply_mtucap; /* 4 bits, 4 bits */ - u8 vlstallcnt_hoqlife; /* 3 bits, 5 bits */ - u8 operationalvl_pei_peo_fpi_fpo; /* 4 bits, 1, 1, 1, 1 */ - __be16 mkey_violations; - __be16 pkey_violations; - __be16 qkey_violations; - u8 guid_cap; - u8 clientrereg_resv_subnetto; /* 1 bit, 2 bits, 5 */ - u8 resv_resptimevalue; /* 3 bits, 5 bits */ - u8 localphyerrors_overrunerrors; /* 4 bits, 4 bits */ - __be16 max_credit_hint; - u8 resv; - u8 link_roundtrip_latency[3]; -} __attribute__ ((packed)); - static int recv_subn_get_portinfo(struct ib_smp *smp, struct ib_device *ibdev, u8 port) { struct ipath_ibdev *dev; - struct port_info *pip = (struct port_info *)smp->data; + struct ib_port_info *pip = (struct ib_port_info *)smp->data; u16 lid; u8 ibcstat; u8 mtu; @@ -312,7 +276,7 @@ static int recv_subn_set_guidinfo(struct ib_smp *smp, static int recv_subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, u8 port) { - struct port_info *pip = (struct port_info *)smp->data; + struct ib_port_info *pip = (struct ib_port_info *)smp->data; struct ib_event event; struct ipath_ibdev *dev; u32 flags; @@ -445,7 +409,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, if (pip->clientrereg_resv_subnetto & 0x80) { clientrereg = 1; - event.event = IB_EVENT_LID_CHANGE; + event.event = IB_EVENT_CLIENT_REREGISTER; ib_dispatch_event(&event); } diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 798e13e14fa..d0f7731802c 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -174,7 +174,6 @@ enum { struct mthca_cmd_context { struct completion done; - struct timer_list timer; int result; int next; u64 out_param; @@ -362,15 +361,6 @@ void mthca_cmd_event(struct mthca_dev *dev, complete(&context->done); } -static void event_timeout(unsigned long context_ptr) -{ - struct mthca_cmd_context *context = - (struct mthca_cmd_context *) context_ptr; - - context->result = -EBUSY; - complete(&context->done); -} - static int mthca_cmd_wait(struct mthca_dev *dev, u64 in_param, u64 *out_param, @@ -401,11 +391,10 @@ static int mthca_cmd_wait(struct mthca_dev *dev, if (err) goto out; - context->timer.expires = jiffies + timeout; - add_timer(&context->timer); - - wait_for_completion(&context->done); - del_timer_sync(&context->timer); + if (!wait_for_completion_timeout(&context->done, timeout)) { + err = -EBUSY; + goto out; + } err = context->result; if (err) @@ -535,10 +524,6 @@ int mthca_cmd_use_events(struct mthca_dev *dev) for (i = 0; i < dev->cmd.max_cmds; ++i) { dev->cmd.context[i].token = i; dev->cmd.context[i].next = i + 1; - init_timer(&dev->cmd.context[i].timer); - dev->cmd.context[i].timer.data = - (unsigned long) &dev->cmd.context[i]; - dev->cmd.context[i].timer.function = event_timeout; } dev->cmd.context[dev->cmd.max_cmds - 1].next = -1; diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 205854e9c66..3e27a084257 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c @@ -540,8 +540,17 @@ static inline int mthca_poll_one(struct mthca_dev *dev, entry->wr_id = srq->wrid[wqe_index]; mthca_free_srq_wqe(srq, wqe); } else { + s32 wqe; wq = &(*cur_qp)->rq; - wqe_index = be32_to_cpu(cqe->wqe) >> wq->wqe_shift; + wqe = be32_to_cpu(cqe->wqe); + wqe_index = wqe >> wq->wqe_shift; + /* + * WQE addr == base - 1 might be reported in receive completion + * with error instead of (rq size - 1) by Sinai FW 1.0.800 and + * Arbel FW 5.1.400. This bug should be fixed in later FW revs. + */ + if (unlikely(wqe_index < 0)) + wqe_index = wq->max - 1; entry->wr_id = (*cur_qp)->wrid[wqe_index]; } @@ -813,6 +822,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, spin_lock_init(&cq->lock); cq->refcount = 1; init_waitqueue_head(&cq->wait); + mutex_init(&cq->mutex); memset(cq_context, 0, sizeof *cq_context); cq_context->flags = cpu_to_be32(MTHCA_CQ_STATUS_OK | diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 99f109c3815..d536217e700 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -695,10 +695,6 @@ static void mthca_unmap_reg(struct mthca_dev *dev, unsigned long offset, static int __devinit mthca_map_eq_regs(struct mthca_dev *dev) { - unsigned long mthca_base; - - mthca_base = pci_resource_start(dev->pdev, 0); - if (mthca_is_memfree(dev)) { /* * We assume that the EQ arm and EQ set CI registers diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index 4730863ece9..d9bc030bccc 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c @@ -114,14 +114,22 @@ static void smp_snoop(struct ib_device *ibdev, mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) && mad->mad_hdr.method == IB_MGMT_METHOD_SET) { if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) { + struct ib_port_info *pinfo = + (struct ib_port_info *) ((struct ib_smp *) mad)->data; + mthca_update_rate(to_mdev(ibdev), port_num); update_sm_ah(to_mdev(ibdev), port_num, - be16_to_cpup((__be16 *) (mad->data + 58)), - (*(u8 *) (mad->data + 76)) & 0xf); + be16_to_cpu(pinfo->lid), + pinfo->neighbormtu_mastersmsl & 0xf); event.device = ibdev; - event.event = IB_EVENT_LID_CHANGE; event.element.port_num = port_num; + + if(pinfo->clientrereg_resv_subnetto & 0x80) + event.event = IB_EVENT_CLIENT_REREGISTER; + else + event.event = IB_EVENT_LID_CHANGE; + ib_dispatch_event(&event); } diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index a2eae8a3016..230ae21db8f 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -115,6 +115,16 @@ static int mthca_query_device(struct ib_device *ibdev, props->max_mcast_qp_attach = MTHCA_QP_PER_MGM; props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * props->max_mcast_grp; + /* + * If Sinai memory key optimization is being used, then only + * the 8-bit key portion will change. For other HCAs, the + * unused index bits will also be used for FMR remapping. + */ + if (mdev->mthca_flags & MTHCA_FLAG_SINAI_OPT) + props->max_map_per_fmr = 255; + else + props->max_map_per_fmr = + (1 << (32 - long_log2(mdev->limits.num_mpts))) - 1; err = 0; out: @@ -783,18 +793,24 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda if (entries < 1 || entries > dev->limits.max_cqes) return -EINVAL; + mutex_lock(&cq->mutex); + entries = roundup_pow_of_two(entries + 1); - if (entries == ibcq->cqe + 1) - return 0; + if (entries == ibcq->cqe + 1) { + ret = 0; + goto out; + } if (cq->is_kernel) { ret = mthca_alloc_resize_buf(dev, cq, entries); if (ret) - return ret; + goto out; lkey = cq->resize_buf->buf.mr.ibmr.lkey; } else { - if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) - return -EFAULT; + if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) { + ret = -EFAULT; + goto out; + } lkey = ucmd.lkey; } @@ -811,7 +827,7 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda cq->resize_buf = NULL; spin_unlock_irq(&cq->lock); } - return ret; + goto out; } if (cq->is_kernel) { @@ -838,7 +854,10 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda } else ibcq->cqe = entries - 1; - return 0; +out: + mutex_unlock(&cq->mutex); + + return ret; } static int mthca_destroy_cq(struct ib_cq *cq) diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h index 179a8f610d0..8de2887ba15 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/drivers/infiniband/hw/mthca/mthca_provider.h @@ -214,6 +214,7 @@ struct mthca_cq { int arm_sn; wait_queue_head_t wait; + struct mutex mutex; }; struct mthca_srq { @@ -237,6 +238,7 @@ struct mthca_srq { struct mthca_mr mr; wait_queue_head_t wait; + struct mutex mutex; }; struct mthca_wq { @@ -278,6 +280,7 @@ struct mthca_qp { union mthca_buf queue; wait_queue_head_t wait; + struct mutex mutex; }; struct mthca_sqp { diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 07c13be07a4..16c387d8170 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -534,7 +534,9 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) struct mthca_qp_context *qp_context; u32 sqd_event = 0; u8 status; - int err; + int err = -EINVAL; + + mutex_lock(&qp->mutex); if (attr_mask & IB_QP_CUR_STATE) { cur_state = attr->cur_qp_state; @@ -553,39 +555,41 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) "%d->%d with attr 0x%08x\n", qp->transport, cur_state, new_state, attr_mask); - return -EINVAL; + goto out; } if ((attr_mask & IB_QP_PKEY_INDEX) && attr->pkey_index >= dev->limits.pkey_table_len) { mthca_dbg(dev, "P_Key index (%u) too large. max is %d\n", attr->pkey_index, dev->limits.pkey_table_len-1); - return -EINVAL; + goto out; } if ((attr_mask & IB_QP_PORT) && (attr->port_num == 0 || attr->port_num > dev->limits.num_ports)) { mthca_dbg(dev, "Port number (%u) is invalid\n", attr->port_num); - return -EINVAL; + goto out; } if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic > dev->limits.max_qp_init_rdma) { mthca_dbg(dev, "Max rdma_atomic as initiator %u too large (max is %d)\n", attr->max_rd_atomic, dev->limits.max_qp_init_rdma); - return -EINVAL; + goto out; } if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic > 1 << dev->qp_table.rdb_shift) { mthca_dbg(dev, "Max rdma_atomic as responder %u too large (max %d)\n", attr->max_dest_rd_atomic, 1 << dev->qp_table.rdb_shift); - return -EINVAL; + goto out; } mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); - if (IS_ERR(mailbox)) - return PTR_ERR(mailbox); + if (IS_ERR(mailbox)) { + err = PTR_ERR(mailbox); + goto out; + } qp_param = mailbox->buf; qp_context = &qp_param->context; memset(qp_param, 0, sizeof *qp_param); @@ -618,7 +622,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_2048) { mthca_dbg(dev, "path MTU (%u) is invalid\n", attr->path_mtu); - return -EINVAL; + goto out_mailbox; } qp_context->mtu_msgmax = (attr->path_mtu << 5) | 31; } @@ -672,7 +676,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) if (attr_mask & IB_QP_AV) { if (mthca_path_set(dev, &attr->ah_attr, &qp_context->pri_path, attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) - return -EINVAL; + goto out_mailbox; qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); } @@ -686,18 +690,18 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) if (attr->alt_pkey_index >= dev->limits.pkey_table_len) { mthca_dbg(dev, "Alternate P_Key index (%u) too large. max is %d\n", attr->alt_pkey_index, dev->limits.pkey_table_len-1); - return -EINVAL; + goto out_mailbox; } if (attr->alt_port_num == 0 || attr->alt_port_num > dev->limits.num_ports) { mthca_dbg(dev, "Alternate port number (%u) is invalid\n", attr->alt_port_num); - return -EINVAL; + goto out_mailbox; } if (mthca_path_set(dev, &attr->alt_ah_attr, &qp_context->alt_path, attr->alt_ah_attr.port_num)) - return -EINVAL; + goto out_mailbox; qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index | attr->alt_port_num << 24); @@ -793,12 +797,12 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) err = mthca_MODIFY_QP(dev, cur_state, new_state, qp->qpn, 0, mailbox, sqd_event, &status); if (err) - goto out; + goto out_mailbox; if (status) { mthca_warn(dev, "modify QP %d->%d returned status %02x.\n", cur_state, new_state, status); err = -EINVAL; - goto out; + goto out_mailbox; } qp->state = new_state; @@ -853,8 +857,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) } } -out: +out_mailbox: mthca_free_mailbox(dev, mailbox); + +out: + mutex_unlock(&qp->mutex); return err; } @@ -1100,6 +1107,7 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, qp->refcount = 1; init_waitqueue_head(&qp->wait); + mutex_init(&qp->mutex); qp->state = IB_QPS_RESET; qp->atomic_rd_en = 0; qp->resp_depth = 0; diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c index df5e494a9d3..f4fddd5327f 100644 --- a/drivers/infiniband/hw/mthca/mthca_reset.c +++ b/drivers/infiniband/hw/mthca/mthca_reset.c @@ -49,6 +49,12 @@ int mthca_reset(struct mthca_dev *mdev) u32 *hca_header = NULL; u32 *bridge_header = NULL; struct pci_dev *bridge = NULL; + int bridge_pcix_cap = 0; + int hca_pcie_cap = 0; + int hca_pcix_cap = 0; + + u16 devctl; + u16 linkctl; #define MTHCA_RESET_OFFSET 0xf0010 #define MTHCA_RESET_VALUE swab32(1) @@ -110,6 +116,9 @@ int mthca_reset(struct mthca_dev *mdev) } } + hca_pcix_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX); + hca_pcie_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP); + if (bridge) { bridge_header = kmalloc(256, GFP_KERNEL); if (!bridge_header) { @@ -129,6 +138,13 @@ int mthca_reset(struct mthca_dev *mdev) goto out; } } + bridge_pcix_cap = pci_find_capability(bridge, PCI_CAP_ID_PCIX); + if (!bridge_pcix_cap) { + err = -ENODEV; + mthca_err(mdev, "Couldn't locate HCA bridge " + "PCI-X capability, aborting.\n"); + goto out; + } } /* actually hit reset */ @@ -178,6 +194,20 @@ int mthca_reset(struct mthca_dev *mdev) good: /* Now restore the PCI headers */ if (bridge) { + if (pci_write_config_dword(bridge, bridge_pcix_cap + 0x8, + bridge_header[(bridge_pcix_cap + 0x8) / 4])) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA bridge Upstream " + "split transaction control, aborting.\n"); + goto out; + } + if (pci_write_config_dword(bridge, bridge_pcix_cap + 0xc, + bridge_header[(bridge_pcix_cap + 0xc) / 4])) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA bridge Downstream " + "split transaction control, aborting.\n"); + goto out; + } /* * Bridge control register is at 0x3e, so we'll * naturally restore it last in this loop. @@ -203,6 +233,35 @@ good: } } + if (hca_pcix_cap) { + if (pci_write_config_dword(mdev->pdev, hca_pcix_cap, + hca_header[hca_pcix_cap / 4])) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA PCI-X " + "command register, aborting.\n"); + goto out; + } + } + + if (hca_pcie_cap) { + devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4]; + if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_DEVCTL, + devctl)) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA PCI Express " + "Device Control register, aborting.\n"); + goto out; + } + linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4]; + if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_LNKCTL, + linkctl)) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA PCI Express " + "Link control register, aborting.\n"); + goto out; + } + } + for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index b292fefa3b4..fab417c5cf4 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c @@ -243,6 +243,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, spin_lock_init(&srq->lock); srq->refcount = 1; init_waitqueue_head(&srq->wait); + mutex_init(&srq->mutex); if (mthca_is_memfree(dev)) mthca_arbel_init_srq_context(dev, pd, srq, mailbox->buf); @@ -371,7 +372,11 @@ int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, if (attr_mask & IB_SRQ_LIMIT) { if (attr->srq_limit > srq->max) return -EINVAL; + + mutex_lock(&srq->mutex); ret = mthca_ARM_SRQ(dev, srq->srqn, attr->srq_limit, &status); + mutex_unlock(&srq->mutex); + if (ret) return ret; if (status) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 12a1e0572ef..491d2afaf5b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -272,8 +272,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); void ipoib_dev_cleanup(struct net_device *dev); void ipoib_mcast_join_task(void *dev_ptr); -void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, - struct sk_buff *skb); +void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb); void ipoib_mcast_restart_task(void *dev_ptr); int ipoib_mcast_start_thread(struct net_device *dev); @@ -369,15 +368,26 @@ extern int ipoib_debug_level; #endif /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */ -#define IPOIB_GID_FMT "%x:%x:%x:%x:%x:%x:%x:%x" - -#define IPOIB_GID_ARG(gid) be16_to_cpup((__be16 *) ((gid).raw + 0)), \ - be16_to_cpup((__be16 *) ((gid).raw + 2)), \ - be16_to_cpup((__be16 *) ((gid).raw + 4)), \ - be16_to_cpup((__be16 *) ((gid).raw + 6)), \ - be16_to_cpup((__be16 *) ((gid).raw + 8)), \ - be16_to_cpup((__be16 *) ((gid).raw + 10)), \ - be16_to_cpup((__be16 *) ((gid).raw + 12)), \ - be16_to_cpup((__be16 *) ((gid).raw + 14)) +#define IPOIB_GID_FMT "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:" \ + "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x" + +#define IPOIB_GID_RAW_ARG(gid) ((u8 *)(gid))[0], \ + ((u8 *)(gid))[1], \ + ((u8 *)(gid))[2], \ + ((u8 *)(gid))[3], \ + ((u8 *)(gid))[4], \ + ((u8 *)(gid))[5], \ + ((u8 *)(gid))[6], \ + ((u8 *)(gid))[7], \ + ((u8 *)(gid))[8], \ + ((u8 *)(gid))[9], \ + ((u8 *)(gid))[10],\ + ((u8 *)(gid))[11],\ + ((u8 *)(gid))[12],\ + ((u8 *)(gid))[13],\ + ((u8 *)(gid))[14],\ + ((u8 *)(gid))[15] + +#define IPOIB_GID_ARG(gid) IPOIB_GID_RAW_ARG((gid).raw) #endif /* _IPOIB_H */ diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 8406839b91c..5033666b148 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -84,15 +84,9 @@ void ipoib_free_ah(struct kref *kref) unsigned long flags; - if ((int) priv->tx_tail - (int) ah->last_send >= 0) { - ipoib_dbg(priv, "Freeing ah %p\n", ah->ah); - ib_destroy_ah(ah->ah); - kfree(ah); - } else { - spin_lock_irqsave(&priv->lock, flags); - list_add_tail(&ah->list, &priv->dead_ahs); - spin_unlock_irqrestore(&priv->lock, flags); - } + spin_lock_irqsave(&priv->lock, flags); + list_add_tail(&ah->list, &priv->dead_ahs); + spin_unlock_irqrestore(&priv->lock, flags); } static int ipoib_ib_post_receive(struct net_device *dev, int id) @@ -377,19 +371,16 @@ static void __ipoib_reap_ah(struct net_device *dev) struct ipoib_ah *ah, *tah; LIST_HEAD(remove_list); - spin_lock_irq(&priv->lock); + spin_lock_irq(&priv->tx_lock); + spin_lock(&priv->lock); list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list) if ((int) priv->tx_tail - (int) ah->last_send >= 0) { list_del(&ah->list); - list_add_tail(&ah->list, &remove_list); + ib_destroy_ah(ah->ah); + kfree(ah); } - spin_unlock_irq(&priv->lock); - - list_for_each_entry_safe(ah, tah, &remove_list, list) { - ipoib_dbg(priv, "Reaping ah %p\n", ah->ah); - ib_destroy_ah(ah->ah); - kfree(ah); - } + spin_unlock(&priv->lock); + spin_unlock_irq(&priv->tx_lock); } void ipoib_reap_ah(void *dev_ptr) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index cb078a7d0bf..1c6ea1c682a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -185,8 +185,7 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu) return 0; } -static struct ipoib_path *__path_find(struct net_device *dev, - union ib_gid *gid) +static struct ipoib_path *__path_find(struct net_device *dev, void *gid) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct rb_node *n = priv->path_tree.rb_node; @@ -196,7 +195,7 @@ static struct ipoib_path *__path_find(struct net_device *dev, while (n) { path = rb_entry(n, struct ipoib_path, rb_node); - ret = memcmp(gid->raw, path->pathrec.dgid.raw, + ret = memcmp(gid, path->pathrec.dgid.raw, sizeof (union ib_gid)); if (ret < 0) @@ -424,8 +423,7 @@ static void path_rec_completion(int status, } } -static struct ipoib_path *path_rec_create(struct net_device *dev, - union ib_gid *gid) +static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_path *path; @@ -440,7 +438,7 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, INIT_LIST_HEAD(&path->neigh_list); - memcpy(path->pathrec.dgid.raw, gid->raw, sizeof (union ib_gid)); + memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid)); path->pathrec.sgid = priv->local_gid; path->pathrec.pkey = cpu_to_be16(priv->pkey); path->pathrec.numb_path = 1; @@ -498,10 +496,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) */ spin_lock(&priv->lock); - path = __path_find(dev, (union ib_gid *) (skb->dst->neighbour->ha + 4)); + path = __path_find(dev, skb->dst->neighbour->ha + 4); if (!path) { - path = path_rec_create(dev, - (union ib_gid *) (skb->dst->neighbour->ha + 4)); + path = path_rec_create(dev, skb->dst->neighbour->ha + 4); if (!path) goto err_path; @@ -551,7 +548,7 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) /* Add in the P_Key for multicasts */ skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff; skb->dst->neighbour->ha[9] = priv->pkey & 0xff; - ipoib_mcast_send(dev, (union ib_gid *) (skb->dst->neighbour->ha + 4), skb); + ipoib_mcast_send(dev, skb->dst->neighbour->ha + 4, skb); } static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, @@ -566,10 +563,9 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, */ spin_lock(&priv->lock); - path = __path_find(dev, (union ib_gid *) (phdr->hwaddr + 4)); + path = __path_find(dev, phdr->hwaddr + 4); if (!path) { - path = path_rec_create(dev, - (union ib_gid *) (phdr->hwaddr + 4)); + path = path_rec_create(dev, phdr->hwaddr + 4); if (path) { /* put pseudoheader back on for next time */ skb_push(skb, sizeof *phdr); @@ -660,7 +656,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff; phdr->hwaddr[9] = priv->pkey & 0xff; - ipoib_mcast_send(dev, (union ib_gid *) (phdr->hwaddr + 4), skb); + ipoib_mcast_send(dev, phdr->hwaddr + 4, skb); } else { /* unicast GID -- should be ARP or RARP reply */ @@ -671,7 +667,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->dst ? "neigh" : "dst", be16_to_cpup((__be16 *) skb->data), be32_to_cpup((__be32 *) phdr->hwaddr), - IPOIB_GID_ARG(*(union ib_gid *) (phdr->hwaddr + 4))); + IPOIB_GID_RAW_ARG(phdr->hwaddr + 4)); dev_kfree_skb_any(skb); ++priv->stats.tx_dropped; goto out; @@ -754,7 +750,7 @@ static void ipoib_neigh_destructor(struct neighbour *n) ipoib_dbg(priv, "neigh_destructor for %06x " IPOIB_GID_FMT "\n", be32_to_cpup((__be32 *) n->ha), - IPOIB_GID_ARG(*((union ib_gid *) (n->ha + 4)))); + IPOIB_GID_RAW_ARG(n->ha + 4)); spin_lock_irqsave(&priv->lock, flags); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 1dae4b23825..216471fa01c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -154,7 +154,7 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev, return mcast; } -static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, union ib_gid *mgid) +static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, void *mgid) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct rb_node *n = priv->multicast_tree.rb_node; @@ -165,7 +165,7 @@ static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, union ib_g mcast = rb_entry(n, struct ipoib_mcast, rb_node); - ret = memcmp(mgid->raw, mcast->mcmember.mgid.raw, + ret = memcmp(mgid, mcast->mcmember.mgid.raw, sizeof (union ib_gid)); if (ret < 0) n = n->rb_left; @@ -694,8 +694,7 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) return 0; } -void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, - struct sk_buff *skb) +void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_mcast *mcast; @@ -718,7 +717,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, if (!mcast) { /* Let's create a new send only group now */ ipoib_dbg_mcast(priv, "setting up send only multicast group for " - IPOIB_GID_FMT "\n", IPOIB_GID_ARG(*mgid)); + IPOIB_GID_FMT "\n", IPOIB_GID_RAW_ARG(mgid)); mcast = ipoib_mcast_alloc(dev, 0); if (!mcast) { @@ -730,7 +729,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, } set_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags); - mcast->mcmember.mgid = *mgid; + memcpy(mcast->mcmember.mgid.raw, mgid, sizeof (union ib_gid)); __ipoib_mcast_add(dev, mcast); list_add_tail(&mcast->list, &priv->multicast_list); } @@ -821,7 +820,8 @@ void ipoib_mcast_restart_task(void *dev_ptr) ipoib_mcast_stop_thread(dev, 0); - spin_lock_irqsave(&dev->xmit_lock, flags); + local_irq_save(flags); + netif_tx_lock(dev); spin_lock(&priv->lock); /* @@ -896,7 +896,8 @@ void ipoib_mcast_restart_task(void *dev_ptr) } spin_unlock(&priv->lock); - spin_unlock_irqrestore(&dev->xmit_lock, flags); + netif_tx_unlock(dev); + local_irq_restore(flags); /* We have to cancel outside of the spinlock */ list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 1d49d1643c5..7b717c648f7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -255,7 +255,8 @@ void ipoib_event(struct ib_event_handler *handler, record->event == IB_EVENT_PKEY_CHANGE || record->event == IB_EVENT_PORT_ACTIVE || record->event == IB_EVENT_LID_CHANGE || - record->event == IB_EVENT_SM_CHANGE) { + record->event == IB_EVENT_SM_CHANGE || + record->event == IB_EVENT_CLIENT_REREGISTER) { ipoib_dbg(priv, "Port state change event\n"); queue_work(ipoib_workqueue, &priv->flush_task); } diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 9cbdffa08dc..4e22afef720 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -62,6 +62,13 @@ MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator " "v" DRV_VERSION " (" DRV_RELDATE ")"); MODULE_LICENSE("Dual BSD/GPL"); +static int srp_sg_tablesize = SRP_DEF_SG_TABLESIZE; +static int srp_max_iu_len; + +module_param(srp_sg_tablesize, int, 0444); +MODULE_PARM_DESC(srp_sg_tablesize, + "Max number of gather/scatter entries per I/O (default is 12)"); + static int topspin_workarounds = 1; module_param(topspin_workarounds, int, 0444); @@ -105,7 +112,8 @@ static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, if (!iu->buf) goto out_free_iu; - iu->dma = dma_map_single(host->dev->dma_device, iu->buf, size, direction); + iu->dma = dma_map_single(host->dev->dev->dma_device, + iu->buf, size, direction); if (dma_mapping_error(iu->dma)) goto out_free_buf; @@ -127,7 +135,8 @@ static void srp_free_iu(struct srp_host *host, struct srp_iu *iu) if (!iu) return; - dma_unmap_single(host->dev->dma_device, iu->dma, iu->size, iu->direction); + dma_unmap_single(host->dev->dev->dma_device, + iu->dma, iu->size, iu->direction); kfree(iu->buf); kfree(iu); } @@ -147,7 +156,7 @@ static int srp_init_qp(struct srp_target_port *target, if (!attr) return -ENOMEM; - ret = ib_find_cached_pkey(target->srp_host->dev, + ret = ib_find_cached_pkey(target->srp_host->dev->dev, target->srp_host->port, be16_to_cpu(target->path.pkey), &attr->pkey_index); @@ -179,7 +188,7 @@ static int srp_create_target_ib(struct srp_target_port *target) if (!init_attr) return -ENOMEM; - target->cq = ib_create_cq(target->srp_host->dev, srp_completion, + target->cq = ib_create_cq(target->srp_host->dev->dev, srp_completion, NULL, target, SRP_CQ_SIZE); if (IS_ERR(target->cq)) { ret = PTR_ERR(target->cq); @@ -198,7 +207,7 @@ static int srp_create_target_ib(struct srp_target_port *target) init_attr->send_cq = target->cq; init_attr->recv_cq = target->cq; - target->qp = ib_create_qp(target->srp_host->pd, init_attr); + target->qp = ib_create_qp(target->srp_host->dev->pd, init_attr); if (IS_ERR(target->qp)) { ret = PTR_ERR(target->qp); ib_destroy_cq(target->cq); @@ -250,7 +259,7 @@ static int srp_lookup_path(struct srp_target_port *target) init_completion(&target->done); - target->path_query_id = ib_sa_path_rec_get(target->srp_host->dev, + target->path_query_id = ib_sa_path_rec_get(target->srp_host->dev->dev, target->srp_host->port, &target->path, IB_SA_PATH_REC_DGID | @@ -309,10 +318,32 @@ static int srp_send_req(struct srp_target_port *target) req->priv.opcode = SRP_LOGIN_REQ; req->priv.tag = 0; - req->priv.req_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN); + req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len); req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT); - memcpy(req->priv.initiator_port_id, target->srp_host->initiator_port_id, 16); + /* + * In the published SRP specification (draft rev. 16a), the + * port identifier format is 8 bytes of ID extension followed + * by 8 bytes of GUID. Older drafts put the two halves in the + * opposite order, so that the GUID comes first. + * + * Targets conforming to these obsolete drafts can be + * recognized by the I/O Class they report. + */ + if (target->io_class == SRP_REV10_IB_IO_CLASS) { + memcpy(req->priv.initiator_port_id, + target->srp_host->initiator_port_id + 8, 8); + memcpy(req->priv.initiator_port_id + 8, + target->srp_host->initiator_port_id, 8); + memcpy(req->priv.target_port_id, &target->ioc_guid, 8); + memcpy(req->priv.target_port_id + 8, &target->id_ext, 8); + } else { + memcpy(req->priv.initiator_port_id, + target->srp_host->initiator_port_id, 16); + memcpy(req->priv.target_port_id, &target->id_ext, 8); + memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8); + } + /* * Topspin/Cisco SRP targets will reject our login unless we * zero out the first 8 bytes of our initiator port ID. The @@ -325,8 +356,6 @@ static int srp_send_req(struct srp_target_port *target) (unsigned long long) be64_to_cpu(target->ioc_guid)); memset(req->priv.initiator_port_id, 0, 8); } - memcpy(req->priv.target_port_id, &target->id_ext, 8); - memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8); status = ib_send_cm_req(target->cm_id, &req->param); @@ -359,9 +388,9 @@ static void srp_remove_work(void *target_ptr) target->state = SRP_TARGET_REMOVED; spin_unlock_irq(target->scsi_host->host_lock); - mutex_lock(&target->srp_host->target_mutex); + spin_lock(&target->srp_host->target_lock); list_del(&target->list); - mutex_unlock(&target->srp_host->target_mutex); + spin_unlock(&target->srp_host->target_lock); scsi_remove_host(target->scsi_host); ib_destroy_cm_id(target->cm_id); @@ -421,6 +450,11 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, scmnd->sc_data_direction != DMA_FROM_DEVICE)) return; + if (req->fmr) { + ib_fmr_pool_unmap(req->fmr); + req->fmr = NULL; + } + /* * This handling of non-SG commands can be killed when the * SCSI midlayer no longer generates non-SG commands. @@ -433,18 +467,30 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, scat = &req->fake_sg; } - dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, + dma_unmap_sg(target->srp_host->dev->dev->dma_device, scat, nents, scmnd->sc_data_direction); } +static void srp_remove_req(struct srp_target_port *target, struct srp_request *req) +{ + srp_unmap_data(req->scmnd, target, req); + list_move_tail(&req->list, &target->free_reqs); +} + +static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) +{ + req->scmnd->result = DID_RESET << 16; + req->scmnd->scsi_done(req->scmnd); + srp_remove_req(target, req); +} + static int srp_reconnect_target(struct srp_target_port *target) { struct ib_cm_id *new_cm_id; struct ib_qp_attr qp_attr; - struct srp_request *req; + struct srp_request *req, *tmp; struct ib_wc wc; int ret; - int i; spin_lock_irq(target->scsi_host->host_lock); if (target->state != SRP_TARGET_LIVE) { @@ -459,7 +505,7 @@ static int srp_reconnect_target(struct srp_target_port *target) * Now get a new local CM ID so that we avoid confusing the * target in case things are really fouled up. */ - new_cm_id = ib_create_cm_id(target->srp_host->dev, + new_cm_id = ib_create_cm_id(target->srp_host->dev->dev, srp_cm_handler, target); if (IS_ERR(new_cm_id)) { ret = PTR_ERR(new_cm_id); @@ -480,19 +526,12 @@ static int srp_reconnect_target(struct srp_target_port *target) while (ib_poll_cq(target->cq, 1, &wc) > 0) ; /* nothing */ - list_for_each_entry(req, &target->req_queue, list) { - req->scmnd->result = DID_RESET << 16; - req->scmnd->scsi_done(req->scmnd); - srp_unmap_data(req->scmnd, target, req); - } + list_for_each_entry_safe(req, tmp, &target->req_queue, list) + srp_reset_req(target, req); target->rx_head = 0; target->tx_head = 0; target->tx_tail = 0; - INIT_LIST_HEAD(&target->free_reqs); - INIT_LIST_HEAD(&target->req_queue); - for (i = 0; i < SRP_SQ_SIZE; ++i) - list_add_tail(&target->req_ring[i].list, &target->free_reqs); ret = srp_connect_target(target); if (ret) @@ -528,14 +567,79 @@ err: return ret; } +static int srp_map_fmr(struct srp_device *dev, struct scatterlist *scat, + int sg_cnt, struct srp_request *req, + struct srp_direct_buf *buf) +{ + u64 io_addr = 0; + u64 *dma_pages; + u32 len; + int page_cnt; + int i, j; + int ret; + + if (!dev->fmr_pool) + return -ENODEV; + + len = page_cnt = 0; + for (i = 0; i < sg_cnt; ++i) { + if (sg_dma_address(&scat[i]) & ~dev->fmr_page_mask) { + if (i > 0) + return -EINVAL; + else + ++page_cnt; + } + if ((sg_dma_address(&scat[i]) + sg_dma_len(&scat[i])) & + ~dev->fmr_page_mask) { + if (i < sg_cnt - 1) + return -EINVAL; + else + ++page_cnt; + } + + len += sg_dma_len(&scat[i]); + } + + page_cnt += len >> dev->fmr_page_shift; + if (page_cnt > SRP_FMR_SIZE) + return -ENOMEM; + + dma_pages = kmalloc(sizeof (u64) * page_cnt, GFP_ATOMIC); + if (!dma_pages) + return -ENOMEM; + + page_cnt = 0; + for (i = 0; i < sg_cnt; ++i) + for (j = 0; j < sg_dma_len(&scat[i]); j += dev->fmr_page_size) + dma_pages[page_cnt++] = + (sg_dma_address(&scat[i]) & dev->fmr_page_mask) + j; + + req->fmr = ib_fmr_pool_map_phys(dev->fmr_pool, + dma_pages, page_cnt, &io_addr); + if (IS_ERR(req->fmr)) { + ret = PTR_ERR(req->fmr); + goto out; + } + + buf->va = cpu_to_be64(sg_dma_address(&scat[0]) & ~dev->fmr_page_mask); + buf->key = cpu_to_be32(req->fmr->fmr->rkey); + buf->len = cpu_to_be32(len); + + ret = 0; + +out: + kfree(dma_pages); + + return ret; +} + static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, struct srp_request *req) { struct scatterlist *scat; struct srp_cmd *cmd = req->cmd->buf; int len, nents, count; - int i; - u8 fmt; + u8 fmt = SRP_DATA_DESC_DIRECT; if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE) return sizeof (struct srp_cmd); @@ -560,53 +664,63 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, sg_init_one(scat, scmnd->request_buffer, scmnd->request_bufflen); } - count = dma_map_sg(target->srp_host->dev->dma_device, scat, nents, - scmnd->sc_data_direction); + count = dma_map_sg(target->srp_host->dev->dev->dma_device, + scat, nents, scmnd->sc_data_direction); + + fmt = SRP_DATA_DESC_DIRECT; + len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf); if (count == 1) { + /* + * The midlayer only generated a single gather/scatter + * entry, or DMA mapping coalesced everything to a + * single entry. So a direct descriptor along with + * the DMA MR suffices. + */ struct srp_direct_buf *buf = (void *) cmd->add_data; - fmt = SRP_DATA_DESC_DIRECT; - buf->va = cpu_to_be64(sg_dma_address(scat)); - buf->key = cpu_to_be32(target->srp_host->mr->rkey); + buf->key = cpu_to_be32(target->srp_host->dev->mr->rkey); buf->len = cpu_to_be32(sg_dma_len(scat)); - - len = sizeof (struct srp_cmd) + - sizeof (struct srp_direct_buf); - } else { + } else if (srp_map_fmr(target->srp_host->dev, scat, count, req, + (void *) cmd->add_data)) { + /* + * FMR mapping failed, and the scatterlist has more + * than one entry. Generate an indirect memory + * descriptor. + */ struct srp_indirect_buf *buf = (void *) cmd->add_data; u32 datalen = 0; + int i; fmt = SRP_DATA_DESC_INDIRECT; + len = sizeof (struct srp_cmd) + + sizeof (struct srp_indirect_buf) + + count * sizeof (struct srp_direct_buf); + + for (i = 0; i < count; ++i) { + buf->desc_list[i].va = + cpu_to_be64(sg_dma_address(&scat[i])); + buf->desc_list[i].key = + cpu_to_be32(target->srp_host->dev->mr->rkey); + buf->desc_list[i].len = + cpu_to_be32(sg_dma_len(&scat[i])); + datalen += sg_dma_len(&scat[i]); + } if (scmnd->sc_data_direction == DMA_TO_DEVICE) cmd->data_out_desc_cnt = count; else cmd->data_in_desc_cnt = count; - buf->table_desc.va = cpu_to_be64(req->cmd->dma + - sizeof *cmd + - sizeof *buf); + buf->table_desc.va = + cpu_to_be64(req->cmd->dma + sizeof *cmd + sizeof *buf); buf->table_desc.key = - cpu_to_be32(target->srp_host->mr->rkey); + cpu_to_be32(target->srp_host->dev->mr->rkey); buf->table_desc.len = cpu_to_be32(count * sizeof (struct srp_direct_buf)); - for (i = 0; i < count; ++i) { - buf->desc_list[i].va = cpu_to_be64(sg_dma_address(&scat[i])); - buf->desc_list[i].key = - cpu_to_be32(target->srp_host->mr->rkey); - buf->desc_list[i].len = cpu_to_be32(sg_dma_len(&scat[i])); - - datalen += sg_dma_len(&scat[i]); - } - buf->len = cpu_to_be32(datalen); - - len = sizeof (struct srp_cmd) + - sizeof (struct srp_indirect_buf) + - count * sizeof (struct srp_direct_buf); } if (scmnd->sc_data_direction == DMA_TO_DEVICE) @@ -617,12 +731,6 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, return len; } -static void srp_remove_req(struct srp_target_port *target, struct srp_request *req) -{ - srp_unmap_data(req->scmnd, target, req); - list_move_tail(&req->list, &target->free_reqs); -} - static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) { struct srp_request *req; @@ -689,7 +797,7 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) iu = target->rx_ring[wc->wr_id & ~SRP_OP_RECV]; - dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma, + dma_sync_single_for_cpu(target->srp_host->dev->dev->dma_device, iu->dma, target->max_ti_iu_len, DMA_FROM_DEVICE); opcode = *(u8 *) iu->buf; @@ -726,7 +834,7 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) break; } - dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma, + dma_sync_single_for_device(target->srp_host->dev->dev->dma_device, iu->dma, target->max_ti_iu_len, DMA_FROM_DEVICE); } @@ -770,7 +878,7 @@ static int __srp_post_recv(struct srp_target_port *target) list.addr = iu->dma; list.length = iu->size; - list.lkey = target->srp_host->mr->lkey; + list.lkey = target->srp_host->dev->mr->lkey; wr.next = NULL; wr.sg_list = &list; @@ -805,12 +913,8 @@ static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target) if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) return NULL; - if (unlikely(target->req_lim < 1)) { - if (printk_ratelimit()) - printk(KERN_DEBUG PFX "Target has req_lim %d\n", - target->req_lim); - return NULL; - } + if (unlikely(target->req_lim < 1)) + ++target->zero_req_lim; return target->tx_ring[target->tx_head & SRP_SQ_SIZE]; } @@ -828,7 +932,7 @@ static int __srp_post_send(struct srp_target_port *target, list.addr = iu->dma; list.length = len; - list.lkey = target->srp_host->mr->lkey; + list.lkey = target->srp_host->dev->mr->lkey; wr.next = NULL; wr.wr_id = target->tx_head & SRP_SQ_SIZE; @@ -870,8 +974,8 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, if (!iu) goto err; - dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma, - SRP_MAX_IU_LEN, DMA_TO_DEVICE); + dma_sync_single_for_cpu(target->srp_host->dev->dev->dma_device, iu->dma, + srp_max_iu_len, DMA_TO_DEVICE); req = list_entry(target->free_reqs.next, struct srp_request, list); @@ -903,8 +1007,8 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, goto err_unmap; } - dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma, - SRP_MAX_IU_LEN, DMA_TO_DEVICE); + dma_sync_single_for_device(target->srp_host->dev->dev->dma_device, iu->dma, + srp_max_iu_len, DMA_TO_DEVICE); if (__srp_post_send(target, iu, len)) { printk(KERN_ERR PFX "Send failed\n"); @@ -936,7 +1040,7 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target) for (i = 0; i < SRP_SQ_SIZE + 1; ++i) { target->tx_ring[i] = srp_alloc_iu(target->srp_host, - SRP_MAX_IU_LEN, + srp_max_iu_len, GFP_KERNEL, DMA_TO_DEVICE); if (!target->tx_ring[i]) goto err; @@ -1107,11 +1211,10 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) srp_cm_rej_handler(cm_id, event, target); break; - case IB_CM_MRA_RECEIVED: - printk(KERN_ERR PFX "MRA received\n"); - break; - - case IB_CM_DREP_RECEIVED: + case IB_CM_DREQ_RECEIVED: + printk(KERN_WARNING PFX "DREQ received - connection closed\n"); + if (ib_send_cm_drep(cm_id, NULL, 0)) + printk(KERN_ERR PFX "Sending CM DREP failed\n"); break; case IB_CM_TIMEWAIT_EXIT: @@ -1121,6 +1224,11 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) target->status = 0; break; + case IB_CM_MRA_RECEIVED: + case IB_CM_DREQ_ERROR: + case IB_CM_DREP_RECEIVED: + break; + default: printk(KERN_WARNING PFX "Unhandled CM event %d\n", event->event); break; @@ -1239,11 +1347,8 @@ static int srp_reset_device(struct scsi_cmnd *scmnd) spin_lock_irq(target->scsi_host->host_lock); list_for_each_entry_safe(req, tmp, &target->req_queue, list) - if (req->scmnd->device == scmnd->device) { - req->scmnd->result = DID_RESET << 16; - req->scmnd->scsi_done(req->scmnd); - srp_remove_req(target, req); - } + if (req->scmnd->device == scmnd->device) + srp_reset_req(target, req); spin_unlock_irq(target->scsi_host->host_lock); @@ -1329,11 +1434,23 @@ static ssize_t show_dgid(struct class_device *cdev, char *buf) be16_to_cpu(((__be16 *) target->path.dgid.raw)[7])); } +static ssize_t show_zero_req_lim(struct class_device *cdev, char *buf) +{ + struct srp_target_port *target = host_to_target(class_to_shost(cdev)); + + if (target->state == SRP_TARGET_DEAD || + target->state == SRP_TARGET_REMOVED) + return -ENODEV; + + return sprintf(buf, "%d\n", target->zero_req_lim); +} + static CLASS_DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); static CLASS_DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL); +static CLASS_DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); static struct class_device_attribute *srp_host_attrs[] = { &class_device_attr_id_ext, @@ -1341,6 +1458,7 @@ static struct class_device_attribute *srp_host_attrs[] = { &class_device_attr_service_id, &class_device_attr_pkey, &class_device_attr_dgid, + &class_device_attr_zero_req_lim, NULL }; @@ -1354,7 +1472,6 @@ static struct scsi_host_template srp_template = { .eh_host_reset_handler = srp_reset_host, .can_queue = SRP_SQ_SIZE, .this_id = -1, - .sg_tablesize = SRP_MAX_INDIRECT, .cmd_per_lun = SRP_SQ_SIZE, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = srp_host_attrs @@ -1365,18 +1482,17 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target) sprintf(target->target_name, "SRP.T10:%016llX", (unsigned long long) be64_to_cpu(target->id_ext)); - if (scsi_add_host(target->scsi_host, host->dev->dma_device)) + if (scsi_add_host(target->scsi_host, host->dev->dev->dma_device)) return -ENODEV; - mutex_lock(&host->target_mutex); + spin_lock(&host->target_lock); list_add_tail(&target->list, &host->target_list); - mutex_unlock(&host->target_mutex); + spin_unlock(&host->target_lock); target->state = SRP_TARGET_LIVE; - /* XXX: are we supposed to have a definition of SCAN_WILD_CARD ?? */ scsi_scan_target(&target->scsi_host->shost_gendev, - 0, target->scsi_id, ~0, 0); + 0, target->scsi_id, SCAN_WILD_CARD, 0); return 0; } @@ -1410,6 +1526,8 @@ enum { SRP_OPT_PKEY = 1 << 3, SRP_OPT_SERVICE_ID = 1 << 4, SRP_OPT_MAX_SECT = 1 << 5, + SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, + SRP_OPT_IO_CLASS = 1 << 7, SRP_OPT_ALL = (SRP_OPT_ID_EXT | SRP_OPT_IOC_GUID | SRP_OPT_DGID | @@ -1418,13 +1536,15 @@ enum { }; static match_table_t srp_opt_tokens = { - { SRP_OPT_ID_EXT, "id_ext=%s" }, - { SRP_OPT_IOC_GUID, "ioc_guid=%s" }, - { SRP_OPT_DGID, "dgid=%s" }, - { SRP_OPT_PKEY, "pkey=%x" }, - { SRP_OPT_SERVICE_ID, "service_id=%s" }, - { SRP_OPT_MAX_SECT, "max_sect=%d" }, - { SRP_OPT_ERR, NULL } + { SRP_OPT_ID_EXT, "id_ext=%s" }, + { SRP_OPT_IOC_GUID, "ioc_guid=%s" }, + { SRP_OPT_DGID, "dgid=%s" }, + { SRP_OPT_PKEY, "pkey=%x" }, + { SRP_OPT_SERVICE_ID, "service_id=%s" }, + { SRP_OPT_MAX_SECT, "max_sect=%d" }, + { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, + { SRP_OPT_IO_CLASS, "io_class=%x" }, + { SRP_OPT_ERR, NULL } }; static int srp_parse_options(const char *buf, struct srp_target_port *target) @@ -1500,6 +1620,29 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) target->scsi_host->max_sectors = token; break; + case SRP_OPT_MAX_CMD_PER_LUN: + if (match_int(args, &token)) { + printk(KERN_WARNING PFX "bad max cmd_per_lun parameter '%s'\n", p); + goto out; + } + target->scsi_host->cmd_per_lun = min(token, SRP_SQ_SIZE); + break; + + case SRP_OPT_IO_CLASS: + if (match_hex(args, &token)) { + printk(KERN_WARNING PFX "bad IO class parameter '%s' \n", p); + goto out; + } + if (token != SRP_REV10_IB_IO_CLASS && + token != SRP_REV16A_IB_IO_CLASS) { + printk(KERN_WARNING PFX "unknown IO class parameter value" + " %x specified (use %x or %x).\n", + token, SRP_REV10_IB_IO_CLASS, SRP_REV16A_IB_IO_CLASS); + goto out; + } + target->io_class = token; + break; + default: printk(KERN_WARNING PFX "unknown parameter or missing value " "'%s' in target creation request\n", p); @@ -1542,6 +1685,7 @@ static ssize_t srp_create_target(struct class_device *class_dev, target = host_to_target(target_host); memset(target, 0, sizeof *target); + target->io_class = SRP_REV16A_IB_IO_CLASS; target->scsi_host = target_host; target->srp_host = host; @@ -1558,7 +1702,7 @@ static ssize_t srp_create_target(struct class_device *class_dev, if (ret) goto err; - ib_get_cached_gid(host->dev, host->port, 0, &target->path.sgid); + ib_get_cached_gid(host->dev->dev, host->port, 0, &target->path.sgid); printk(KERN_DEBUG PFX "new target: id_ext %016llx ioc_guid %016llx pkey %04x " "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", @@ -1579,7 +1723,7 @@ static ssize_t srp_create_target(struct class_device *class_dev, if (ret) goto err; - target->cm_id = ib_create_cm_id(host->dev, srp_cm_handler, target); + target->cm_id = ib_create_cm_id(host->dev->dev, srp_cm_handler, target); if (IS_ERR(target->cm_id)) { ret = PTR_ERR(target->cm_id); goto err_free; @@ -1619,7 +1763,7 @@ static ssize_t show_ibdev(struct class_device *class_dev, char *buf) struct srp_host *host = container_of(class_dev, struct srp_host, class_dev); - return sprintf(buf, "%s\n", host->dev->name); + return sprintf(buf, "%s\n", host->dev->dev->name); } static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); @@ -1634,7 +1778,7 @@ static ssize_t show_port(struct class_device *class_dev, char *buf) static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); -static struct srp_host *srp_add_port(struct ib_device *device, u8 port) +static struct srp_host *srp_add_port(struct srp_device *device, u8 port) { struct srp_host *host; @@ -1643,32 +1787,21 @@ static struct srp_host *srp_add_port(struct ib_device *device, u8 port) return NULL; INIT_LIST_HEAD(&host->target_list); - mutex_init(&host->target_mutex); + spin_lock_init(&host->target_lock); init_completion(&host->released); host->dev = device; host->port = port; host->initiator_port_id[7] = port; - memcpy(host->initiator_port_id + 8, &device->node_guid, 8); - - host->pd = ib_alloc_pd(device); - if (IS_ERR(host->pd)) - goto err_free; - - host->mr = ib_get_dma_mr(host->pd, - IB_ACCESS_LOCAL_WRITE | - IB_ACCESS_REMOTE_READ | - IB_ACCESS_REMOTE_WRITE); - if (IS_ERR(host->mr)) - goto err_pd; + memcpy(host->initiator_port_id + 8, &device->dev->node_guid, 8); host->class_dev.class = &srp_class; - host->class_dev.dev = device->dma_device; + host->class_dev.dev = device->dev->dma_device; snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d", - device->name, port); + device->dev->name, port); if (class_device_register(&host->class_dev)) - goto err_mr; + goto free_host; if (class_device_create_file(&host->class_dev, &class_device_attr_add_target)) goto err_class; if (class_device_create_file(&host->class_dev, &class_device_attr_ibdev)) @@ -1681,13 +1814,7 @@ static struct srp_host *srp_add_port(struct ib_device *device, u8 port) err_class: class_device_unregister(&host->class_dev); -err_mr: - ib_dereg_mr(host->mr); - -err_pd: - ib_dealloc_pd(host->pd); - -err_free: +free_host: kfree(host); return NULL; @@ -1695,15 +1822,62 @@ err_free: static void srp_add_one(struct ib_device *device) { - struct list_head *dev_list; + struct srp_device *srp_dev; + struct ib_device_attr *dev_attr; + struct ib_fmr_pool_param fmr_param; struct srp_host *host; int s, e, p; - dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); - if (!dev_list) + dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); + if (!dev_attr) return; - INIT_LIST_HEAD(dev_list); + if (ib_query_device(device, dev_attr)) { + printk(KERN_WARNING PFX "Query device failed for %s\n", + device->name); + goto free_attr; + } + + srp_dev = kmalloc(sizeof *srp_dev, GFP_KERNEL); + if (!srp_dev) + goto free_attr; + + /* + * Use the smallest page size supported by the HCA, down to a + * minimum of 512 bytes (which is the smallest sector that a + * SCSI command will ever carry). + */ + srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1); + srp_dev->fmr_page_size = 1 << srp_dev->fmr_page_shift; + srp_dev->fmr_page_mask = ~((unsigned long) srp_dev->fmr_page_size - 1); + + INIT_LIST_HEAD(&srp_dev->dev_list); + + srp_dev->dev = device; + srp_dev->pd = ib_alloc_pd(device); + if (IS_ERR(srp_dev->pd)) + goto free_dev; + + srp_dev->mr = ib_get_dma_mr(srp_dev->pd, + IB_ACCESS_LOCAL_WRITE | + IB_ACCESS_REMOTE_READ | + IB_ACCESS_REMOTE_WRITE); + if (IS_ERR(srp_dev->mr)) + goto err_pd; + + memset(&fmr_param, 0, sizeof fmr_param); + fmr_param.pool_size = SRP_FMR_POOL_SIZE; + fmr_param.dirty_watermark = SRP_FMR_DIRTY_SIZE; + fmr_param.cache = 1; + fmr_param.max_pages_per_fmr = SRP_FMR_SIZE; + fmr_param.page_shift = srp_dev->fmr_page_shift; + fmr_param.access = (IB_ACCESS_LOCAL_WRITE | + IB_ACCESS_REMOTE_WRITE | + IB_ACCESS_REMOTE_READ); + + srp_dev->fmr_pool = ib_create_fmr_pool(srp_dev->pd, &fmr_param); + if (IS_ERR(srp_dev->fmr_pool)) + srp_dev->fmr_pool = NULL; if (device->node_type == IB_NODE_SWITCH) { s = 0; @@ -1714,25 +1888,35 @@ static void srp_add_one(struct ib_device *device) } for (p = s; p <= e; ++p) { - host = srp_add_port(device, p); + host = srp_add_port(srp_dev, p); if (host) - list_add_tail(&host->list, dev_list); + list_add_tail(&host->list, &srp_dev->dev_list); } - ib_set_client_data(device, &srp_client, dev_list); + ib_set_client_data(device, &srp_client, srp_dev); + + goto free_attr; + +err_pd: + ib_dealloc_pd(srp_dev->pd); + +free_dev: + kfree(srp_dev); + +free_attr: + kfree(dev_attr); } static void srp_remove_one(struct ib_device *device) { - struct list_head *dev_list; + struct srp_device *srp_dev; struct srp_host *host, *tmp_host; LIST_HEAD(target_list); struct srp_target_port *target, *tmp_target; - unsigned long flags; - dev_list = ib_get_client_data(device, &srp_client); + srp_dev = ib_get_client_data(device, &srp_client); - list_for_each_entry_safe(host, tmp_host, dev_list, list) { + list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) { class_device_unregister(&host->class_dev); /* * Wait for the sysfs entry to go away, so that no new @@ -1744,15 +1928,13 @@ static void srp_remove_one(struct ib_device *device) * Mark all target ports as removed, so we stop queueing * commands and don't try to reconnect. */ - mutex_lock(&host->target_mutex); - list_for_each_entry_safe(target, tmp_target, - &host->target_list, list) { - spin_lock_irqsave(target->scsi_host->host_lock, flags); - if (target->state != SRP_TARGET_REMOVED) - target->state = SRP_TARGET_REMOVED; - spin_unlock_irqrestore(target->scsi_host->host_lock, flags); + spin_lock(&host->target_lock); + list_for_each_entry(target, &host->target_list, list) { + spin_lock_irq(target->scsi_host->host_lock); + target->state = SRP_TARGET_REMOVED; + spin_unlock_irq(target->scsi_host->host_lock); } - mutex_unlock(&host->target_mutex); + spin_unlock(&host->target_lock); /* * Wait for any reconnection tasks that may have @@ -1770,18 +1952,26 @@ static void srp_remove_one(struct ib_device *device) scsi_host_put(target->scsi_host); } - ib_dereg_mr(host->mr); - ib_dealloc_pd(host->pd); kfree(host); } - kfree(dev_list); + if (srp_dev->fmr_pool) + ib_destroy_fmr_pool(srp_dev->fmr_pool); + ib_dereg_mr(srp_dev->mr); + ib_dealloc_pd(srp_dev->pd); + + kfree(srp_dev); } static int __init srp_init_module(void) { int ret; + srp_template.sg_tablesize = srp_sg_tablesize; + srp_max_iu_len = (sizeof (struct srp_cmd) + + sizeof (struct srp_indirect_buf) + + srp_sg_tablesize * 16); + ret = class_register(&srp_class); if (ret) { printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index c5cd43aae86..5b581fb8eb0 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -46,6 +46,7 @@ #include <rdma/ib_verbs.h> #include <rdma/ib_sa.h> #include <rdma/ib_cm.h> +#include <rdma/ib_fmr_pool.h> enum { SRP_PATH_REC_TIMEOUT_MS = 1000, @@ -55,20 +56,21 @@ enum { SRP_DLID_REDIRECT = 2, SRP_MAX_LUN = 512, - SRP_MAX_IU_LEN = 256, + SRP_DEF_SG_TABLESIZE = 12, SRP_RQ_SHIFT = 6, SRP_RQ_SIZE = 1 << SRP_RQ_SHIFT, SRP_SQ_SIZE = SRP_RQ_SIZE - 1, SRP_CQ_SIZE = SRP_SQ_SIZE + SRP_RQ_SIZE, - SRP_TAG_TSK_MGMT = 1 << (SRP_RQ_SHIFT + 1) + SRP_TAG_TSK_MGMT = 1 << (SRP_RQ_SHIFT + 1), + + SRP_FMR_SIZE = 256, + SRP_FMR_POOL_SIZE = 1024, + SRP_FMR_DIRTY_SIZE = SRP_FMR_POOL_SIZE / 4 }; #define SRP_OP_RECV (1 << 31) -#define SRP_MAX_INDIRECT ((SRP_MAX_IU_LEN - \ - sizeof (struct srp_cmd) - \ - sizeof (struct srp_indirect_buf)) / 16) enum srp_target_state { SRP_TARGET_LIVE, @@ -77,15 +79,24 @@ enum srp_target_state { SRP_TARGET_REMOVED }; -struct srp_host { - u8 initiator_port_id[16]; +struct srp_device { + struct list_head dev_list; struct ib_device *dev; - u8 port; struct ib_pd *pd; struct ib_mr *mr; + struct ib_fmr_pool *fmr_pool; + int fmr_page_shift; + int fmr_page_size; + unsigned long fmr_page_mask; +}; + +struct srp_host { + u8 initiator_port_id[16]; + struct srp_device *dev; + u8 port; struct class_device class_dev; struct list_head target_list; - struct mutex target_mutex; + spinlock_t target_lock; struct completion released; struct list_head list; }; @@ -95,6 +106,7 @@ struct srp_request { struct scsi_cmnd *scmnd; struct srp_iu *cmd; struct srp_iu *tsk_mgmt; + struct ib_pool_fmr *fmr; /* * Fake scatterlist used when scmnd->use_sg==0. Can be killed * when the SCSI midlayer no longer generates non-SG commands. @@ -110,6 +122,7 @@ struct srp_target_port { __be64 id_ext; __be64 ioc_guid; __be64 service_id; + u16 io_class; struct srp_host *srp_host; struct Scsi_Host *scsi_host; char target_name[32]; @@ -126,6 +139,8 @@ struct srp_target_port { int max_ti_iu_len; s32 req_lim; + int zero_req_lim; + unsigned rx_head; struct srp_iu *rx_ring[SRP_RQ_SIZE]; diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 2f0f35811bf..9fd87521a16 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void *data) dvb_net_feed_stop(dev); priv->rx_mode = RX_MODE_UNI; - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); if (dev->flags & IFF_PROMISC) { dprintk("%s: promiscuous mode\n", dev->name); @@ -1077,7 +1077,7 @@ static void wq_set_multicast_list (void *data) } } - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); dvb_net_feed_start(dev); } diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index f2a4d382ea1..3201de05394 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -831,6 +831,7 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) return rc; } +#ifdef CONFIG_PM /* * spi module resume handler */ @@ -846,6 +847,7 @@ mptspi_resume(struct pci_dev *pdev) return rc; } +#endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 5ea133c59af..7bd4d85d0b4 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c @@ -55,6 +55,7 @@ struct i2o_exec_wait { u32 m; /* message id */ struct i2o_message *msg; /* pointer to the reply message */ struct list_head list; /* node in global wait list */ + spinlock_t lock; /* lock before modifying */ }; /* Work struct needed to handle LCT NOTIFY replies */ @@ -87,6 +88,7 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void) return NULL; INIT_LIST_HEAD(&wait->list); + spin_lock_init(&wait->lock); return wait; }; @@ -125,6 +127,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, DECLARE_WAIT_QUEUE_HEAD(wq); struct i2o_exec_wait *wait; static u32 tcntxt = 0x80000000; + long flags; int rc = 0; wait = i2o_exec_wait_alloc(); @@ -146,33 +149,28 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, wait->tcntxt = tcntxt++; msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt); + wait->wq = &wq; + /* + * we add elements to the head, because if a entry in the list will + * never be removed, we have to iterate over it every time + */ + list_add(&wait->list, &i2o_exec_wait_list); + /* * Post the message to the controller. At some point later it will * return. If we time out before it returns then complete will be zero. */ i2o_msg_post(c, msg); - if (!wait->complete) { - wait->wq = &wq; - /* - * we add elements add the head, because if a entry in the list - * will never be removed, we have to iterate over it every time - */ - list_add(&wait->list, &i2o_exec_wait_list); - - wait_event_interruptible_timeout(wq, wait->complete, - timeout * HZ); + wait_event_interruptible_timeout(wq, wait->complete, timeout * HZ); - wait->wq = NULL; - } + spin_lock_irqsave(&wait->lock, flags); - barrier(); + wait->wq = NULL; - if (wait->complete) { + if (wait->complete) rc = le32_to_cpu(wait->msg->body[0]) >> 24; - i2o_flush_reply(c, wait->m); - i2o_exec_wait_free(wait); - } else { + else { /* * We cannot remove it now. This is important. When it does * terminate (which it must do if the controller has not @@ -186,6 +184,13 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, rc = -ETIMEDOUT; } + spin_unlock_irqrestore(&wait->lock, flags); + + if (rc != -ETIMEDOUT) { + i2o_flush_reply(c, wait->m); + i2o_exec_wait_free(wait); + } + return rc; }; @@ -213,7 +218,6 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, { struct i2o_exec_wait *wait, *tmp; unsigned long flags; - static spinlock_t lock = SPIN_LOCK_UNLOCKED; int rc = 1; /* @@ -223,23 +227,24 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, * already expired. Not much we can do about that except log it for * debug purposes, increase timeout, and recompile. */ - spin_lock_irqsave(&lock, flags); list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { if (wait->tcntxt == context) { - list_del(&wait->list); + spin_lock_irqsave(&wait->lock, flags); - spin_unlock_irqrestore(&lock, flags); + list_del(&wait->list); wait->m = m; wait->msg = msg; wait->complete = 1; - barrier(); - - if (wait->wq) { - wake_up_interruptible(wait->wq); + if (wait->wq) rc = 0; - } else { + else + rc = -1; + + spin_unlock_irqrestore(&wait->lock, flags); + + if (rc) { struct device *dev; dev = &c->pdev->dev; @@ -248,15 +253,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, c->name); i2o_dma_free(dev, &wait->dma); i2o_exec_wait_free(wait); - rc = -1; - } + } else + wake_up_interruptible(wait->wq); return rc; } } - spin_unlock_irqrestore(&lock, flags); - osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, context); @@ -322,14 +325,9 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL); static int i2o_exec_probe(struct device *dev) { struct i2o_device *i2o_dev = to_i2o_device(dev); - struct i2o_controller *c = i2o_dev->iop; i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); - c->exec = i2o_dev; - - i2o_exec_lct_notify(c, c->lct->change_ind + 1); - device_create_file(dev, &dev_attr_vendor_id); device_create_file(dev, &dev_attr_product_id); @@ -523,6 +521,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) struct device *dev; struct i2o_message *msg; + down(&c->lct_lock); + dev = &c->pdev->dev; if (i2o_dma_realloc @@ -545,6 +545,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) i2o_msg_post(c, msg); + up(&c->lct_lock); + return 0; }; diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 49216744693..febbdd4e060 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -804,8 +804,6 @@ void i2o_iop_remove(struct i2o_controller *c) /* Ask the IOP to switch to RESET state */ i2o_iop_reset(c); - - put_device(&c->device); } /** @@ -1059,7 +1057,7 @@ struct i2o_controller *i2o_iop_alloc(void) snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name); if (i2o_pool_alloc - (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4, + (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4 + sizeof(u32), I2O_MSG_INPOOL_MIN)) { kfree(c); return ERR_PTR(-ENOMEM); diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index f6d51ce34b0..bb44509fd40 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -909,7 +909,7 @@ MODULE_PARM_DESC(irq, "EtherLink IRQ number"); * here also causes the module to be unloaded */ -int init_module(void) +int __init init_module(void) { dev_3c501 = el1_probe(-1); if (IS_ERR(dev_3c501)) diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index dcc98afa65d..cb5ef75450d 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -688,7 +688,7 @@ MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ -int +int __init init_module(void) { struct net_device *dev; diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 111601ca4ca..19c0b856c48 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -1633,7 +1633,7 @@ MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)"); MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)"); MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)"); -int init_module(void) +int __init init_module(void) { int this_dev, found = 0; diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 4db82893909..6039049259e 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -932,7 +932,7 @@ module_param(irq, int, 0); MODULE_PARM_DESC(io, "EtherLink16 I/O base address"); MODULE_PARM_DESC(irq, "(ignored)"); -int init_module(void) +int __init init_module(void) { if (io == 0) printk("3c507: You should not use auto-probing with insmod!\n"); diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index b40885d4168..4bf8510655c 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -1277,7 +1277,7 @@ MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)"); MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)"); MODULE_LICENSE("GPL"); -int init_module(void) +int __init init_module(void) { int this_dev,found = 0; diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 6db3301e796..1b1cb002607 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -1646,7 +1646,7 @@ static struct net_device *this_device; * insmod multiple modules for now but it's a hack. */ -int init_module(void) +int __init init_module(void) { this_device = mc32_probe(-1); if (IS_ERR(this_device)) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f499a3bc629..0c6b45a11d1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -447,6 +447,7 @@ config MIPS_GT96100ETH config MIPS_AU1X00_ENET bool "MIPS AU1000 Ethernet support" depends on NET_ETHERNET && SOC_AU1X00 + select PHYLIB select CRC32 help If you have an Alchemy Semi AU1X00 based system @@ -869,7 +870,7 @@ config SMC911X tristate "SMSC LAN911[5678] support" select CRC32 select MII - depends on NET_ETHERNET + depends on NET_ETHERNET && ARCH_PXA help This is a driver for SMSC's LAN911x series of Ethernet chipsets including the new LAN9115, LAN9116, LAN9117, and LAN9118. @@ -2179,6 +2180,8 @@ config TIGON3 config BNX2 tristate "Broadcom NetXtremeII support" depends on PCI + select CRC32 + select ZLIB_INFLATE help This driver supports Broadcom NetXtremeII gigabit Ethernet cards. diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index e1fe960d71b..038d5fcb15e 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -9,6 +9,9 @@ * Update: 2004 Bjoern Riemer, riemer@fokus.fraunhofer.de * or riemer@riemer-nt.de: fixed the link beat detection with * ioctls (SIOCGMIIPHY) + * Copyright 2006 Herbert Valerio Riedel <hvr@gnu.org> + * converted to use linux-2.6.x's PHY framework + * * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -53,6 +56,7 @@ #include <linux/skbuff.h> #include <linux/delay.h> #include <linux/crc32.h> +#include <linux/phy.h> #include <asm/mipsregs.h> #include <asm/irq.h> #include <asm/io.h> @@ -88,17 +92,15 @@ static int au1000_tx(struct sk_buff *, struct net_device *); static int au1000_rx(struct net_device *); static irqreturn_t au1000_interrupt(int, void *, struct pt_regs *); static void au1000_tx_timeout(struct net_device *); -static int au1000_set_config(struct net_device *dev, struct ifmap *map); static void set_rx_mode(struct net_device *); static struct net_device_stats *au1000_get_stats(struct net_device *); -static void au1000_timer(unsigned long); static int au1000_ioctl(struct net_device *, struct ifreq *, int); static int mdio_read(struct net_device *, int, int); static void mdio_write(struct net_device *, int, int, u16); -static void dump_mii(struct net_device *dev, int phy_id); +static void au1000_adjust_link(struct net_device *); +static void enable_mac(struct net_device *, int); // externs -extern void ack_rise_edge_irq(unsigned int); extern int get_ethernet_addr(char *ethernet_addr); extern void str2eaddr(unsigned char *ea, unsigned char *str); extern char * __init prom_getcmdline(void); @@ -126,705 +128,83 @@ static unsigned char au1000_mac_addr[6] __devinitdata = { 0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00 }; -#define nibswap(x) ((((x) >> 4) & 0x0f) | (((x) << 4) & 0xf0)) -#define RUN_AT(x) (jiffies + (x)) - -// For reading/writing 32-bit words from/to DMA memory -#define cpu_to_dma32 cpu_to_be32 -#define dma32_to_cpu be32_to_cpu - struct au1000_private *au_macs[NUM_ETH_INTERFACES]; -/* FIXME - * All of the PHY code really should be detached from the MAC - * code. +/* + * board-specific configurations + * + * PHY detection algorithm + * + * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is + * autodetected: + * + * mii_probe() first searches the current MAC's MII bus for a PHY, + * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is + * defined) PHY address not already claimed by another netdev. + * + * If nothing was found that way when searching for the 2nd ethernet + * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then + * the first MII bus is searched as well for an unclaimed PHY; this is + * needed in case of a dual-PHY accessible only through the MAC0's MII + * bus. + * + * Finally, if no PHY is found, then the corresponding ethernet + * controller is not registered to the network subsystem. */ -/* Default advertise */ -#define GENMII_DEFAULT_ADVERTISE \ - ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ - ADVERTISED_Autoneg - -#define GENMII_DEFAULT_FEATURES \ - SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ - SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ - SUPPORTED_Autoneg - -int bcm_5201_init(struct net_device *dev, int phy_addr) -{ - s16 data; - - /* Stop auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); - - /* Set advertisement to 10/100 and Half/Full duplex - * (full capabilities) */ - data = mdio_read(dev, phy_addr, MII_ANADV); - data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; - mdio_write(dev, phy_addr, MII_ANADV, data); - - /* Restart auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; - mdio_write(dev, phy_addr, MII_CONTROL, data); - - if (au1000_debug > 4) - dump_mii(dev, phy_addr); - return 0; -} - -int bcm_5201_reset(struct net_device *dev, int phy_addr) -{ - s16 mii_control, timeout; - - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); - mdelay(1); - for (timeout = 100; timeout > 0; --timeout) { - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - if ((mii_control & MII_CNTL_RESET) == 0) - break; - mdelay(1); - } - if (mii_control & MII_CNTL_RESET) { - printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); - return -1; - } - return 0; -} - -int -bcm_5201_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - u16 mii_data; - struct au1000_private *aup; - - if (!dev) { - printk(KERN_ERR "bcm_5201_status error: NULL dev\n"); - return -1; - } - aup = (struct au1000_private *) dev->priv; - - mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); - if (mii_data & MII_STAT_LINK) { - *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL); - if (mii_data & MII_AUX_100) { - if (mii_data & MII_AUX_FDX) { - *speed = IF_PORT_100BASEFX; - dev->if_port = IF_PORT_100BASEFX; - } - else { - *speed = IF_PORT_100BASETX; - dev->if_port = IF_PORT_100BASETX; - } - } - else { - *speed = IF_PORT_10BASET; - dev->if_port = IF_PORT_10BASET; - } - - } - else { - *link = 0; - *speed = 0; - dev->if_port = IF_PORT_UNKNOWN; - } - return 0; -} - -int lsi_80227_init(struct net_device *dev, int phy_addr) -{ - if (au1000_debug > 4) - printk("lsi_80227_init\n"); - - /* restart auto-negotiation */ - mdio_write(dev, phy_addr, MII_CONTROL, - MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO); // | MII_CNTL_FDX); - mdelay(1); - - /* set up LEDs to correct display */ -#ifdef CONFIG_MIPS_MTX1 - mdio_write(dev, phy_addr, 17, 0xff80); -#else - mdio_write(dev, phy_addr, 17, 0xffc0); -#endif - - if (au1000_debug > 4) - dump_mii(dev, phy_addr); - return 0; -} - -int lsi_80227_reset(struct net_device *dev, int phy_addr) -{ - s16 mii_control, timeout; - - if (au1000_debug > 4) { - printk("lsi_80227_reset\n"); - dump_mii(dev, phy_addr); - } - - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); - mdelay(1); - for (timeout = 100; timeout > 0; --timeout) { - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - if ((mii_control & MII_CNTL_RESET) == 0) - break; - mdelay(1); - } - if (mii_control & MII_CNTL_RESET) { - printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); - return -1; - } - return 0; -} - -int -lsi_80227_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - u16 mii_data; - struct au1000_private *aup; - - if (!dev) { - printk(KERN_ERR "lsi_80227_status error: NULL dev\n"); - return -1; - } - aup = (struct au1000_private *) dev->priv; - - mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); - if (mii_data & MII_STAT_LINK) { - *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_PHY_STAT); - if (mii_data & MII_LSI_PHY_STAT_SPD) { - if (mii_data & MII_LSI_PHY_STAT_FDX) { - *speed = IF_PORT_100BASEFX; - dev->if_port = IF_PORT_100BASEFX; - } - else { - *speed = IF_PORT_100BASETX; - dev->if_port = IF_PORT_100BASETX; - } - } - else { - *speed = IF_PORT_10BASET; - dev->if_port = IF_PORT_10BASET; - } - - } - else { - *link = 0; - *speed = 0; - dev->if_port = IF_PORT_UNKNOWN; - } - return 0; -} - -int am79c901_init(struct net_device *dev, int phy_addr) -{ - printk("am79c901_init\n"); - return 0; -} - -int am79c901_reset(struct net_device *dev, int phy_addr) -{ - printk("am79c901_reset\n"); - return 0; -} - -int -am79c901_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - return 0; -} - -int am79c874_init(struct net_device *dev, int phy_addr) -{ - s16 data; - - /* 79c874 has quit resembled bit assignments to BCM5201 */ - if (au1000_debug > 4) - printk("am79c847_init\n"); - - /* Stop auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); - - /* Set advertisement to 10/100 and Half/Full duplex - * (full capabilities) */ - data = mdio_read(dev, phy_addr, MII_ANADV); - data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; - mdio_write(dev, phy_addr, MII_ANADV, data); - - /* Restart auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; - - mdio_write(dev, phy_addr, MII_CONTROL, data); - - if (au1000_debug > 4) dump_mii(dev, phy_addr); - return 0; -} - -int am79c874_reset(struct net_device *dev, int phy_addr) -{ - s16 mii_control, timeout; - - if (au1000_debug > 4) - printk("am79c874_reset\n"); - - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); - mdelay(1); - for (timeout = 100; timeout > 0; --timeout) { - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - if ((mii_control & MII_CNTL_RESET) == 0) - break; - mdelay(1); - } - if (mii_control & MII_CNTL_RESET) { - printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); - return -1; - } - return 0; -} - -int -am79c874_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - u16 mii_data; - struct au1000_private *aup; - - // printk("am79c874_status\n"); - if (!dev) { - printk(KERN_ERR "am79c874_status error: NULL dev\n"); - return -1; - } - - aup = (struct au1000_private *) dev->priv; - mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); +/* autodetection defaults */ +#undef AU1XXX_PHY_SEARCH_HIGHEST_ADDR +#define AU1XXX_PHY1_SEARCH_ON_MAC0 - if (mii_data & MII_STAT_LINK) { - *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, MII_AMD_PHY_STAT); - if (mii_data & MII_AMD_PHY_STAT_SPD) { - if (mii_data & MII_AMD_PHY_STAT_FDX) { - *speed = IF_PORT_100BASEFX; - dev->if_port = IF_PORT_100BASEFX; - } - else { - *speed = IF_PORT_100BASETX; - dev->if_port = IF_PORT_100BASETX; - } - } - else { - *speed = IF_PORT_10BASET; - dev->if_port = IF_PORT_10BASET; - } - - } - else { - *link = 0; - *speed = 0; - dev->if_port = IF_PORT_UNKNOWN; - } - return 0; -} - -int lxt971a_init(struct net_device *dev, int phy_addr) -{ - if (au1000_debug > 4) - printk("lxt971a_init\n"); - - /* restart auto-negotiation */ - mdio_write(dev, phy_addr, MII_CONTROL, - MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO | MII_CNTL_FDX); - - /* set up LEDs to correct display */ - mdio_write(dev, phy_addr, 20, 0x0422); - - if (au1000_debug > 4) - dump_mii(dev, phy_addr); - return 0; -} - -int lxt971a_reset(struct net_device *dev, int phy_addr) -{ - s16 mii_control, timeout; - - if (au1000_debug > 4) { - printk("lxt971a_reset\n"); - dump_mii(dev, phy_addr); - } - - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); - mdelay(1); - for (timeout = 100; timeout > 0; --timeout) { - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - if ((mii_control & MII_CNTL_RESET) == 0) - break; - mdelay(1); - } - if (mii_control & MII_CNTL_RESET) { - printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); - return -1; - } - return 0; -} - -int -lxt971a_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - u16 mii_data; - struct au1000_private *aup; - - if (!dev) { - printk(KERN_ERR "lxt971a_status error: NULL dev\n"); - return -1; - } - aup = (struct au1000_private *) dev->priv; - - mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); - if (mii_data & MII_STAT_LINK) { - *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, MII_INTEL_PHY_STAT); - if (mii_data & MII_INTEL_PHY_STAT_SPD) { - if (mii_data & MII_INTEL_PHY_STAT_FDX) { - *speed = IF_PORT_100BASEFX; - dev->if_port = IF_PORT_100BASEFX; - } - else { - *speed = IF_PORT_100BASETX; - dev->if_port = IF_PORT_100BASETX; - } - } - else { - *speed = IF_PORT_10BASET; - dev->if_port = IF_PORT_10BASET; - } - - } - else { - *link = 0; - *speed = 0; - dev->if_port = IF_PORT_UNKNOWN; - } - return 0; -} - -int ks8995m_init(struct net_device *dev, int phy_addr) -{ - s16 data; - -// printk("ks8995m_init\n"); - /* Stop auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); - - /* Set advertisement to 10/100 and Half/Full duplex - * (full capabilities) */ - data = mdio_read(dev, phy_addr, MII_ANADV); - data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; - mdio_write(dev, phy_addr, MII_ANADV, data); - - /* Restart auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; - mdio_write(dev, phy_addr, MII_CONTROL, data); - - if (au1000_debug > 4) dump_mii(dev, phy_addr); - - return 0; -} - -int ks8995m_reset(struct net_device *dev, int phy_addr) -{ - s16 mii_control, timeout; - -// printk("ks8995m_reset\n"); - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); - mdelay(1); - for (timeout = 100; timeout > 0; --timeout) { - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - if ((mii_control & MII_CNTL_RESET) == 0) - break; - mdelay(1); - } - if (mii_control & MII_CNTL_RESET) { - printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); - return -1; - } - return 0; -} - -int ks8995m_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - u16 mii_data; - struct au1000_private *aup; - - if (!dev) { - printk(KERN_ERR "ks8995m_status error: NULL dev\n"); - return -1; - } - aup = (struct au1000_private *) dev->priv; - - mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); - if (mii_data & MII_STAT_LINK) { - *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL); - if (mii_data & MII_AUX_100) { - if (mii_data & MII_AUX_FDX) { - *speed = IF_PORT_100BASEFX; - dev->if_port = IF_PORT_100BASEFX; - } - else { - *speed = IF_PORT_100BASETX; - dev->if_port = IF_PORT_100BASETX; - } - } - else { - *speed = IF_PORT_10BASET; - dev->if_port = IF_PORT_10BASET; - } - - } - else { - *link = 0; - *speed = 0; - dev->if_port = IF_PORT_UNKNOWN; - } - return 0; -} - -int -smsc_83C185_init (struct net_device *dev, int phy_addr) -{ - s16 data; - - if (au1000_debug > 4) - printk("smsc_83C185_init\n"); - - /* Stop auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); - - /* Set advertisement to 10/100 and Half/Full duplex - * (full capabilities) */ - data = mdio_read(dev, phy_addr, MII_ANADV); - data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; - mdio_write(dev, phy_addr, MII_ANADV, data); - - /* Restart auto-negotiation */ - data = mdio_read(dev, phy_addr, MII_CONTROL); - data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; - - mdio_write(dev, phy_addr, MII_CONTROL, data); - - if (au1000_debug > 4) dump_mii(dev, phy_addr); - return 0; -} - -int -smsc_83C185_reset (struct net_device *dev, int phy_addr) -{ - s16 mii_control, timeout; - - if (au1000_debug > 4) - printk("smsc_83C185_reset\n"); - - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); - mdelay(1); - for (timeout = 100; timeout > 0; --timeout) { - mii_control = mdio_read(dev, phy_addr, MII_CONTROL); - if ((mii_control & MII_CNTL_RESET) == 0) - break; - mdelay(1); - } - if (mii_control & MII_CNTL_RESET) { - printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); - return -1; - } - return 0; -} - -int -smsc_83C185_status (struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - u16 mii_data; - struct au1000_private *aup; - - if (!dev) { - printk(KERN_ERR "smsc_83C185_status error: NULL dev\n"); - return -1; - } - - aup = (struct au1000_private *) dev->priv; - mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); - - if (mii_data & MII_STAT_LINK) { - *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, 0x1f); - if (mii_data & (1<<3)) { - if (mii_data & (1<<4)) { - *speed = IF_PORT_100BASEFX; - dev->if_port = IF_PORT_100BASEFX; - } - else { - *speed = IF_PORT_100BASETX; - dev->if_port = IF_PORT_100BASETX; - } - } - else { - *speed = IF_PORT_10BASET; - dev->if_port = IF_PORT_10BASET; - } - } - else { - *link = 0; - *speed = 0; - dev->if_port = IF_PORT_UNKNOWN; - } - return 0; -} - - -#ifdef CONFIG_MIPS_BOSPORUS -int stub_init(struct net_device *dev, int phy_addr) -{ - //printk("PHY stub_init\n"); - return 0; -} - -int stub_reset(struct net_device *dev, int phy_addr) -{ - //printk("PHY stub_reset\n"); - return 0; -} - -int -stub_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) -{ - //printk("PHY stub_status\n"); - *link = 1; - /* hmmm, revisit */ - *speed = IF_PORT_100BASEFX; - dev->if_port = IF_PORT_100BASEFX; - return 0; -} -#endif - -struct phy_ops bcm_5201_ops = { - bcm_5201_init, - bcm_5201_reset, - bcm_5201_status, -}; - -struct phy_ops am79c874_ops = { - am79c874_init, - am79c874_reset, - am79c874_status, -}; - -struct phy_ops am79c901_ops = { - am79c901_init, - am79c901_reset, - am79c901_status, -}; - -struct phy_ops lsi_80227_ops = { - lsi_80227_init, - lsi_80227_reset, - lsi_80227_status, -}; - -struct phy_ops lxt971a_ops = { - lxt971a_init, - lxt971a_reset, - lxt971a_status, -}; +/* static PHY setup + * + * most boards PHY setup should be detectable properly with the + * autodetection algorithm in mii_probe(), but in some cases (e.g. if + * you have a switch attached, or want to use the PHY's interrupt + * notification capabilities) you can provide a static PHY + * configuration here + * + * IRQs may only be set, if a PHY address was configured + * If a PHY address is given, also a bus id is required to be set + * + * ps: make sure the used irqs are configured properly in the board + * specific irq-map + */ -struct phy_ops ks8995m_ops = { - ks8995m_init, - ks8995m_reset, - ks8995m_status, -}; +#if defined(CONFIG_MIPS_BOSPORUS) +/* + * Micrel/Kendin 5 port switch attached to MAC0, + * MAC0 is associated with PHY address 5 (== WAN port) + * MAC1 is not associated with any PHY, since it's connected directly + * to the switch. + * no interrupts are used + */ +# define AU1XXX_PHY_STATIC_CONFIG -struct phy_ops smsc_83C185_ops = { - smsc_83C185_init, - smsc_83C185_reset, - smsc_83C185_status, -}; +# define AU1XXX_PHY0_ADDR 5 +# define AU1XXX_PHY0_BUSID 0 +# undef AU1XXX_PHY0_IRQ -#ifdef CONFIG_MIPS_BOSPORUS -struct phy_ops stub_ops = { - stub_init, - stub_reset, - stub_status, -}; +# undef AU1XXX_PHY1_ADDR +# undef AU1XXX_PHY1_BUSID +# undef AU1XXX_PHY1_IRQ #endif -static struct mii_chip_info { - const char * name; - u16 phy_id0; - u16 phy_id1; - struct phy_ops *phy_ops; - int dual_phy; -} mii_chip_table[] = { - {"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0}, - {"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0}, - {"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1}, - {"NS DP83847 PHY", 0x2000, 0x5c30, &bcm_5201_ops ,0}, - {"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0}, - {"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0}, - {"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0}, - {"Intel LXT971A Dual Speed PHY",0x0013,0x78e2, &lxt971a_ops,0}, - {"Kendin KS8995M 10/100 BaseT PHY",0x0022,0x1450, &ks8995m_ops,0}, - {"SMSC LAN83C185 10/100 BaseT PHY",0x0007,0xc0a3, &smsc_83C185_ops,0}, -#ifdef CONFIG_MIPS_BOSPORUS - {"Stub", 0x1234, 0x5678, &stub_ops }, +#if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0) +# error MAC0-associated PHY attached 2nd MACs MII bus not supported yet #endif - {0,}, -}; -static int mdio_read(struct net_device *dev, int phy_id, int reg) +/* + * MII operations + */ +static int mdio_read(struct net_device *dev, int phy_addr, int reg) { struct au1000_private *aup = (struct au1000_private *) dev->priv; - volatile u32 *mii_control_reg; - volatile u32 *mii_data_reg; + volatile u32 *const mii_control_reg = &aup->mac->mii_control; + volatile u32 *const mii_data_reg = &aup->mac->mii_data; u32 timedout = 20; u32 mii_control; - #ifdef CONFIG_BCM5222_DUAL_PHY - /* First time we probe, it's for the mac0 phy. - * Since we haven't determined yet that we have a dual phy, - * aup->mii->mii_control_reg won't be setup and we'll - * default to the else statement. - * By the time we probe for the mac1 phy, the mii_control_reg - * will be setup to be the address of the mac0 phy control since - * both phys are controlled through mac0. - */ - if (aup->mii && aup->mii->mii_control_reg) { - mii_control_reg = aup->mii->mii_control_reg; - mii_data_reg = aup->mii->mii_data_reg; - } - else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { - /* assume both phys are controlled through mac0 */ - mii_control_reg = au_macs[0]->mii->mii_control_reg; - mii_data_reg = au_macs[0]->mii->mii_data_reg; - } - else - #endif - { - /* default control and data reg addresses */ - mii_control_reg = &aup->mac->mii_control; - mii_data_reg = &aup->mac->mii_data; - } - while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { @@ -835,7 +215,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg) } mii_control = MAC_SET_MII_SELECT_REG(reg) | - MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_READ; + MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ; *mii_control_reg = mii_control; @@ -851,32 +231,14 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg) return (int)*mii_data_reg; } -static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value) +static void mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value) { struct au1000_private *aup = (struct au1000_private *) dev->priv; - volatile u32 *mii_control_reg; - volatile u32 *mii_data_reg; + volatile u32 *const mii_control_reg = &aup->mac->mii_control; + volatile u32 *const mii_data_reg = &aup->mac->mii_data; u32 timedout = 20; u32 mii_control; - #ifdef CONFIG_BCM5222_DUAL_PHY - if (aup->mii && aup->mii->mii_control_reg) { - mii_control_reg = aup->mii->mii_control_reg; - mii_data_reg = aup->mii->mii_data_reg; - } - else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { - /* assume both phys are controlled through mac0 */ - mii_control_reg = au_macs[0]->mii->mii_control_reg; - mii_data_reg = au_macs[0]->mii->mii_data_reg; - } - else - #endif - { - /* default control and data reg addresses */ - mii_control_reg = &aup->mac->mii_control; - mii_data_reg = &aup->mac->mii_data; - } - while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { @@ -887,165 +249,145 @@ static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value) } mii_control = MAC_SET_MII_SELECT_REG(reg) | - MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_WRITE; + MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE; *mii_data_reg = value; *mii_control_reg = mii_control; } +static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) +{ + /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does + * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */ + struct net_device *const dev = bus->priv; + + enable_mac(dev, 0); /* make sure the MAC associated with this + * mii_bus is enabled */ + return mdio_read(dev, phy_addr, regnum); +} -static void dump_mii(struct net_device *dev, int phy_id) +static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, + u16 value) { - int i, val; + struct net_device *const dev = bus->priv; - for (i = 0; i < 7; i++) { - if ((val = mdio_read(dev, phy_id, i)) >= 0) - printk("%s: MII Reg %d=%x\n", dev->name, i, val); - } - for (i = 16; i < 25; i++) { - if ((val = mdio_read(dev, phy_id, i)) >= 0) - printk("%s: MII Reg %d=%x\n", dev->name, i, val); - } + enable_mac(dev, 0); /* make sure the MAC associated with this + * mii_bus is enabled */ + mdio_write(dev, phy_addr, regnum, value); + return 0; } -static int mii_probe (struct net_device * dev) +static int mdiobus_reset(struct mii_bus *bus) { - struct au1000_private *aup = (struct au1000_private *) dev->priv; - int phy_addr; -#ifdef CONFIG_MIPS_BOSPORUS - int phy_found=0; -#endif + struct net_device *const dev = bus->priv; - /* search for total of 32 possible mii phy addresses */ - for (phy_addr = 0; phy_addr < 32; phy_addr++) { - u16 mii_status; - u16 phy_id0, phy_id1; - int i; + enable_mac(dev, 0); /* make sure the MAC associated with this + * mii_bus is enabled */ + return 0; +} - #ifdef CONFIG_BCM5222_DUAL_PHY - /* Mask the already found phy, try next one */ - if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { - if (au_macs[0]->phy_addr == phy_addr) - continue; - } - #endif - - mii_status = mdio_read(dev, phy_addr, MII_STATUS); - if (mii_status == 0xffff || mii_status == 0x0000) - /* the mii is not accessable, try next one */ - continue; - - phy_id0 = mdio_read(dev, phy_addr, MII_PHY_ID0); - phy_id1 = mdio_read(dev, phy_addr, MII_PHY_ID1); - - /* search our mii table for the current mii */ - for (i = 0; mii_chip_table[i].phy_id1; i++) { - if (phy_id0 == mii_chip_table[i].phy_id0 && - phy_id1 == mii_chip_table[i].phy_id1) { - struct mii_phy * mii_phy = aup->mii; - - printk(KERN_INFO "%s: %s at phy address %d\n", - dev->name, mii_chip_table[i].name, - phy_addr); -#ifdef CONFIG_MIPS_BOSPORUS - phy_found = 1; -#endif - mii_phy->chip_info = mii_chip_table+i; - aup->phy_addr = phy_addr; - aup->want_autoneg = 1; - aup->phy_ops = mii_chip_table[i].phy_ops; - aup->phy_ops->phy_init(dev,phy_addr); - - // Check for dual-phy and then store required - // values and set indicators. We need to do - // this now since mdio_{read,write} need the - // control and data register addresses. - #ifdef CONFIG_BCM5222_DUAL_PHY - if ( mii_chip_table[i].dual_phy) { - - /* assume both phys are controlled - * through MAC0. Board specific? */ - - /* sanity check */ - if (!au_macs[0] || !au_macs[0]->mii) - return -1; - aup->mii->mii_control_reg = (u32 *) - &au_macs[0]->mac->mii_control; - aup->mii->mii_data_reg = (u32 *) - &au_macs[0]->mac->mii_data; - } - #endif - goto found; - } +static int mii_probe (struct net_device *dev) +{ + struct au1000_private *const aup = (struct au1000_private *) dev->priv; + struct phy_device *phydev = NULL; + +#if defined(AU1XXX_PHY_STATIC_CONFIG) + BUG_ON(aup->mac_id < 0 || aup->mac_id > 1); + + if(aup->mac_id == 0) { /* get PHY0 */ +# if defined(AU1XXX_PHY0_ADDR) + phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus.phy_map[AU1XXX_PHY0_ADDR]; +# else + printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", + dev->name); + return 0; +# endif /* defined(AU1XXX_PHY0_ADDR) */ + } else if (aup->mac_id == 1) { /* get PHY1 */ +# if defined(AU1XXX_PHY1_ADDR) + phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus.phy_map[AU1XXX_PHY1_ADDR]; +# else + printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", + dev->name); + return 0; +# endif /* defined(AU1XXX_PHY1_ADDR) */ + } + +#else /* defined(AU1XXX_PHY_STATIC_CONFIG) */ + int phy_addr; + + /* find the first (lowest address) PHY on the current MAC's MII bus */ + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) + if (aup->mii_bus.phy_map[phy_addr]) { + phydev = aup->mii_bus.phy_map[phy_addr]; +# if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR) + break; /* break out with first one found */ +# endif } - } -found: - -#ifdef CONFIG_MIPS_BOSPORUS - /* This is a workaround for the Micrel/Kendin 5 port switch - The second MAC doesn't see a PHY connected... so we need to - trick it into thinking we have one. - - If this kernel is run on another Au1500 development board - the stub will be found as well as the actual PHY. However, - the last found PHY will be used... usually at Addr 31 (Db1500). - */ - if ( (!phy_found) ) - { - u16 phy_id0, phy_id1; - int i; - phy_id0 = 0x1234; - phy_id1 = 0x5678; - - /* search our mii table for the current mii */ - for (i = 0; mii_chip_table[i].phy_id1; i++) { - if (phy_id0 == mii_chip_table[i].phy_id0 && - phy_id1 == mii_chip_table[i].phy_id1) { - struct mii_phy * mii_phy; - - printk(KERN_INFO "%s: %s at phy address %d\n", - dev->name, mii_chip_table[i].name, - phy_addr); - mii_phy = kmalloc(sizeof(struct mii_phy), - GFP_KERNEL); - if (mii_phy) { - mii_phy->chip_info = mii_chip_table+i; - aup->phy_addr = phy_addr; - mii_phy->next = aup->mii; - aup->phy_ops = - mii_chip_table[i].phy_ops; - aup->mii = mii_phy; - aup->phy_ops->phy_init(dev,phy_addr); - } else { - printk(KERN_ERR "%s: out of memory\n", - dev->name); - return -1; - } - mii_phy->chip_info = mii_chip_table+i; - aup->phy_addr = phy_addr; - aup->phy_ops = mii_chip_table[i].phy_ops; - aup->phy_ops->phy_init(dev,phy_addr); - break; - } +# if defined(AU1XXX_PHY1_SEARCH_ON_MAC0) + /* try harder to find a PHY */ + if (!phydev && (aup->mac_id == 1)) { + /* no PHY found, maybe we have a dual PHY? */ + printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, " + "let's see if it's attached to MAC0...\n"); + + BUG_ON(!au_macs[0]); + + /* find the first (lowest address) non-attached PHY on + * the MAC0 MII bus */ + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { + struct phy_device *const tmp_phydev = + au_macs[0]->mii_bus.phy_map[phy_addr]; + + if (!tmp_phydev) + continue; /* no PHY here... */ + + if (tmp_phydev->attached_dev) + continue; /* already claimed by MAC0 */ + + phydev = tmp_phydev; + break; /* found it */ } } - if (aup->mac_id == 0) { - /* the Bosporus phy responds to addresses 0-5 but - * 5 is the correct one. - */ - aup->phy_addr = 5; - } -#endif +# endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */ - if (aup->mii->chip_info == NULL) { - printk(KERN_ERR "%s: Au1x No known MII transceivers found!\n", - dev->name); +#endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */ + if (!phydev) { + printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name); return -1; } - printk(KERN_INFO "%s: Using %s as default\n", - dev->name, aup->mii->chip_info->name); + /* now we are supposed to have a proper phydev, to attach to... */ + BUG_ON(!phydev); + BUG_ON(phydev->attached_dev); + + phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0); + + if (IS_ERR(phydev)) { + printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); + return PTR_ERR(phydev); + } + + /* mask with MAC supported features */ + phydev->supported &= (SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full + | SUPPORTED_Autoneg + /* | SUPPORTED_Pause | SUPPORTED_Asym_Pause */ + | SUPPORTED_MII + | SUPPORTED_TP); + + phydev->advertising = phydev->supported; + + aup->old_link = 0; + aup->old_speed = 0; + aup->old_duplex = -1; + aup->phy_dev = phydev; + + printk(KERN_INFO "%s: attached PHY driver [%s] " + "(mii_bus:phy_addr=%s, irq=%d)\n", + dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq); return 0; } @@ -1097,35 +439,38 @@ static void hard_stop(struct net_device *dev) au_sync_delay(10); } - -static void reset_mac(struct net_device *dev) +static void enable_mac(struct net_device *dev, int force_reset) { - int i; - u32 flags; + unsigned long flags; struct au1000_private *aup = (struct au1000_private *) dev->priv; - if (au1000_debug > 4) - printk(KERN_INFO "%s: reset mac, aup %x\n", - dev->name, (unsigned)aup); - spin_lock_irqsave(&aup->lock, flags); - if (aup->timer.function == &au1000_timer) {/* check if timer initted */ - del_timer(&aup->timer); - } - hard_stop(dev); - #ifdef CONFIG_BCM5222_DUAL_PHY - if (aup->mac_id != 0) { - #endif - /* If BCM5222, we can't leave MAC0 in reset because then - * we can't access the dual phy for ETH1 */ + if(force_reset || (!aup->mac_enabled)) { *aup->enable = MAC_EN_CLOCK_ENABLE; au_sync_delay(2); - *aup->enable = 0; + *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 + | MAC_EN_CLOCK_ENABLE); au_sync_delay(2); - #ifdef CONFIG_BCM5222_DUAL_PHY + + aup->mac_enabled = 1; } - #endif + + spin_unlock_irqrestore(&aup->lock, flags); +} + +static void reset_mac_unlocked(struct net_device *dev) +{ + struct au1000_private *const aup = (struct au1000_private *) dev->priv; + int i; + + hard_stop(dev); + + *aup->enable = MAC_EN_CLOCK_ENABLE; + au_sync_delay(2); + *aup->enable = 0; + au_sync_delay(2); + aup->tx_full = 0; for (i = 0; i < NUM_RX_DMA; i++) { /* reset control bits */ @@ -1135,9 +480,26 @@ static void reset_mac(struct net_device *dev) /* reset control bits */ aup->tx_dma_ring[i]->buff_stat &= ~0xf; } - spin_unlock_irqrestore(&aup->lock, flags); + + aup->mac_enabled = 0; + } +static void reset_mac(struct net_device *dev) +{ + struct au1000_private *const aup = (struct au1000_private *) dev->priv; + unsigned long flags; + + if (au1000_debug > 4) + printk(KERN_INFO "%s: reset mac, aup %x\n", + dev->name, (unsigned)aup); + + spin_lock_irqsave(&aup->lock, flags); + + reset_mac_unlocked (dev); + + spin_unlock_irqrestore(&aup->lock, flags); +} /* * Setup the receive and transmit "rings". These pointers are the addresses @@ -1208,178 +570,31 @@ static int __init au1000_init_module(void) return 0; } -static int au1000_setup_aneg(struct net_device *dev, u32 advertise) -{ - struct au1000_private *aup = (struct au1000_private *)dev->priv; - u16 ctl, adv; - - /* Setup standard advertise */ - adv = mdio_read(dev, aup->phy_addr, MII_ADVERTISE); - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); - if (advertise & ADVERTISED_10baseT_Half) - adv |= ADVERTISE_10HALF; - if (advertise & ADVERTISED_10baseT_Full) - adv |= ADVERTISE_10FULL; - if (advertise & ADVERTISED_100baseT_Half) - adv |= ADVERTISE_100HALF; - if (advertise & ADVERTISED_100baseT_Full) - adv |= ADVERTISE_100FULL; - mdio_write(dev, aup->phy_addr, MII_ADVERTISE, adv); - - /* Start/Restart aneg */ - ctl = mdio_read(dev, aup->phy_addr, MII_BMCR); - ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); - mdio_write(dev, aup->phy_addr, MII_BMCR, ctl); - - return 0; -} +/* + * ethtool operations + */ -static int au1000_setup_forced(struct net_device *dev, int speed, int fd) +static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct au1000_private *aup = (struct au1000_private *)dev->priv; - u16 ctl; - - ctl = mdio_read(dev, aup->phy_addr, MII_BMCR); - ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE); - - /* First reset the PHY */ - mdio_write(dev, aup->phy_addr, MII_BMCR, ctl | BMCR_RESET); - - /* Select speed & duplex */ - switch (speed) { - case SPEED_10: - break; - case SPEED_100: - ctl |= BMCR_SPEED100; - break; - case SPEED_1000: - default: - return -EINVAL; - } - if (fd == DUPLEX_FULL) - ctl |= BMCR_FULLDPLX; - mdio_write(dev, aup->phy_addr, MII_BMCR, ctl); - - return 0; -} - -static void -au1000_start_link(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct au1000_private *aup = (struct au1000_private *)dev->priv; - u32 advertise; - int autoneg; - int forced_speed; - int forced_duplex; - - /* Default advertise */ - advertise = GENMII_DEFAULT_ADVERTISE; - autoneg = aup->want_autoneg; - forced_speed = SPEED_100; - forced_duplex = DUPLEX_FULL; - - /* Setup link parameters */ - if (cmd) { - if (cmd->autoneg == AUTONEG_ENABLE) { - advertise = cmd->advertising; - autoneg = 1; - } else { - autoneg = 0; - - forced_speed = cmd->speed; - forced_duplex = cmd->duplex; - } - } + if (aup->phy_dev) + return phy_ethtool_gset(aup->phy_dev, cmd); - /* Configure PHY & start aneg */ - aup->want_autoneg = autoneg; - if (autoneg) - au1000_setup_aneg(dev, advertise); - else - au1000_setup_forced(dev, forced_speed, forced_duplex); - mod_timer(&aup->timer, jiffies + HZ); + return -EINVAL; } -static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct au1000_private *aup = (struct au1000_private *)dev->priv; - u16 link, speed; - - cmd->supported = GENMII_DEFAULT_FEATURES; - cmd->advertising = GENMII_DEFAULT_ADVERTISE; - cmd->port = PORT_MII; - cmd->transceiver = XCVR_EXTERNAL; - cmd->phy_address = aup->phy_addr; - spin_lock_irq(&aup->lock); - cmd->autoneg = aup->want_autoneg; - aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed); - if ((speed == IF_PORT_100BASETX) || (speed == IF_PORT_100BASEFX)) - cmd->speed = SPEED_100; - else if (speed == IF_PORT_10BASET) - cmd->speed = SPEED_10; - if (link && (dev->if_port == IF_PORT_100BASEFX)) - cmd->duplex = DUPLEX_FULL; - else - cmd->duplex = DUPLEX_HALF; - spin_unlock_irq(&aup->lock); - return 0; -} -static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct au1000_private *aup = (struct au1000_private *)dev->priv; - unsigned long features = GENMII_DEFAULT_FEATURES; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) - return -EINVAL; - if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0) - return -EINVAL; - if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) - return -EINVAL; - if (cmd->autoneg == AUTONEG_DISABLE) - switch (cmd->speed) { - case SPEED_10: - if (cmd->duplex == DUPLEX_HALF && - (features & SUPPORTED_10baseT_Half) == 0) - return -EINVAL; - if (cmd->duplex == DUPLEX_FULL && - (features & SUPPORTED_10baseT_Full) == 0) - return -EINVAL; - break; - case SPEED_100: - if (cmd->duplex == DUPLEX_HALF && - (features & SUPPORTED_100baseT_Half) == 0) - return -EINVAL; - if (cmd->duplex == DUPLEX_FULL && - (features & SUPPORTED_100baseT_Full) == 0) - return -EINVAL; - break; - default: - return -EINVAL; - } - else if ((features & SUPPORTED_Autoneg) == 0) - return -EINVAL; - - spin_lock_irq(&aup->lock); - au1000_start_link(dev, cmd); - spin_unlock_irq(&aup->lock); - return 0; -} + if (!capable(CAP_NET_ADMIN)) + return -EPERM; -static int au1000_nway_reset(struct net_device *dev) -{ - struct au1000_private *aup = (struct au1000_private *)dev->priv; + if (aup->phy_dev) + return phy_ethtool_sset(aup->phy_dev, cmd); - if (!aup->want_autoneg) - return -EINVAL; - spin_lock_irq(&aup->lock); - au1000_start_link(dev, NULL); - spin_unlock_irq(&aup->lock); - return 0; + return -EINVAL; } static void @@ -1394,17 +609,11 @@ au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) info->regdump_len = 0; } -static u32 au1000_get_link(struct net_device *dev) -{ - return netif_carrier_ok(dev); -} - static struct ethtool_ops au1000_ethtool_ops = { .get_settings = au1000_get_settings, .set_settings = au1000_set_settings, .get_drvinfo = au1000_get_drvinfo, - .nway_reset = au1000_nway_reset, - .get_link = au1000_get_link + .get_link = ethtool_op_get_link, }; static struct net_device * au1000_probe(int port_num) @@ -1499,23 +708,31 @@ static struct net_device * au1000_probe(int port_num) memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); dev->dev_addr[5] += port_num; - /* Bring the device out of reset, otherwise probing the MII will hang */ - *aup->enable = MAC_EN_CLOCK_ENABLE; - au_sync_delay(2); - *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | - MAC_EN_CLOCK_ENABLE; - au_sync_delay(2); - - aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL); - if (!aup->mii) { - printk(KERN_ERR "%s: out of memory\n", dev->name); - goto err_out; - } - aup->mii->next = NULL; - aup->mii->chip_info = NULL; - aup->mii->status = 0; - aup->mii->mii_control_reg = 0; - aup->mii->mii_data_reg = 0; + *aup->enable = 0; + aup->mac_enabled = 0; + + aup->mii_bus.priv = dev; + aup->mii_bus.read = mdiobus_read; + aup->mii_bus.write = mdiobus_write; + aup->mii_bus.reset = mdiobus_reset; + aup->mii_bus.name = "au1000_eth_mii"; + aup->mii_bus.id = aup->mac_id; + aup->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); + for(i = 0; i < PHY_MAX_ADDR; ++i) + aup->mii_bus.irq[i] = PHY_POLL; + + /* if known, set corresponding PHY IRQs */ +#if defined(AU1XXX_PHY_STATIC_CONFIG) +# if defined(AU1XXX_PHY0_IRQ) + if (AU1XXX_PHY0_BUSID == aup->mii_bus.id) + aup->mii_bus.irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ; +# endif +# if defined(AU1XXX_PHY1_IRQ) + if (AU1XXX_PHY1_BUSID == aup->mii_bus.id) + aup->mii_bus.irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ; +# endif +#endif + mdiobus_register(&aup->mii_bus); if (mii_probe(dev) != 0) { goto err_out; @@ -1561,7 +778,6 @@ static struct net_device * au1000_probe(int port_num) dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &au1000_ioctl; SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); - dev->set_config = &au1000_set_config; dev->tx_timeout = au1000_tx_timeout; dev->watchdog_timeo = ETH_TX_TIMEOUT; @@ -1577,7 +793,7 @@ err_out: /* here we should have a valid dev plus aup-> register addresses * so we can reset the mac properly.*/ reset_mac(dev); - kfree(aup->mii); + for (i = 0; i < NUM_RX_DMA; i++) { if (aup->rx_db_inuse[i]) ReleaseDB(aup, aup->rx_db_inuse[i]); @@ -1610,19 +826,14 @@ static int au1000_init(struct net_device *dev) u32 flags; int i; u32 control; - u16 link, speed; if (au1000_debug > 4) printk("%s: au1000_init\n", dev->name); - spin_lock_irqsave(&aup->lock, flags); - /* bring the device out of reset */ - *aup->enable = MAC_EN_CLOCK_ENABLE; - au_sync_delay(2); - *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | - MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE; - au_sync_delay(20); + enable_mac(dev, 1); + + spin_lock_irqsave(&aup->lock, flags); aup->mac->control = 0; aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2; @@ -1638,12 +849,16 @@ static int au1000_init(struct net_device *dev) } au_sync(); - aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed); - control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE; + control = MAC_RX_ENABLE | MAC_TX_ENABLE; #ifndef CONFIG_CPU_LITTLE_ENDIAN control |= MAC_BIG_ENDIAN; #endif - if (link && (dev->if_port == IF_PORT_100BASEFX)) { + if (aup->phy_dev) { + if (aup->phy_dev->link && (DUPLEX_FULL == aup->phy_dev->duplex)) + control |= MAC_FULL_DUPLEX; + else + control |= MAC_DISABLE_RX_OWN; + } else { /* PHY-less op, assume full-duplex */ control |= MAC_FULL_DUPLEX; } @@ -1655,57 +870,84 @@ static int au1000_init(struct net_device *dev) return 0; } -static void au1000_timer(unsigned long data) +static void +au1000_adjust_link(struct net_device *dev) { - struct net_device *dev = (struct net_device *)data; struct au1000_private *aup = (struct au1000_private *) dev->priv; - unsigned char if_port; - u16 link, speed; + struct phy_device *phydev = aup->phy_dev; + unsigned long flags; - if (!dev) { - /* fatal error, don't restart the timer */ - printk(KERN_ERR "au1000_timer error: NULL dev\n"); - return; - } + int status_change = 0; - if_port = dev->if_port; - if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) { - if (link) { - if (!netif_carrier_ok(dev)) { - netif_carrier_on(dev); - printk(KERN_INFO "%s: link up\n", dev->name); - } - } - else { - if (netif_carrier_ok(dev)) { - netif_carrier_off(dev); - dev->if_port = 0; - printk(KERN_INFO "%s: link down\n", dev->name); - } + BUG_ON(!aup->phy_dev); + + spin_lock_irqsave(&aup->lock, flags); + + if (phydev->link && (aup->old_speed != phydev->speed)) { + // speed changed + + switch(phydev->speed) { + case SPEED_10: + case SPEED_100: + break; + default: + printk(KERN_WARNING + "%s: Speed (%d) is not 10/100 ???\n", + dev->name, phydev->speed); + break; } + + aup->old_speed = phydev->speed; + + status_change = 1; } - if (link && (dev->if_port != if_port) && - (dev->if_port != IF_PORT_UNKNOWN)) { + if (phydev->link && (aup->old_duplex != phydev->duplex)) { + // duplex mode changed + + /* switching duplex mode requires to disable rx and tx! */ hard_stop(dev); - if (dev->if_port == IF_PORT_100BASEFX) { - printk(KERN_INFO "%s: going to full duplex\n", - dev->name); - aup->mac->control |= MAC_FULL_DUPLEX; - au_sync_delay(1); - } - else { - aup->mac->control &= ~MAC_FULL_DUPLEX; - au_sync_delay(1); - } + + if (DUPLEX_FULL == phydev->duplex) + aup->mac->control = ((aup->mac->control + | MAC_FULL_DUPLEX) + & ~MAC_DISABLE_RX_OWN); + else + aup->mac->control = ((aup->mac->control + & ~MAC_FULL_DUPLEX) + | MAC_DISABLE_RX_OWN); + au_sync_delay(1); + enable_rx_tx(dev); + aup->old_duplex = phydev->duplex; + + status_change = 1; + } + + if(phydev->link != aup->old_link) { + // link state changed + + if (phydev->link) // link went up + netif_schedule(dev); + else { // link went down + aup->old_speed = 0; + aup->old_duplex = -1; + } + + aup->old_link = phydev->link; + status_change = 1; } - aup->timer.expires = RUN_AT((1*HZ)); - aup->timer.data = (unsigned long)dev; - aup->timer.function = &au1000_timer; /* timer handler */ - add_timer(&aup->timer); + spin_unlock_irqrestore(&aup->lock, flags); + if (status_change) { + if (phydev->link) + printk(KERN_INFO "%s: link up (%d/%s)\n", + dev->name, phydev->speed, + DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); + else + printk(KERN_INFO "%s: link down\n", dev->name); + } } static int au1000_open(struct net_device *dev) @@ -1716,25 +958,26 @@ static int au1000_open(struct net_device *dev) if (au1000_debug > 4) printk("%s: open: dev=%p\n", dev->name, dev); + if ((retval = request_irq(dev->irq, &au1000_interrupt, 0, + dev->name, dev))) { + printk(KERN_ERR "%s: unable to get IRQ %d\n", + dev->name, dev->irq); + return retval; + } + if ((retval = au1000_init(dev))) { printk(KERN_ERR "%s: error in au1000_init\n", dev->name); free_irq(dev->irq, dev); return retval; } - netif_start_queue(dev); - if ((retval = request_irq(dev->irq, &au1000_interrupt, 0, - dev->name, dev))) { - printk(KERN_ERR "%s: unable to get IRQ %d\n", - dev->name, dev->irq); - return retval; + if (aup->phy_dev) { + /* cause the PHY state machine to schedule a link state check */ + aup->phy_dev->state = PHY_CHANGELINK; + phy_start(aup->phy_dev); } - init_timer(&aup->timer); /* used in ioctl() */ - aup->timer.expires = RUN_AT((3*HZ)); - aup->timer.data = (unsigned long)dev; - aup->timer.function = &au1000_timer; /* timer handler */ - add_timer(&aup->timer); + netif_start_queue(dev); if (au1000_debug > 4) printk("%s: open: Initialization done.\n", dev->name); @@ -1744,16 +987,19 @@ static int au1000_open(struct net_device *dev) static int au1000_close(struct net_device *dev) { - u32 flags; - struct au1000_private *aup = (struct au1000_private *) dev->priv; + unsigned long flags; + struct au1000_private *const aup = (struct au1000_private *) dev->priv; if (au1000_debug > 4) printk("%s: close: dev=%p\n", dev->name, dev); - reset_mac(dev); + if (aup->phy_dev) + phy_stop(aup->phy_dev); spin_lock_irqsave(&aup->lock, flags); - + + reset_mac_unlocked (dev); + /* stop the device */ netif_stop_queue(dev); @@ -1775,7 +1021,6 @@ static void __exit au1000_cleanup_module(void) if (dev) { aup = (struct au1000_private *) dev->priv; unregister_netdev(dev); - kfree(aup->mii); for (j = 0; j < NUM_RX_DMA; j++) if (aup->rx_db_inuse[j]) ReleaseDB(aup, aup->rx_db_inuse[j]); @@ -1798,7 +1043,7 @@ static void update_tx_stats(struct net_device *dev, u32 status) struct net_device_stats *ps = &aup->stats; if (status & TX_FRAME_ABORTED) { - if (dev->if_port == IF_PORT_100BASEFX) { + if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) { if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { /* any other tx errors are only valid * in half duplex mode */ @@ -2072,126 +1317,15 @@ static void set_rx_mode(struct net_device *dev) } } - static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct au1000_private *aup = (struct au1000_private *)dev->priv; - u16 *data = (u16 *)&rq->ifr_ifru; - - switch(cmd) { - case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ - case SIOCGMIIPHY: - if (!netif_running(dev)) return -EINVAL; - data[0] = aup->phy_addr; - case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ - case SIOCGMIIREG: - data[3] = mdio_read(dev, data[0], data[1]); - return 0; - case SIOCDEVPRIVATE+2: /* Write the specified MII register */ - case SIOCSMIIREG: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - mdio_write(dev, data[0], data[1],data[2]); - return 0; - default: - return -EOPNOTSUPP; - } - -} - - -static int au1000_set_config(struct net_device *dev, struct ifmap *map) -{ - struct au1000_private *aup = (struct au1000_private *) dev->priv; - u16 control; - if (au1000_debug > 4) { - printk("%s: set_config called: dev->if_port %d map->port %x\n", - dev->name, dev->if_port, map->port); - } + if (!netif_running(dev)) return -EINVAL; - switch(map->port){ - case IF_PORT_UNKNOWN: /* use auto here */ - printk(KERN_INFO "%s: config phy for aneg\n", - dev->name); - dev->if_port = map->port; - /* Link Down: the timer will bring it up */ - netif_carrier_off(dev); - - /* read current control */ - control = mdio_read(dev, aup->phy_addr, MII_CONTROL); - control &= ~(MII_CNTL_FDX | MII_CNTL_F100); - - /* enable auto negotiation and reset the negotiation */ - mdio_write(dev, aup->phy_addr, MII_CONTROL, - control | MII_CNTL_AUTO | - MII_CNTL_RST_AUTO); + if (!aup->phy_dev) return -EINVAL; // PHY not controllable - break; - - case IF_PORT_10BASET: /* 10BaseT */ - printk(KERN_INFO "%s: config phy for 10BaseT\n", - dev->name); - dev->if_port = map->port; - - /* Link Down: the timer will bring it up */ - netif_carrier_off(dev); - - /* set Speed to 10Mbps, Half Duplex */ - control = mdio_read(dev, aup->phy_addr, MII_CONTROL); - control &= ~(MII_CNTL_F100 | MII_CNTL_AUTO | - MII_CNTL_FDX); - - /* disable auto negotiation and force 10M/HD mode*/ - mdio_write(dev, aup->phy_addr, MII_CONTROL, control); - break; - - case IF_PORT_100BASET: /* 100BaseT */ - case IF_PORT_100BASETX: /* 100BaseTx */ - printk(KERN_INFO "%s: config phy for 100BaseTX\n", - dev->name); - dev->if_port = map->port; - - /* Link Down: the timer will bring it up */ - netif_carrier_off(dev); - - /* set Speed to 100Mbps, Half Duplex */ - /* disable auto negotiation and enable 100MBit Mode */ - control = mdio_read(dev, aup->phy_addr, MII_CONTROL); - control &= ~(MII_CNTL_AUTO | MII_CNTL_FDX); - control |= MII_CNTL_F100; - mdio_write(dev, aup->phy_addr, MII_CONTROL, control); - break; - - case IF_PORT_100BASEFX: /* 100BaseFx */ - printk(KERN_INFO "%s: config phy for 100BaseFX\n", - dev->name); - dev->if_port = map->port; - - /* Link Down: the timer will bring it up */ - netif_carrier_off(dev); - - /* set Speed to 100Mbps, Full Duplex */ - /* disable auto negotiation and enable 100MBit Mode */ - control = mdio_read(dev, aup->phy_addr, MII_CONTROL); - control &= ~MII_CNTL_AUTO; - control |= MII_CNTL_F100 | MII_CNTL_FDX; - mdio_write(dev, aup->phy_addr, MII_CONTROL, control); - break; - case IF_PORT_10BASE2: /* 10Base2 */ - case IF_PORT_AUI: /* AUI */ - /* These Modes are not supported (are they?)*/ - printk(KERN_ERR "%s: 10Base2/AUI not supported", - dev->name); - return -EOPNOTSUPP; - break; - - default: - printk(KERN_ERR "%s: Invalid media selected", - dev->name); - return -EINVAL; - } - return 0; + return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); } static struct net_device_stats *au1000_get_stats(struct net_device *dev) diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h index 7f9326e39cc..41c2f848d2c 100644 --- a/drivers/net/au1000_eth.h +++ b/drivers/net/au1000_eth.h @@ -40,120 +40,6 @@ #define MULTICAST_FILTER_LIMIT 64 -/* FIXME - * The PHY defines should be in a separate file. - */ - -/* MII register offsets */ -#define MII_CONTROL 0x0000 -#define MII_STATUS 0x0001 -#define MII_PHY_ID0 0x0002 -#define MII_PHY_ID1 0x0003 -#define MII_ANADV 0x0004 -#define MII_ANLPAR 0x0005 -#define MII_AEXP 0x0006 -#define MII_ANEXT 0x0007 -#define MII_LSI_PHY_CONFIG 0x0011 -/* Status register */ -#define MII_LSI_PHY_STAT 0x0012 -#define MII_AMD_PHY_STAT MII_LSI_PHY_STAT -#define MII_INTEL_PHY_STAT 0x0011 - -#define MII_AUX_CNTRL 0x0018 -/* mii registers specific to AMD 79C901 */ -#define MII_STATUS_SUMMARY = 0x0018 - -/* MII Control register bit definitions. */ -#define MII_CNTL_FDX 0x0100 -#define MII_CNTL_RST_AUTO 0x0200 -#define MII_CNTL_ISOLATE 0x0400 -#define MII_CNTL_PWRDWN 0x0800 -#define MII_CNTL_AUTO 0x1000 -#define MII_CNTL_F100 0x2000 -#define MII_CNTL_LPBK 0x4000 -#define MII_CNTL_RESET 0x8000 - -/* MII Status register bit */ -#define MII_STAT_EXT 0x0001 -#define MII_STAT_JAB 0x0002 -#define MII_STAT_LINK 0x0004 -#define MII_STAT_CAN_AUTO 0x0008 -#define MII_STAT_FAULT 0x0010 -#define MII_STAT_AUTO_DONE 0x0020 -#define MII_STAT_CAN_T 0x0800 -#define MII_STAT_CAN_T_FDX 0x1000 -#define MII_STAT_CAN_TX 0x2000 -#define MII_STAT_CAN_TX_FDX 0x4000 -#define MII_STAT_CAN_T4 0x8000 - - -#define MII_ID1_OUI_LO 0xFC00 /* low bits of OUI mask */ -#define MII_ID1_MODEL 0x03F0 /* model number */ -#define MII_ID1_REV 0x000F /* model number */ - -/* MII NWAY Register Bits ... - valid for the ANAR (Auto-Negotiation Advertisement) and - ANLPAR (Auto-Negotiation Link Partner) registers */ -#define MII_NWAY_NODE_SEL 0x001f -#define MII_NWAY_CSMA_CD 0x0001 -#define MII_NWAY_T 0x0020 -#define MII_NWAY_T_FDX 0x0040 -#define MII_NWAY_TX 0x0080 -#define MII_NWAY_TX_FDX 0x0100 -#define MII_NWAY_T4 0x0200 -#define MII_NWAY_PAUSE 0x0400 -#define MII_NWAY_RF 0x2000 /* Remote Fault */ -#define MII_NWAY_ACK 0x4000 /* Remote Acknowledge */ -#define MII_NWAY_NP 0x8000 /* Next Page (Enable) */ - -/* mii stsout register bits */ -#define MII_STSOUT_LINK_FAIL 0x4000 -#define MII_STSOUT_SPD 0x0080 -#define MII_STSOUT_DPLX 0x0040 - -/* mii stsics register bits */ -#define MII_STSICS_SPD 0x8000 -#define MII_STSICS_DPLX 0x4000 -#define MII_STSICS_LINKSTS 0x0001 - -/* mii stssum register bits */ -#define MII_STSSUM_LINK 0x0008 -#define MII_STSSUM_DPLX 0x0004 -#define MII_STSSUM_AUTO 0x0002 -#define MII_STSSUM_SPD 0x0001 - -/* lsi phy status register */ -#define MII_LSI_PHY_STAT_FDX 0x0040 -#define MII_LSI_PHY_STAT_SPD 0x0080 - -/* amd phy status register */ -#define MII_AMD_PHY_STAT_FDX 0x0800 -#define MII_AMD_PHY_STAT_SPD 0x0400 - -/* intel phy status register */ -#define MII_INTEL_PHY_STAT_FDX 0x0200 -#define MII_INTEL_PHY_STAT_SPD 0x4000 - -/* Auxilliary Control/Status Register */ -#define MII_AUX_FDX 0x0001 -#define MII_AUX_100 0x0002 -#define MII_AUX_F100 0x0004 -#define MII_AUX_ANEG 0x0008 - -typedef struct mii_phy { - struct mii_phy * next; - struct mii_chip_info * chip_info; - u16 status; - u32 *mii_control_reg; - u32 *mii_data_reg; -} mii_phy_t; - -struct phy_ops { - int (*phy_init) (struct net_device *, int); - int (*phy_reset) (struct net_device *, int); - int (*phy_status) (struct net_device *, int, u16 *, u16 *); -}; - /* * Data Buffer Descriptor. Data buffers must be aligned on 32 byte * boundary for both, receive and transmit. @@ -200,7 +86,6 @@ typedef struct mac_reg { struct au1000_private { - db_dest_t *pDBfree; db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS]; volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA]; @@ -213,8 +98,15 @@ struct au1000_private { u32 tx_full; int mac_id; - mii_phy_t *mii; - struct phy_ops *phy_ops; + + int mac_enabled; /* whether MAC is currently enabled and running (req. for mdio) */ + + int old_link; /* used by au1000_adjust_link */ + int old_speed; + int old_duplex; + + struct phy_device *phy_dev; + struct mii_bus mii_bus; /* These variables are just for quick access to certain regs addresses. */ volatile mac_reg_t *mac; /* mac registers */ @@ -223,14 +115,6 @@ struct au1000_private { u32 vaddr; /* virtual address of rx/tx buffers */ dma_addr_t dma_addr; /* dma address of rx/tx buffers */ - u8 *hash_table; - u32 hash_mode; - u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ - int phy_addr; /* phy address */ - u32 options; /* User-settable misc. driver options. */ - u32 drv_flags; - int want_autoneg; struct net_device_stats stats; - struct timer_list timer; spinlock_t lock; /* Serialise access to device */ }; diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 54161aef3ca..702d546567a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -32,6 +32,7 @@ #include <asm/irq.h> #include <linux/delay.h> #include <asm/byteorder.h> +#include <asm/page.h> #include <linux/time.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -49,14 +50,15 @@ #include <linux/crc32.h> #include <linux/prefetch.h> #include <linux/cache.h> +#include <linux/zlib.h> #include "bnx2.h" #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4.40" -#define DRV_MODULE_RELDATE "May 22, 2006" +#define DRV_MODULE_VERSION "1.4.42" +#define DRV_MODULE_RELDATE "June 12, 2006" #define RUN_AT(x) (jiffies + (x)) @@ -1820,7 +1822,7 @@ reuse_rx: skb->protocol = eth_type_trans(skb, bp->dev); if ((len > (bp->dev->mtu + ETH_HLEN)) && - (htons(skb->protocol) != 0x8100)) { + (ntohs(skb->protocol) != 0x8100)) { dev_kfree_skb_irq(skb); goto next_rx; @@ -2009,7 +2011,7 @@ bnx2_poll(struct net_device *dev, int *budget) return 1; } -/* Called with rtnl_lock from vlan functions and also dev->xmit_lock +/* Called with rtnl_lock from vlan functions and also netif_tx_lock * from set_multicast. */ static void @@ -2083,6 +2085,92 @@ bnx2_set_rx_mode(struct net_device *dev) spin_unlock_bh(&bp->phy_lock); } +#define FW_BUF_SIZE 0x8000 + +static int +bnx2_gunzip_init(struct bnx2 *bp) +{ + if ((bp->gunzip_buf = vmalloc(FW_BUF_SIZE)) == NULL) + goto gunzip_nomem1; + + if ((bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL)) == NULL) + goto gunzip_nomem2; + + bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); + if (bp->strm->workspace == NULL) + goto gunzip_nomem3; + + return 0; + +gunzip_nomem3: + kfree(bp->strm); + bp->strm = NULL; + +gunzip_nomem2: + vfree(bp->gunzip_buf); + bp->gunzip_buf = NULL; + +gunzip_nomem1: + printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for " + "uncompression.\n", bp->dev->name); + return -ENOMEM; +} + +static void +bnx2_gunzip_end(struct bnx2 *bp) +{ + kfree(bp->strm->workspace); + + kfree(bp->strm); + bp->strm = NULL; + + if (bp->gunzip_buf) { + vfree(bp->gunzip_buf); + bp->gunzip_buf = NULL; + } +} + +static int +bnx2_gunzip(struct bnx2 *bp, u8 *zbuf, int len, void **outbuf, int *outlen) +{ + int n, rc; + + /* check gzip header */ + if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) + return -EINVAL; + + n = 10; + +#define FNAME 0x8 + if (zbuf[3] & FNAME) + while ((zbuf[n++] != 0) && (n < len)); + + bp->strm->next_in = zbuf + n; + bp->strm->avail_in = len - n; + bp->strm->next_out = bp->gunzip_buf; + bp->strm->avail_out = FW_BUF_SIZE; + + rc = zlib_inflateInit2(bp->strm, -MAX_WBITS); + if (rc != Z_OK) + return rc; + + rc = zlib_inflate(bp->strm, Z_FINISH); + + *outlen = FW_BUF_SIZE - bp->strm->avail_out; + *outbuf = bp->gunzip_buf; + + if ((rc != Z_OK) && (rc != Z_STREAM_END)) + printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n", + bp->dev->name, bp->strm->msg); + + zlib_inflateEnd(bp->strm); + + if (rc == Z_STREAM_END) + return 0; + + return rc; +} + static void load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, u32 rv2p_proc) @@ -2092,9 +2180,9 @@ load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, for (i = 0; i < rv2p_code_len; i += 8) { - REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code); + REG_WR(bp, BNX2_RV2P_INSTR_HIGH, cpu_to_le32(*rv2p_code)); rv2p_code++; - REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code); + REG_WR(bp, BNX2_RV2P_INSTR_LOW, cpu_to_le32(*rv2p_code)); rv2p_code++; if (rv2p_proc == RV2P_PROC1) { @@ -2134,7 +2222,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) int j; for (j = 0; j < (fw->text_len / 4); j++, offset += 4) { - REG_WR_IND(bp, offset, fw->text[j]); + REG_WR_IND(bp, offset, cpu_to_le32(fw->text[j])); } } @@ -2190,15 +2278,32 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) REG_WR_IND(bp, cpu_reg->mode, val); } -static void +static int bnx2_init_cpus(struct bnx2 *bp) { struct cpu_reg cpu_reg; struct fw_info fw; + int rc = 0; + void *text; + u32 text_len; + + if ((rc = bnx2_gunzip_init(bp)) != 0) + return rc; /* Initialize the RV2P processor. */ - load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1); - load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2); + rc = bnx2_gunzip(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), &text, + &text_len); + if (rc) + goto init_cpu_err; + + load_rv2p_fw(bp, text, text_len, RV2P_PROC1); + + rc = bnx2_gunzip(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), &text, + &text_len); + if (rc) + goto init_cpu_err; + + load_rv2p_fw(bp, text, text_len, RV2P_PROC2); /* Initialize the RX Processor. */ cpu_reg.mode = BNX2_RXP_CPU_MODE; @@ -2222,7 +2327,13 @@ bnx2_init_cpus(struct bnx2 *bp) fw.text_addr = bnx2_RXP_b06FwTextAddr; fw.text_len = bnx2_RXP_b06FwTextLen; fw.text_index = 0; - fw.text = bnx2_RXP_b06FwText; + + rc = bnx2_gunzip(bp, bnx2_RXP_b06FwText, sizeof(bnx2_RXP_b06FwText), + &text, &text_len); + if (rc) + goto init_cpu_err; + + fw.text = text; fw.data_addr = bnx2_RXP_b06FwDataAddr; fw.data_len = bnx2_RXP_b06FwDataLen; @@ -2268,7 +2379,13 @@ bnx2_init_cpus(struct bnx2 *bp) fw.text_addr = bnx2_TXP_b06FwTextAddr; fw.text_len = bnx2_TXP_b06FwTextLen; fw.text_index = 0; - fw.text = bnx2_TXP_b06FwText; + + rc = bnx2_gunzip(bp, bnx2_TXP_b06FwText, sizeof(bnx2_TXP_b06FwText), + &text, &text_len); + if (rc) + goto init_cpu_err; + + fw.text = text; fw.data_addr = bnx2_TXP_b06FwDataAddr; fw.data_len = bnx2_TXP_b06FwDataLen; @@ -2314,7 +2431,13 @@ bnx2_init_cpus(struct bnx2 *bp) fw.text_addr = bnx2_TPAT_b06FwTextAddr; fw.text_len = bnx2_TPAT_b06FwTextLen; fw.text_index = 0; - fw.text = bnx2_TPAT_b06FwText; + + rc = bnx2_gunzip(bp, bnx2_TPAT_b06FwText, sizeof(bnx2_TPAT_b06FwText), + &text, &text_len); + if (rc) + goto init_cpu_err; + + fw.text = text; fw.data_addr = bnx2_TPAT_b06FwDataAddr; fw.data_len = bnx2_TPAT_b06FwDataLen; @@ -2360,7 +2483,13 @@ bnx2_init_cpus(struct bnx2 *bp) fw.text_addr = bnx2_COM_b06FwTextAddr; fw.text_len = bnx2_COM_b06FwTextLen; fw.text_index = 0; - fw.text = bnx2_COM_b06FwText; + + rc = bnx2_gunzip(bp, bnx2_COM_b06FwText, sizeof(bnx2_COM_b06FwText), + &text, &text_len); + if (rc) + goto init_cpu_err; + + fw.text = text; fw.data_addr = bnx2_COM_b06FwDataAddr; fw.data_len = bnx2_COM_b06FwDataLen; @@ -2384,6 +2513,9 @@ bnx2_init_cpus(struct bnx2 *bp) load_cpu_fw(bp, &cpu_reg, &fw); +init_cpu_err: + bnx2_gunzip_end(bp); + return rc; } static int @@ -3256,7 +3388,9 @@ bnx2_init_chip(struct bnx2 *bp) * context block must have already been enabled. */ bnx2_init_context(bp); - bnx2_init_cpus(bp); + if ((rc = bnx2_init_cpus(bp)) != 0) + return rc; + bnx2_init_nvram(bp); bnx2_set_mac_addr(bp); @@ -3556,7 +3690,9 @@ bnx2_reset_nic(struct bnx2 *bp, u32 reset_code) if (rc) return rc; - bnx2_init_chip(bp); + if ((rc = bnx2_init_chip(bp)) != 0) + return rc; + bnx2_init_tx_ring(bp); bnx2_init_rx_ring(bp); return 0; @@ -4034,6 +4170,8 @@ bnx2_timer(unsigned long data) msg = (u32) ++bp->fw_drv_pulse_wr_seq; REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg); + bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); + if ((bp->phy_flags & PHY_SERDES_FLAG) && (CHIP_NUM(bp) == CHIP_NUM_5706)) { @@ -4252,7 +4390,7 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) } #endif -/* Called with dev->xmit_lock. +/* Called with netif_tx_lock. * hard_start_xmit is pseudo-lockless - a lock is only required when * the tx queue is full. This way, we get the benefit of lockless * operations most of the time without the complexities to handle @@ -4310,7 +4448,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) ip_tcp_len = (skb->nh.iph->ihl << 2) + sizeof(struct tcphdr); skb->nh.iph->check = 0; - skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); + skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr, @@ -4504,6 +4642,10 @@ bnx2_get_stats(struct net_device *dev) net_stats->tx_aborted_errors + net_stats->tx_carrier_errors; + net_stats->rx_missed_errors = + (unsigned long) (stats_blk->stat_IfInMBUFDiscards + + stats_blk->stat_FwRxDrop); + return net_stats; } @@ -4986,7 +5128,7 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data) return 0; } -#define BNX2_NUM_STATS 45 +#define BNX2_NUM_STATS 46 static struct { char string[ETH_GSTRING_LEN]; @@ -5036,6 +5178,7 @@ static struct { { "rx_mac_ctrl_frames" }, { "rx_filtered_packets" }, { "rx_discards" }, + { "rx_fw_discards" }, }; #define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4) @@ -5086,6 +5229,7 @@ static const unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { STATS_OFFSET32(stat_MacControlFramesReceived), STATS_OFFSET32(stat_IfInFramesL2FilterDiscards), STATS_OFFSET32(stat_IfInMBUFDiscards), + STATS_OFFSET32(stat_FwRxDrop), }; /* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are @@ -5096,7 +5240,7 @@ static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = { 4,0,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4, + 4,4,4,4,4,4, }; static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = { @@ -5104,7 +5248,7 @@ static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = { 4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4, + 4,4,4,4,4,4, }; #define BNX2_NUM_TESTS 6 @@ -5634,7 +5778,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) } } - if (CHIP_NUM(bp) == CHIP_NUM_5708) + if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || + (CHIP_ID(bp) == CHIP_ID_5708_B0) || + (CHIP_ID(bp) == CHIP_ID_5708_B1)) bp->flags |= NO_WOL_FLAG; if (CHIP_ID(bp) == CHIP_ID_5706_A0) { diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index b87925f6a22..5845e334941 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -231,6 +231,7 @@ struct statistics_block { u32 stat_GenStat13; u32 stat_GenStat14; u32 stat_GenStat15; + u32 stat_FwRxDrop; }; @@ -3481,6 +3482,8 @@ struct l2_fhdr { #define BNX2_COM_SCRATCH 0x00120000 +#define BNX2_FW_RX_DROP_COUNT 0x00120084 + /* * cp_reg definition @@ -3747,7 +3750,12 @@ struct l2_fhdr { #define DMA_READ_CHANS 5 #define DMA_WRITE_CHANS 3 -#define BCM_PAGE_BITS 12 +/* Use CPU native page size up to 16K for the ring sizes. */ +#if (PAGE_SHIFT > 14) +#define BCM_PAGE_BITS 14 +#else +#define BCM_PAGE_BITS PAGE_SHIFT +#endif #define BCM_PAGE_SIZE (1 << BCM_PAGE_BITS) #define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd)) @@ -3770,7 +3778,7 @@ struct l2_fhdr { #define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx) -#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> 8) +#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4)) #define RX_IDX(x) ((x) & MAX_RX_DESC_CNT) /* Context size. */ @@ -4048,6 +4056,9 @@ struct bnx2 { u32 flash_size; int status_stats_size; + + struct z_stream_s *strm; + void *gunzip_buf; }; static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset); diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h index 8158974c35a..2d753dca0d7 100644 --- a/drivers/net/bnx2_fw.h +++ b/drivers/net/bnx2_fw.h @@ -7,7 +7,7 @@ * the Free Software Foundation, except as noted below. * * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004, 2005 Broadcom Corporation. + * source code, Copyright (c) 2004, 2005, 2006 Broadcom Corporation. * * Permission is hereby granted for the distribution of this firmware data * in hexadecimal or equivalent format, provided this copyright notice is @@ -28,943 +28,641 @@ static const u32 bnx2_COM_b06FwBssAddr = 0x08005860; static const int bnx2_COM_b06FwBssLen = 0x88; static const u32 bnx2_COM_b06FwSbssAddr = 0x08005840; static const int bnx2_COM_b06FwSbssLen = 0x1c; -static u32 bnx2_COM_b06FwText[(0x57bc/4) + 1] = { - 0x0a00022d, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x322e352e, - 0x38000000, 0x02050802, 0x00000000, 0x00000003, 0x00000014, 0x00000032, - 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0000ffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000002, 0x00000020, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425840, - 0x3c030800, 0x246358e8, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004, - 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261008b4, 0x3c1c0800, - 0x279c5840, 0x0e0002f7, 0x00000000, 0x0000000d, 0x27bdffe8, 0x3c1a8000, - 0x3c020008, 0x0342d825, 0x3c036010, 0xafbf0010, 0x8c655000, 0x3c020800, - 0x24470f30, 0x3c040800, 0x24865860, 0x2402ff7f, 0x00a22824, 0x34a5380c, - 0xac655000, 0x00002821, 0x24020037, 0x24030c80, 0xaf420008, 0xaf430024, - 0xacc70000, 0x24a50001, 0x2ca20016, 0x1440fffc, 0x24c60004, 0x24845860, - 0x3c020800, 0x24420f3c, 0x3c030800, 0x24630e2c, 0xac820004, 0x3c020800, - 0x24420a2c, 0x3c050800, 0x24a51268, 0xac82000c, 0x3c020800, 0x244243dc, - 0xac830008, 0x3c030800, 0x24633698, 0xac820014, 0x3c020800, 0x24423c24, - 0xac830018, 0xac83001c, 0x3c030800, 0x24630f44, 0xac820024, 0x3c020800, - 0x244243ac, 0xac83002c, 0x3c030800, 0x246343cc, 0xac820030, 0x3c020800, - 0x244242f0, 0xac830034, 0x3c030800, 0x24633d78, 0xac82003c, 0x3c020800, - 0x24420fd4, 0xac850010, 0xac850020, 0xac830040, 0x0e0010b7, 0xac820050, - 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafb00010, 0x27500100, - 0xafbf0018, 0xafb10014, 0x9203000b, 0x24020003, 0x1462005b, 0x96110008, - 0x32220001, 0x10400009, 0x27430080, 0x8e020000, 0x96040014, 0x000211c2, - 0x00021040, 0x00621821, 0xa4640000, 0x0a0002d0, 0x3c020800, 0x3c020800, - 0x8c430020, 0x1060002a, 0x3c030800, 0x0e00148e, 0x00000000, 0x97420108, - 0x8f850018, 0x9743010c, 0x3042003e, 0x00021400, 0x00621825, 0xaca30000, - 0x8f840018, 0x8f420100, 0xac820004, 0x97430116, 0x9742010e, 0x8f840018, - 0x00031c00, 0x00431025, 0xac820008, 0x97430110, 0x97440112, 0x8f850018, - 0x00031c00, 0x00832025, 0xaca4000c, 0x97420114, 0x8f840018, 0x3042ffff, - 0xac820010, 0x8f830018, 0xac600014, 0x8f820018, 0x3c030800, 0xac400018, - 0x946258ce, 0x8f840018, 0x3c032000, 0x00431025, 0xac82001c, 0x0e0014cc, - 0x24040001, 0x3c030800, 0x8c620040, 0x24420001, 0xac620040, 0x3c020800, - 0x8c430044, 0x32240004, 0x24630001, 0x10800017, 0xac430044, 0x8f4202b8, - 0x04430007, 0x8e020020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001, - 0x0a0002f2, 0xac830060, 0x3c060800, 0x8cc4005c, 0xaf420280, 0x96030016, - 0x00001021, 0xa7430284, 0x8e050004, 0x24840001, 0x3c031000, 0xaf450288, - 0xaf4302b8, 0x0a0002f2, 0xacc4005c, 0x32220002, 0x0a0002f2, 0x0002102b, - 0x3c026000, 0xac400808, 0x0000000d, 0x00001021, 0x8fbf0018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffc8, 0xafbf0034, 0xafbe0030, - 0xafb7002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018, - 0xafb10014, 0x0e000244, 0xafb00010, 0x3c170800, 0x3c160800, 0x24110020, - 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800, 0x8f820004, - 0x3c040800, 0x8c830020, 0x10430005, 0x8ee200a4, 0xaf830004, 0x0e001593, - 0x00000000, 0x8ee200a4, 0x8ec300a0, 0x10430004, 0x26c400a0, 0x94820002, - 0xa742009e, 0xaee300a4, 0x8f500000, 0x32020007, 0x1040ffee, 0x32020001, - 0x1040002c, 0x32020002, 0x8f420100, 0xaf420020, 0x8f430104, 0xaf4300a8, - 0x9342010b, 0x93630000, 0x306300ff, 0x10710005, 0x304400ff, 0x10750006, - 0x2c820016, 0x0a000333, 0x00000000, 0xaf940000, 0x0a000334, 0x2c820016, - 0xaf930000, 0x0a000334, 0x00000000, 0xaf800000, 0x14400005, 0x00041880, - 0x0e0003cc, 0x00000000, 0x0a000340, 0x00000000, 0x3c020800, 0x24425860, - 0x00621821, 0x8c620000, 0x0040f809, 0x00000000, 0x10400005, 0x3c030800, - 0x8f420104, 0x3c016020, 0xac220014, 0x3c030800, 0x8c620034, 0xaf520138, - 0x24420001, 0xac620034, 0x32020002, 0x1040001a, 0x32020004, 0x8f420140, - 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000, 0x10750006, - 0x00000000, 0x0a00035d, 0x00000000, 0xaf940000, 0x0a00035e, 0x00000000, - 0xaf930000, 0x0a00035e, 0x00000000, 0xaf800000, 0x0e000c7b, 0x00000000, - 0x3c040800, 0x8c820038, 0xaf520178, 0x24420001, 0xac820038, 0x32020004, - 0x1040ffa4, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff, - 0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a000378, 0x00000000, - 0xaf940000, 0x0a000379, 0x00000000, 0xaf930000, 0x0a000379, 0x00000000, - 0xaf800000, 0x8f430180, 0x24020f00, 0x14620005, 0x00000000, 0x8f420188, - 0xa742009c, 0x0a000387, 0x8fc2003c, 0x93620000, 0x14510004, 0x8fc2003c, - 0x0e000bad, 0x00000000, 0x8fc2003c, 0xaf5201b8, 0x24420001, 0x0a00030b, - 0xafc2003c, 0x27bdffe8, 0xafbf0010, 0x97420108, 0x24033000, 0x30447000, - 0x10830016, 0x28823001, 0x10400007, 0x24024000, 0x1080000b, 0x24022000, - 0x1082000c, 0x00000000, 0x0a0003b3, 0x00000000, 0x10820010, 0x24025000, - 0x10820012, 0x00000000, 0x0a0003b3, 0x00000000, 0x0000000d, 0x0a0003b5, - 0x00001021, 0x0e000442, 0x00000000, 0x0a0003b6, 0x8fbf0010, 0x0e00041a, - 0x00000000, 0x0a0003b5, 0x00001021, 0x0e000669, 0x00000000, 0x0a0003b5, - 0x00001021, 0x0e001467, 0x00000000, 0x0a0003b5, 0x00001021, 0x0000000d, - 0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020, - 0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0003c9, - 0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008, - 0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000, - 0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100, - 0x94830008, 0x30620004, 0x10400017, 0x30620002, 0x8f4202b8, 0x04430007, - 0x8c820020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001, 0x03e00008, - 0xac830060, 0xaf420280, 0x94830016, 0x3c060800, 0xa7430284, 0x8c850004, - 0x8cc4005c, 0x00001021, 0x3c031000, 0x24840001, 0xaf450288, 0xaf4302b8, - 0x03e00008, 0xacc4005c, 0x14400003, 0x3c040800, 0x03e00008, 0x00001021, - 0x8c830084, 0x24020001, 0x24630001, 0x03e00008, 0xac830084, 0x27450100, - 0x3c040800, 0x8c820088, 0x94a3000c, 0x24420001, 0x007a1821, 0xac820088, - 0x8ca40018, 0x90664000, 0xaf440038, 0x8ca2001c, 0x2403fff8, 0x00063600, - 0x00431024, 0x34420004, 0x3c030005, 0xaf42003c, 0xaf430030, 0x00000000, - 0x00000000, 0x00000000, 0xaf460404, 0x00000000, 0x00000000, 0x00000000, - 0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, - 0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000, - 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e, - 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000, - 0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, - 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, - 0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, - 0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, - 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, - 0x27500100, 0xafbf0014, 0x92020009, 0x14400003, 0x3c020800, 0x0a00046c, - 0x24020001, 0x8c430020, 0x1060001f, 0x00001021, 0x0e00148e, 0x00000000, - 0x8f830018, 0x8e020018, 0xac620000, 0x8f840018, 0x9602000c, 0xac820004, - 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, - 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448, 0xac830018, - 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018, 0x00021400, 0x00441025, - 0x24040001, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf0014, 0x8fb00010, - 0x03e00008, 0x27bd0018, 0x3c0b0800, 0x8d6808b0, 0x3c070800, 0x24e700b0, - 0x00084900, 0x01271821, 0xac640000, 0x93620005, 0x97660008, 0x00e95021, - 0x93630023, 0x9364003f, 0x25080001, 0x00021600, 0x00063400, 0x00461025, - 0x00031a00, 0x00431025, 0x00822025, 0xad440004, 0x9362007e, 0x9366007f, - 0x8f630178, 0x9364007a, 0x00021600, 0x00063400, 0x00461025, 0x00031a00, - 0x00431025, 0x00822025, 0xad440008, 0x93620080, 0x9363007d, 0x3108007f, - 0x01403821, 0xad6808b0, 0x00021600, 0x00031c00, 0x00431025, 0x00451025, - 0x03e00008, 0xace2000c, 0x27bdffb8, 0xafb3002c, 0x00009821, 0xafbe0040, - 0x0000f021, 0xafb50034, 0x27550100, 0xafbf0044, 0xafb7003c, 0xafb60038, - 0xafb40030, 0xafb20028, 0xafb10024, 0xafb00020, 0xafa00010, 0xafa00014, - 0x96a20008, 0x8f540100, 0x8eb10018, 0x30420001, 0x10400037, 0x02a0b821, - 0x8f630054, 0x2622ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, - 0x00000000, 0x2400015c, 0x0a0004e5, 0x00002021, 0x8f62004c, 0x02221023, - 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, - 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c, - 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, - 0x00021023, 0x30420005, 0x0a0004e5, 0x34440004, 0x27660100, 0x00041080, - 0x00c21021, 0x8c430000, 0x02231823, 0x04600004, 0x24820001, 0x30440007, - 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094, - 0x24040005, 0x24420001, 0x0a0004e5, 0xac620094, 0x24040004, 0x00809821, - 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010, 0x2c420001, - 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001, 0x38820014, - 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012, 0x14820002, - 0x00001021, 0x24020001, 0x10400009, 0x00000000, 0x8ea20020, 0x8f630040, - 0x0040b021, 0x00431023, 0x5c400010, 0x8f760040, 0x0a000511, 0x00000000, - 0x9343010b, 0x24020004, 0x1462000a, 0x8eb60020, 0x8f630040, 0x3c021000, - 0x00761823, 0x0043102a, 0x10400004, 0x00000000, 0x0000000d, 0x00000000, - 0x240002fa, 0x9343010b, 0x24020004, 0x5462000b, 0x96a20008, 0x24020001, - 0xafa20010, 0x96a20008, 0x24030001, 0xafa30018, 0x8eb2001c, 0x36730002, - 0x30420020, 0x0a000526, 0xafa20014, 0x36730080, 0x30420002, 0x10400003, - 0xafa00018, 0x0a000526, 0x8eb2001c, 0x8eb20014, 0x2402fffb, 0x02628024, - 0x1200002a, 0x3c030800, 0x8c620030, 0x02021024, 0x10400026, 0x3c020800, - 0x8c430020, 0x10600024, 0x32620004, 0x0e00148e, 0x00000000, 0x8f830018, - 0x8f420100, 0xac620000, 0x8f840018, 0x02401821, 0x32620002, 0xac900004, - 0x8f840018, 0x54400001, 0x02c01821, 0xac830008, 0x8f830018, 0x8ee20020, - 0xac62000c, 0x8f840018, 0x8f620040, 0xac820010, 0x8f830018, 0x8ee20018, - 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, - 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc, - 0xaca3001c, 0x32620004, 0x10400063, 0x00003821, 0x3c029000, 0x34420001, - 0x3c038000, 0x02821025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, - 0x1440fffd, 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000, - 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, - 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, - 0xaf710064, 0x3c023fff, 0x0a000580, 0x3442ffff, 0x8f62005c, 0x02221023, - 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, - 0x3442ffff, 0xaf710064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, - 0x02251021, 0x3c053fff, 0x34a5ffff, 0x02251021, 0xaf62005c, 0x24070001, - 0xaf71004c, 0x8f620054, 0x16220005, 0x00000000, 0x93620023, 0x30420040, - 0x10400017, 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, - 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, - 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, - 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, - 0xaf62000c, 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000, - 0x34420001, 0x02821025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, - 0x00000000, 0x0e0013c4, 0x00000000, 0x00403821, 0x54e00001, 0x241e0001, - 0x8f700040, 0x8f620040, 0x14520003, 0x00521023, 0x0a0005bf, 0x00001021, - 0x28420001, 0x10400041, 0x8fa20010, 0x0e000fae, 0x02402021, 0xaf720040, - 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022, 0x24420001, - 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b, 0x14600027, - 0x3c020800, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, - 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, - 0x34420001, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020, - 0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050273, 0x0a0005f2, - 0x24050001, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, - 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x24050001, 0x24020001, 0xa7620012, - 0xa3600022, 0x0a0005fe, 0x2ca20001, 0x9743007a, 0x9444002a, 0x00002821, - 0x00641821, 0x3063fffe, 0xa7630012, 0x2ca20001, 0x00021023, 0x03c2f024, - 0x8fa20010, 0x10400004, 0x8fa30014, 0x0e0013c1, 0x00000000, 0x8fa30014, - 0x10600003, 0x00000000, 0x0e0010eb, 0x00000000, 0x13c0001f, 0x3c029000, - 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, - 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, - 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000, 0x02802021, - 0x0e000470, 0x2405036c, 0x0a00062b, 0x8fa20018, 0x8f4201f8, 0x00431024, - 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8, - 0x8fa20018, 0x5040002f, 0x96a20008, 0x8f620048, 0x8f630024, 0x00761821, - 0xaf630048, 0x9764003c, 0x00501023, 0x0044102b, 0x10400025, 0x3c029000, - 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100, 0x3c068000, 0x24630001, - 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020, 0x00461024, 0x1440fffd, - 0x00000000, 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, - 0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, - 0x0e000470, 0x2405038a, 0x0a00065b, 0x96a20008, 0x8f4201f8, 0x00431024, - 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, - 0x96a20008, 0x8fbf0044, 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034, - 0x8fb40030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x00021042, - 0x30420001, 0x03e00008, 0x27bd0048, 0x27bdffe0, 0xafbf0018, 0x97420108, - 0x24030019, 0x304400ff, 0x10830065, 0x2882001a, 0x1040001a, 0x2882000a, - 0x1040000f, 0x28820008, 0x10400040, 0x24020001, 0x1082003a, 0x28820002, - 0x50400005, 0x24020006, 0x10800032, 0x3c026000, 0x0a0006fb, 0x00000000, - 0x1082003d, 0x00000000, 0x0a0006fb, 0x00000000, 0x2402000b, 0x10820044, - 0x2882000b, 0x1440004b, 0x2402000e, 0x10820045, 0x00000000, 0x0a0006fb, - 0x00000000, 0x24020020, 0x10820062, 0x28820021, 0x1040000e, 0x2402001c, - 0x1082004c, 0x2882001d, 0x10400005, 0x2402001b, 0x10820043, 0x00000000, - 0x0a0006fb, 0x00000000, 0x2402001f, 0x10820050, 0x00000000, 0x0a0006fb, - 0x00000000, 0x240200c1, 0x10820042, 0x288200c2, 0x10400005, 0x24020080, - 0x10820021, 0x00000000, 0x0a0006fb, 0x00000000, 0x240200c2, 0x1082003d, - 0x240200c9, 0x50820049, 0xafa00010, 0x0a0006fb, 0x00000000, 0x0e001163, - 0xac400808, 0x0a0006fd, 0x8fbf0018, 0x3c026000, 0x8c444448, 0x3c030800, - 0xac640064, 0x0e001163, 0x00000000, 0x3c026000, 0x8c444448, 0x3c030800, - 0x0a0006fc, 0xac640068, 0x8f440100, 0x0e0006ff, 0x00000000, 0x3c026000, - 0x8c444448, 0x3c030800, 0x0a0006fc, 0xac64006c, 0x0e001191, 0x00000000, - 0x0a0006fd, 0x8fbf0018, 0x8f440100, 0x0e0011bb, 0x00000000, 0x0a0006fd, - 0x8fbf0018, 0x0e001202, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0000000d, - 0x0a0006fd, 0x8fbf0018, 0x0e000826, 0x00000000, 0x0a0006fd, 0x8fbf0018, - 0x8f440100, 0x0e001264, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00134e, - 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00087c, 0x27440100, 0x0a0006fd, - 0x8fbf0018, 0x8f640040, 0x0e000fae, 0x00000000, 0x0a0006fd, 0x8fbf0018, - 0x8f440100, 0x0e001059, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e001417, - 0x00000000, 0x0a0006fd, 0x8fbf0018, 0xafa00014, 0x8f440100, 0x8f450118, - 0x8f46011c, 0x0e001439, 0x8f470120, 0x0a0006fd, 0x8fbf0018, 0x0000000d, - 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x9742010c, - 0x1440005e, 0x00803821, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020, - 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, - 0x30420010, 0x14400026, 0x3c030800, 0x8f630074, 0x3c027fff, 0x3442ffff, - 0x00621824, 0xaf630074, 0x93620005, 0x34420001, 0xa3620005, 0x8f63004c, - 0x8f620054, 0x10620021, 0x24040001, 0x9762006a, 0x00022880, 0x50a00001, - 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, - 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, - 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, - 0x00a21021, 0xaf62000c, 0x0a00073d, 0x24040001, 0x8c6200a8, 0x00002021, - 0x24420001, 0xac6200a8, 0x0000000d, 0x00000000, 0x2400044d, 0x3c028000, - 0x34420001, 0x00e21025, 0xaf420020, 0x1080001f, 0x3c029000, 0x34420001, - 0x00e21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, - 0x00e31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00e02021, 0x0e000470, - 0x24050455, 0x0a000761, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd, - 0x24020002, 0x3c031000, 0xaf4701c0, 0xa34201c4, 0xaf4301f8, 0x0e001163, - 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafbf0024, - 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x93630005, - 0x00809821, 0x24020030, 0x30630030, 0x146200ac, 0x00a0a021, 0x3c020800, - 0x8c430020, 0x106000a6, 0x00000000, 0x0e00148e, 0x00000000, 0x8f830018, - 0xac730000, 0x936200c4, 0x30420002, 0x10400004, 0x24020001, 0x8f830018, - 0x0a000784, 0x00000000, 0x8f830018, 0x24020003, 0xac620004, 0x8f6200dc, - 0x8f630040, 0x00431023, 0x18400004, 0x00000000, 0x0000000d, 0x00000000, - 0x24000509, 0x8f840018, 0x8f6200dc, 0xac820008, 0x8f830018, 0xac60000c, - 0x8f820018, 0xac400010, 0x8f830018, 0x8f62004c, 0x3c100800, 0xac620014, - 0x8f850018, 0x3c026000, 0x8c434448, 0x261258c0, 0x00002021, 0xaca30018, - 0x9642000e, 0x8f850018, 0x3c034010, 0x00431025, 0x0e0014cc, 0xaca2001c, - 0x8f830018, 0xac730000, 0x9362003e, 0x9363003f, 0x8f840018, 0x00021200, - 0x00621825, 0xac830004, 0x93620081, 0x93630082, 0x8f840018, 0x00021600, - 0x00031c00, 0x00431025, 0xac820008, 0x8f830018, 0x8f620040, 0xac62000c, - 0x8f840018, 0x8f620048, 0xac820010, 0x8f71004c, 0x8f820018, 0xac510014, - 0x8f620050, 0x8f850018, 0x00401821, 0x02221023, 0x5c400001, 0x02201821, - 0x00002021, 0xaca30018, 0x9642000e, 0x8f850018, 0x3c03c00b, 0x00431025, - 0x0e0014cc, 0xaca2001c, 0x8f620054, 0x8f840018, 0x00401821, 0x02221023, - 0x5c400001, 0x02201821, 0xac830000, 0x8f840018, 0x8f630058, 0xac830004, - 0x93620023, 0x30420010, 0x10400004, 0x00000000, 0x8f830018, 0x0a0007dd, - 0x8f620148, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f830018, 0x8f620060, - 0xac62000c, 0x8f840018, 0x8f620064, 0xac820010, 0x97630068, 0x9762006a, - 0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f850018, 0x00002021, - 0x2402ffff, 0x260358c0, 0xaca20018, 0x9462000e, 0x8f850018, 0x3c03c00c, - 0x00431025, 0x0e0014cc, 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000, - 0x936200c4, 0x30420002, 0x10400006, 0x00000000, 0x976200c8, 0x8f830018, - 0x3042ffff, 0x0a000803, 0xac620004, 0x8f820018, 0xac400004, 0x8f830018, - 0x8f62006c, 0xac620008, 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018, - 0xac600010, 0x93620005, 0x8f830018, 0x00021600, 0x00541025, 0xac620014, - 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x260258c0, 0xaca30018, - 0x9443000e, 0x8f850018, 0x3c02400d, 0x00621825, 0x0e0014cc, 0xaca3001c, - 0x0e00122e, 0x02602021, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb00010, - 0x27500100, 0xafbf0018, 0xafb10014, 0x9603000c, 0x240200c1, 0x54620024, - 0x8e040000, 0x3c029000, 0x8f450100, 0x34420001, 0x3c038000, 0x00a21025, - 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, - 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825, - 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470, 0x240505b2, - 0x0a000878, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, - 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x0a000878, 0x8fbf0018, - 0x8f65004c, 0x24060001, 0x0e0012a3, 0x240705be, 0x3c020800, 0x8c430020, - 0x9611000c, 0x1060001d, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018, - 0xac500000, 0x8f840018, 0x00111400, 0xac820004, 0x8f830018, 0xac600008, - 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018, 0x240205c1, - 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, - 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc, - 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, - 0x27bdffb0, 0xafb5003c, 0x0000a821, 0xafbe0048, 0x0000f021, 0xafb70044, - 0x0000b821, 0xafb30034, 0x00009821, 0xafb60040, 0x0080b021, 0xafbf004c, - 0xafb40038, 0xafb20030, 0xafb1002c, 0xafb00028, 0xafa00010, 0x8f620040, - 0x8ec30014, 0x96d1000c, 0x00431023, 0x04410025, 0x8ed40000, 0x32220401, - 0x1040030c, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, - 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, - 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020, - 0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050664, 0x0a000ba2, - 0x8fbf004c, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, - 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x0a000ba2, 0x8fbf004c, 0x32220010, - 0x1040006b, 0x00003021, 0x9362003f, 0x92c6000f, 0x304500ff, 0x24c3fff8, - 0x2c62000f, 0x10400057, 0x3c020800, 0x244257c0, 0x00031880, 0x00621821, - 0x8c640000, 0x00800008, 0x00000000, 0x38a20012, 0x0a000924, 0x0002a82b, - 0x2402000e, 0x14a20004, 0x2402000c, 0x24150001, 0x0a000924, 0x24060010, - 0x10a20049, 0x38a30010, 0x2c630001, 0x38a20016, 0x2c420001, 0x00621825, - 0x1460004d, 0x0000a821, 0x24020014, 0x10a2004a, 0x00000000, 0x0000000d, - 0x00000000, 0x2400069c, 0x0a000924, 0x0000a821, 0x24020016, 0x14a20005, - 0x2402000c, 0x24150001, 0x24060010, 0x0a000924, 0x3231fffd, 0x10a20032, - 0x38a30010, 0x2c630001, 0x38a2000e, 0x2c420001, 0x00621825, 0x14600036, - 0x0000a821, 0x24020014, 0x14a20003, 0x24150001, 0x0a000924, 0x24060012, - 0x0000000d, 0x00000000, 0x240006bc, 0x0a000924, 0x0000a821, 0x2402000e, - 0x14a20004, 0x24020016, 0x24150001, 0x0a000924, 0x3231fffb, 0x14a20004, - 0x24020014, 0x24150001, 0x0a000924, 0x3231fffd, 0x54a20013, 0x92c2000e, - 0x24150001, 0x24060012, 0x0a000924, 0x3231fffd, 0x2402000c, 0x54a2000c, - 0x92c2000e, 0x92c3000e, 0x2402000a, 0x10620005, 0x24150001, 0x0000000d, - 0x00000000, 0x240006e8, 0x24150001, 0x0a000924, 0x24060014, 0x92c2000e, - 0x14a20003, 0x00000000, 0x0a000924, 0x24150001, 0x10a6ffc1, 0x24020012, - 0x10a20005, 0x0000a821, 0x0000000d, 0x00000000, 0x24000704, 0x0000a821, - 0x12a00022, 0x32220004, 0x10400002, 0x24020001, 0xafa20010, 0x32230102, - 0x24020002, 0x1462000f, 0x00000000, 0x92c2000a, 0x30420020, 0x1440000b, - 0x00000000, 0x8f630048, 0x8f620040, 0x14620004, 0x00000000, 0x8f620048, - 0x24420001, 0xaf620048, 0x8f620040, 0x24420001, 0xaf620040, 0xa366003f, - 0x38c30012, 0x2c630001, 0x38c20010, 0x2c420001, 0x00621825, 0x10600005, - 0x3c030800, 0x8c620074, 0x24420001, 0x0e00140d, 0xac620074, 0x32220040, - 0x32230020, 0xafa30020, 0x32230080, 0xafa30024, 0x32230001, 0xafa30018, - 0x32230008, 0xafa3001c, 0x32230100, 0x104000c4, 0xafa30014, 0x8ec60010, - 0x8f630054, 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, - 0x00000000, 0x2400015c, 0x0a000989, 0x00009021, 0x8f62004c, 0x00c21023, - 0x18400028, 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, - 0x308400ff, 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c, - 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, - 0x00021023, 0x30420005, 0x0a000989, 0x34520004, 0x27670100, 0x00041080, - 0x00e21021, 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007, - 0x1485fff9, 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094, - 0x24120005, 0x24420001, 0x0a000989, 0xac620094, 0x24120004, 0x32420001, - 0x10400021, 0x3c020800, 0x8c430020, 0x8ed00000, 0x1060001c, 0x8ed30010, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, - 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, - 0xac600010, 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448, - 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, - 0x00621825, 0x0e0014cc, 0xaca3001c, 0x24130001, 0x32420004, 0x10400068, - 0x00003821, 0x3c029000, 0x8ec60010, 0x34420001, 0x3c038000, 0x02821025, - 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, - 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, - 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, - 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff, - 0x0a0009da, 0x3442ffff, 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000, - 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064, - 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff, - 0x34a5ffff, 0x00c51021, 0xaf62005c, 0x24070001, 0xaf66004c, 0x8fa20010, - 0x10400003, 0x00000000, 0xaf660050, 0xaf660054, 0x8f620054, 0x14c20005, - 0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, - 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, - 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, - 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, - 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x93620082, 0x30420080, - 0x50400001, 0xa3600081, 0x3c028000, 0x34420001, 0x02821025, 0xaf420020, - 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b821, 0x0e0013c4, 0x00000000, - 0x00403821, 0x00e0b821, 0x8fa30020, 0x10600009, 0x8fa20010, 0x8ec20018, - 0xaf620018, 0x8ec3001c, 0xaf63001c, 0x8ec20020, 0x24170001, 0xaf620058, - 0x8fa20010, 0x10400057, 0x8fa30024, 0x93620023, 0x30420040, 0x10400053, - 0x00000000, 0x16600021, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040001e, - 0x24130001, 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, - 0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, - 0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, - 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, - 0x3c024010, 0x00621825, 0xaca3001c, 0x0e0014cc, 0x24130001, 0x8e420020, - 0x1040001c, 0x8ed00000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, - 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, - 0x8f820018, 0xac400010, 0x8f830018, 0x24020798, 0xac620014, 0x8f850018, - 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, - 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, - 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, - 0x1440fffd, 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001, - 0x02821025, 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30024, 0x10600012, - 0x8fa30018, 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a, - 0x1462000b, 0x8fa30018, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b, - 0x14400005, 0x8fa30018, 0x0e0013c4, 0x00000000, 0x02e2b825, 0x8fa30018, - 0x3062ffff, 0x10400003, 0x32220200, 0x0a000a94, 0x241e0004, 0x10400003, - 0x00000000, 0x241e0040, 0x24170001, 0x12a000d0, 0x32220002, 0x104000cf, - 0x8fa2001c, 0x92c2000a, 0x30420002, 0x5040003b, 0x92c2000a, 0x93620023, - 0x30420008, 0x54400037, 0x92c2000a, 0x3c020800, 0x8c430020, 0x10600023, - 0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000, - 0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040, - 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018, - 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018, - 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, - 0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001, - 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630008, - 0xa3630023, 0xaf420020, 0x92c2000a, 0x30420020, 0x1040008e, 0x8fa2001c, - 0x93620023, 0x30420001, 0x14400035, 0x3c020800, 0x8c430020, 0x10600023, - 0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000, - 0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040, - 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018, - 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018, - 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, - 0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001, - 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630001, - 0xa3630023, 0xaf420020, 0x93620023, 0x30420040, 0x10400052, 0x8fa2001c, - 0x16600020, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040003c, 0x3c029000, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x24020001, - 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, - 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448, - 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, - 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x3c029000, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x3c02008d, - 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, - 0xac600010, 0x8f840018, 0x240207ee, 0xac820014, 0x8f850018, 0x3c026000, - 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, - 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001, - 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x306300bf, - 0xa3630023, 0xaf420020, 0x8fa2001c, 0x1040000e, 0x8fa20014, 0x92c2000a, - 0xa3620082, 0x57c00005, 0x37de0008, 0x8fa30014, 0x10600004, 0x00000000, - 0x37de0008, 0x0a000b75, 0x24170001, 0x0e0012cf, 0x02802021, 0x8fa20014, - 0x10400003, 0x00000000, 0x37de0010, 0x24170001, 0x12e00020, 0x3c029000, - 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, - 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x03c21025, 0xa362007d, - 0x8f640074, 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000, - 0x02802021, 0x0e000470, 0x2405082a, 0x0a000b9b, 0x00000000, 0x8f4201f8, - 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, - 0xaf4301f8, 0x9363003f, 0x24020012, 0x14620004, 0x8fbf004c, 0x0e00140d, - 0x00000000, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c, - 0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008, - 0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184, - 0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824, - 0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b, - 0x3c020100, 0x1062000d, 0x00000000, 0x0a000c2c, 0x00000000, 0x10620027, - 0x3c020400, 0x1062003e, 0x02002021, 0x0a000c2c, 0x00000000, 0x0e000c31, - 0x02002021, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e, - 0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, - 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, - 0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005, - 0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000766, - 0x24055854, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f, - 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, - 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x34420004, 0xa3620023, - 0x93630005, 0x3c048000, 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020, - 0x34840001, 0x02042025, 0x0a000c0a, 0xaf440020, 0x00002821, 0x00003021, - 0x0e000fb1, 0x240708d9, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f, - 0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008, - 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, - 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, - 0x944358ce, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e0014cc, 0xaca3001c, - 0x0a000c2e, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008, - 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021, 0x93640000, - 0x24030020, 0x00021402, 0x10830008, 0x304500ff, 0x3c036018, 0x8c625000, - 0x34420400, 0xac625000, 0x0000000d, 0x00000000, 0x24000955, 0x9363003f, - 0x24020012, 0x14620023, 0x3c029000, 0x34420001, 0x3c038000, 0x00c21025, - 0xaf650178, 0xa365007a, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, - 0x00c31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470, - 0x24050963, 0x0a000c79, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd, - 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a000c79, - 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x8f620178, 0x1045000b, - 0x00000000, 0x8f820000, 0xaf650178, 0x8f660178, 0x8f440180, 0x8f65004c, - 0x8c430000, 0x0060f809, 0x30c600ff, 0x0a000c79, 0x8fbf0010, 0xaf650178, - 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93630000, - 0x24020020, 0x10620005, 0x00000000, 0x93630000, 0x24020030, 0x1462004d, - 0x8fbf0010, 0x93420148, 0x2444ffff, 0x2c830005, 0x10600047, 0x3c020800, - 0x24425800, 0x00041880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000, - 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001, 0xaf62000c, 0x0e000d59, - 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x8f62000c, 0x0a000cca, 0x00000000, - 0x97630010, 0x8f420144, 0x14430006, 0x24020001, 0xa7620010, 0x0e00137a, - 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620010, 0x0a000cca, 0x00000000, - 0x97630012, 0x8f420144, 0x14430006, 0x24020001, 0xa7620012, 0x0e001395, - 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620012, 0x0a000cca, 0x00000000, - 0x97630014, 0x8f420144, 0x14430006, 0x24020001, 0xa7620014, 0x0e0013bb, - 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620014, 0x0a000cca, 0x00000000, - 0x97630016, 0x8f420144, 0x14430006, 0x24020001, 0xa7620016, 0x0e0013be, - 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620016, 0x14400006, 0x8fbf0010, - 0x3c030800, 0x8c620070, 0x24420001, 0xac620070, 0x8fbf0010, 0x03e00008, - 0x27bd0018, 0x27bdffe0, 0x3c029000, 0xafbf001c, 0xafb20018, 0xafb10014, - 0xafb00010, 0x8f500140, 0x34420001, 0x3c038000, 0x02021025, 0xaf420020, - 0x8f420020, 0x00431024, 0x1440fffd, 0x24020012, 0x24030080, 0xa362003f, - 0xa3630082, 0x93620023, 0x30420040, 0x10400007, 0x00008821, 0x93620023, - 0x24110001, 0x304200bf, 0xa3620023, 0x0a000cf0, 0x3c028000, 0x3c028000, - 0x34420001, 0x3c039000, 0x34630001, 0x3c048000, 0x02021025, 0x02031825, - 0xaf420020, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000, - 0x9362007d, 0x3c038000, 0x34420020, 0xa362007d, 0x8f640074, 0x34630001, - 0x02031825, 0xaf430020, 0x04810006, 0x3c038000, 0x02002021, 0x0e000470, - 0x24050a63, 0x0a000d13, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd, - 0x24020002, 0x3c031000, 0xaf5001c0, 0xa34201c4, 0xaf4301f8, 0x1220003f, - 0x3c120800, 0x8e420020, 0x8f71004c, 0x1040003c, 0x8fbf001c, 0x0e00148e, - 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004, - 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, - 0x8f820018, 0xac510014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, - 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, - 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x8fbf001c, 0x0e00148e, - 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004, - 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, - 0x8f840018, 0x24020a6a, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, - 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019, - 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8fbf001c, 0x8fb20018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x93620081, - 0x3c030800, 0x8c640048, 0x0044102b, 0x14400005, 0x00000000, 0x0e000cd3, - 0x00000000, 0x0a000da4, 0x8fbf0010, 0x93620081, 0x24420001, 0x0e0013c4, - 0xa3620081, 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001, - 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, - 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, - 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, - 0xaf62000c, 0x10e00021, 0x3c029000, 0x8f450140, 0x34420001, 0x3c038000, - 0x00a21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, - 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, - 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470, - 0x24050a92, 0x0a000da4, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd, - 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010, - 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024, - 0xafb40020, 0xafb20018, 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800, - 0x8f520100, 0x30420001, 0x104000da, 0x00000000, 0x8e700018, 0x8f630054, - 0x2602ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000, - 0x2400015c, 0x0a000dea, 0x00008821, 0x8f62004c, 0x02021023, 0x18400028, - 0x00008821, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff, - 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800, - 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023, - 0x30420005, 0x0a000dea, 0x34510004, 0x27660100, 0x00041080, 0x00c21021, - 0x8c430000, 0x02031823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9, - 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005, - 0x24420001, 0x0a000dea, 0xac620094, 0x24110004, 0x32220001, 0x1040001e, - 0x8e820020, 0x1040001d, 0x32220004, 0x0e00148e, 0x00000000, 0x8f820018, - 0xac520000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, 0xac600008, - 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac500014, - 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, - 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc, 0xaca3001c, - 0x32220004, 0x10400081, 0x00003821, 0x3c029000, 0x34420001, 0x3c038000, - 0x02421025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, - 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, - 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064, - 0x3c023fff, 0x0a000e37, 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011, - 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, - 0xaf700064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x02051021, - 0x3c053fff, 0x34a5ffff, 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c, - 0x8f620054, 0x16020005, 0x00000000, 0x93620023, 0x30420040, 0x10400017, - 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068, - 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, - 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, - 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, - 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000, 0x34420001, - 0x02421025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, 0x00000000, - 0x0e0013c4, 0x00000000, 0x00403821, 0x10e0001f, 0x3c029000, 0x34420001, - 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, - 0x02431825, 0xaf430020, 0x04810006, 0x3c038000, 0x02402021, 0x0e000470, - 0x24050b3d, 0x0a000e8d, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd, - 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b, - 0x9343010b, 0x8e820020, 0x27500100, 0x38630006, 0x10400029, 0x2c710001, - 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, - 0x96020008, 0xac820004, 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018, - 0x3c026000, 0x8c434448, 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010, - 0x8f850018, 0x8e030020, 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018, - 0x00021400, 0x00431025, 0xac820018, 0x12200005, 0x3c020800, 0x944358ce, - 0x8f840018, 0x0a000eb8, 0x3c024013, 0x944358ce, 0x8f840018, 0x3c024014, - 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8e700014, 0x8f620040, - 0x14500003, 0x00501023, 0x0a000ec3, 0x00001021, 0x28420001, 0x1040003a, - 0x00000000, 0x0e000fae, 0x02002021, 0xaf700040, 0x9362003e, 0x30420001, - 0x1440000b, 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022, - 0x3c020800, 0x8c440098, 0x0064182b, 0x14600025, 0x3c020800, 0x3c029000, - 0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, - 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d, - 0x8f640074, 0x34630001, 0x02431825, 0xaf430020, 0x04810006, 0x3c038000, - 0x02402021, 0x0e000470, 0x24050273, 0x0a000ef6, 0x24020001, 0x8f4201f8, - 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4, - 0xaf4301f8, 0x24020001, 0xa7620012, 0x0a000efe, 0xa3600022, 0x9743007a, - 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012, 0x97420108, 0x8fbf0024, - 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, - 0x30420001, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800, - 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014, - 0x0e00148e, 0x00000000, 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1, - 0x936200c5, 0x8f850018, 0x00031e00, 0x00021400, 0x34420100, 0x00621825, - 0xaca30004, 0x8f840018, 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048, - 0xac62000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f830018, 0x8f620040, - 0x24040001, 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800, - 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825, - 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020, - 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, - 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, - 0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, - 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, - 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018, - 0x3c120800, 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041, - 0xafb10014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, - 0x8f840018, 0x24020100, 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008, - 0x8f840018, 0x8e020018, 0xac82000c, 0x8f830018, 0x96020012, 0xac620010, - 0x8f840018, 0x96020008, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, - 0x24040001, 0x3c020800, 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018, - 0x3c024017, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010, - 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000, - 0x8f820018, 0xac500000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, - 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0xac600014, - 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, - 0x8f850018, 0x3c034015, 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021, - 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, - 0x27bdfff0, 0x03e00008, 0x27bd0010, 0x27bdffd0, 0xafb10014, 0x00808821, - 0xafb40020, 0x00c0a021, 0xafbf0028, 0xafb50024, 0xafb3001c, 0xafb20018, - 0xafb00010, 0x93620023, 0x00e0a821, 0x30420040, 0x1040003e, 0x30b3ffff, - 0x3c120800, 0x8e420020, 0x1040003a, 0x8f70004c, 0x0e00148e, 0x00000000, - 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, - 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, - 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800, - 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010, 0x00621825, - 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001b, 0x00000000, 0x0e00148e, - 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x3c02008d, 0xac820004, - 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, - 0x8f820018, 0xac550014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001, - 0xaca30018, 0x9602000e, 0x8f850018, 0x3c034019, 0x00431025, 0x0e0014cc, - 0xaca2001c, 0x93620023, 0x30420020, 0x14400003, 0x3c120800, 0x1280003f, - 0x3c029000, 0x8e420020, 0x8f70004c, 0x1040003b, 0x3c029000, 0x0e00148e, - 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004, - 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, - 0x8f820018, 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448, - 0x3c020800, 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010, - 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001c, 0x3c029000, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x00131400, - 0xac820004, 0x8f830018, 0xac750008, 0x8f820018, 0xac40000c, 0x8f830018, - 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c036000, 0x8c634448, - 0x24040001, 0xaca30018, 0x9602000e, 0x8f850018, 0x3c03401b, 0x00431025, - 0x0e0014cc, 0xaca2001c, 0x3c029000, 0x34420001, 0x02221025, 0xaf420020, - 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023, - 0x3c028000, 0x34420001, 0x02221025, 0x8fbf0028, 0x8fb50024, 0x8fb40020, - 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023, - 0xaf420020, 0x03e00008, 0x27bd0030, 0x27bdffe0, 0xafb10014, 0x27510100, - 0x3c029000, 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000, - 0xafbf0018, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, - 0xa7600008, 0x8f63005c, 0x3c028000, 0x34420001, 0xaf630148, 0x8f640050, - 0x02021025, 0x3c039000, 0xaf64017c, 0xaf420020, 0x8f450100, 0x34630001, - 0x3c048000, 0x00a31825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, - 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d, 0x8f640074, - 0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, - 0x0e000470, 0x24050de5, 0x0a001093, 0x3c020800, 0x8f4201f8, 0x00431024, - 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, - 0x3c020800, 0x8c430020, 0x1060001e, 0x8fbf0018, 0x0e00148e, 0x00000000, - 0x8f830018, 0xac700000, 0x9622000c, 0x8f840018, 0x00021400, 0xac820004, - 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, - 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, - 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401f, 0x00621825, - 0x0e0014cc, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, - 0x27bd0020, 0x3c020800, 0x24424c3c, 0xaf82000c, 0x03e00008, 0x00000000, - 0x27bdffe8, 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003, - 0x3c020800, 0x0000000d, 0x3c020800, 0x8c430020, 0x10600020, 0x00001021, - 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, - 0x8e02001c, 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018, - 0xac82000c, 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c026000, - 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, - 0x8f840018, 0x3c024012, 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, - 0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, - 0x97430078, 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008, - 0xa7630010, 0x27bdfff0, 0x00001021, 0x03e00008, 0x27bd0010, 0x8f420100, - 0x34420001, 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018, - 0xafb10014, 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020031, 0x00808821, - 0x8f620178, 0x1602002e, 0x00000000, 0x9362007f, 0x1602002b, 0x00000000, - 0x9362007a, 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x240009d2, - 0x0e0013e6, 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825, - 0xa370007a, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000, - 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, 0x02231825, - 0xaf430020, 0x04810006, 0x3c038000, 0x02202021, 0x0e000470, 0x240509dd, - 0x0a001138, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, - 0x3c031000, 0xaf5101c0, 0xa34201c4, 0xaf4301f8, 0x0a001138, 0x8fbf0018, - 0x0000000d, 0x00000000, 0x240009e2, 0x8fbf0018, 0x8fb10014, 0x8fb00010, - 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x30a500ff, 0x3c029000, 0x34420001, - 0x00803821, 0x00e21025, 0x3c038000, 0xafbf0010, 0xaf420020, 0x8f420020, - 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x00a21025, - 0xa362007d, 0x8f640074, 0x34630001, 0x00e31825, 0xaf430020, 0x04810006, - 0x3c038000, 0x00e02021, 0x0e000470, 0x00c02821, 0x0a001161, 0x8fbf0010, - 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4701c0, - 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, - 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014, - 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, - 0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018, - 0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400, - 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, - 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018, - 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014, - 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, - 0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e00148e, 0x00000000, - 0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, - 0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, - 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, - 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018, - 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014, - 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100, - 0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020, - 0x1060003a, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f840018, 0x8e030000, - 0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018, - 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, - 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, - 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e0014cc, - 0xaca3001c, 0x0a0011ff, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015, - 0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020, - 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001, - 0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000766, - 0xaf430020, 0x0a0011ff, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, - 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, - 0x27500100, 0x10600022, 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f840018, - 0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00, - 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, - 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, - 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, - 0x3c02400e, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x0e00122e, 0x8e040000, - 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278, - 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244, - 0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, - 0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c, - 0xafbf001c, 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, - 0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, - 0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, - 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024019, - 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100, - 0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620031, 0x00803021, 0x3c029000, - 0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, - 0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000, - 0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020, - 0x8f420020, 0x00451024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, - 0x34420020, 0xa362007d, 0x8f640074, 0x34630001, 0x00c31825, 0xaf430020, - 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470, 0x24050906, 0x0a0012a1, - 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, - 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a0012a1, 0x8fbf0010, 0x00c02021, - 0x94a5000c, 0x24060001, 0x0e000fb1, 0x2407090e, 0x8fbf0010, 0x03e00008, - 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021, - 0xafb20018, 0x00a09021, 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, - 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, - 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448, - 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024010, 0x00621825, - 0xac83001c, 0x0e0014cc, 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, - 0x93620005, 0x30420001, 0x10400036, 0x00808021, 0x3c029000, 0x34420001, - 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x93620023, 0x34420004, 0xa3620023, 0x93630005, 0x3c048000, - 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020, 0x34840001, 0x02042025, - 0xaf440020, 0x10600020, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f820018, - 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00, 0x00431025, - 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, - 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448, - 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c02400a, 0x00621825, - 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf0014, 0x8fb00010, 0x03e00008, - 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, 0x00808821, - 0xafb20018, 0x00a09021, 0xafb00010, 0x30d000ff, 0x1060002f, 0xafbf001c, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f830018, 0xac700004, - 0x8f820018, 0xac520008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, - 0x9763006a, 0x00032880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, - 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, - 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, - 0x8f830018, 0x2402fffe, 0x00822824, 0x3c026000, 0xac650014, 0x8f840018, - 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024011, - 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014, - 0xafb00010, 0x8f440100, 0x27500100, 0x8f650050, 0x0e0010fc, 0x9206001b, - 0x3c020800, 0x8c430020, 0x1060001d, 0x8e100018, 0x0e00148e, 0x00000000, - 0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f840018, - 0x8f620050, 0xac820008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, - 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018, 0x8c434448, 0x24040001, - 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401c, 0x00621825, - 0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, - 0x8f430238, 0x3c020800, 0x04610013, 0x8c44009c, 0x2406fffe, 0x3c050800, - 0x3c038000, 0x2484ffff, 0x14800009, 0x00000000, 0x97420078, 0x8ca3007c, - 0x24420001, 0x00461024, 0x24630001, 0xa7620010, 0x03e00008, 0xaca3007c, - 0x8f420238, 0x00431024, 0x1440fff3, 0x2484ffff, 0x8f420140, 0x3c031000, - 0xaf420200, 0x03e00008, 0xaf430238, 0x27bdffe8, 0x3c029000, 0xafbf0010, - 0x8f450140, 0x34420001, 0x3c038000, 0x00a21025, 0xaf420020, 0x8f420020, - 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, - 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825, 0xaf430020, 0x04810006, - 0x3c038000, 0x00a02021, 0x0e000470, 0x24050ac7, 0x0a0013b9, 0x8fbf0010, - 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, - 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x0000000d, - 0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x24020001, - 0x03e00008, 0xa7620010, 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001, - 0x38820010, 0x2c420001, 0x00621825, 0x14600003, 0x24020012, 0x14820003, - 0x00000000, 0x03e00008, 0x00001021, 0x9363007e, 0x9362007a, 0x14620006, - 0x00000000, 0x9363007e, 0x24020001, 0x24630001, 0x03e00008, 0xa363007e, - 0x9362007e, 0x8f630178, 0x304200ff, 0x14430006, 0x00000000, 0x9363000b, - 0x24020001, 0x24630001, 0x03e00008, 0xa363000b, 0x03e00008, 0x00001021, - 0x9362000b, 0x10400023, 0x00001021, 0xa360000b, 0x9362003f, 0x304400ff, - 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825, 0x14600017, - 0x00001821, 0x24020012, 0x10820014, 0x00000000, 0x9363007e, 0x9362007a, - 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001, 0xa362007e, - 0x03e00008, 0x00601021, 0x9362007e, 0x8f630178, 0x304200ff, 0x14430005, - 0x00001821, 0x9362000b, 0x24030001, 0x24420001, 0xa362000b, 0x03e00008, - 0x00601021, 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc, - 0x8f6200cc, 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008, - 0xa7640016, 0x3c020800, 0x8c430020, 0x27bdffe8, 0x1060001b, 0xafbf0010, - 0x0e00148e, 0x00000000, 0x8f820018, 0xac400000, 0x8f830018, 0xac600004, - 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, - 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800, - 0xac830018, 0x944358ce, 0x8f840018, 0x3c024020, 0x00621825, 0xac83001c, - 0x0e0014cc, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, - 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00a08021, 0xafb10014, 0x00c08821, - 0xafb20018, 0x00e09021, 0x1060001e, 0xafbf001c, 0x0e00148e, 0x00000000, - 0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f820018, - 0xac510008, 0x8f830018, 0xac72000c, 0x8f840018, 0x8fa20030, 0xac820010, - 0x8f830018, 0x8fa20034, 0xac620014, 0x8f840018, 0x3c026000, 0x8c434448, - 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c0240c9, 0x00621825, - 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x8c430020, 0x27bdffe8, - 0xafb00010, 0x27500100, 0x1060001d, 0xafbf0014, 0x0e00148e, 0x00000000, - 0x8f830018, 0x8e020004, 0xac620000, 0x8f840018, 0x8e020018, 0xac820004, - 0x8f850018, 0x8e020000, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, - 0xac400010, 0x8f830018, 0xac600014, 0x8f820018, 0xac400018, 0x96030008, - 0x3c020800, 0x944458ce, 0x8f850018, 0x00031c00, 0x00641825, 0x24040001, - 0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, - 0x3c060800, 0x24c558c0, 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a, - 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d, - 0x00000000, 0x2400005a, 0x0a0014a3, 0x24020001, 0x8f820014, 0x0062102b, - 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400, - 0x3c07000a, 0x3c020800, 0x244558c0, 0x94a9000a, 0x8f880014, 0x03471021, - 0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023, - 0x00021400, 0x00021403, 0x04410006, 0x0048102b, 0x0000000d, 0x00000000, - 0x2400005a, 0x0a0014be, 0x24020001, 0x14400002, 0x00001021, 0x24020001, - 0x304200ff, 0x1440ffec, 0x03471021, 0x24c458c0, 0x8c820010, 0xaf420038, - 0x8c830014, 0x3c020005, 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018, - 0x03e00008, 0x00000000, 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800, - 0x24e858c0, 0xafbf001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a, - 0x8d060014, 0x00009021, 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020, - 0x24630001, 0xaf820010, 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000, - 0x04c10007, 0xad030014, 0x00621024, 0x14400005, 0x262258c0, 0x8d020010, - 0x24420001, 0xad020010, 0x262258c0, 0x9444000a, 0x94450018, 0x0010102b, - 0x00a41826, 0x2c630001, 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010, - 0x24120001, 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000, - 0x00000000, 0x27450400, 0x8f420000, 0x30420010, 0x1040fffd, 0x262258c0, - 0x9444000a, 0x94430018, 0xaf800010, 0xaf850018, 0x14830012, 0x262758c0, - 0x0e00155a, 0x00000000, 0x1600000e, 0x262758c0, 0x0e00148e, 0x00000000, - 0x0a001517, 0x262758c0, 0x00041c00, 0x00031c03, 0x00051400, 0x00021403, - 0x00621823, 0x18600002, 0x3c026000, 0xac400808, 0x262758c0, 0x94e2000e, - 0x94e3000c, 0x24420001, 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e, - 0x12000005, 0x3c02000a, 0x94e2000a, 0xa74200a2, 0x0a001554, 0x02401021, - 0x03421821, 0x94640006, 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03, - 0x04610006, 0xa4e40006, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001536, - 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021, 0x24020001, - 0x304200ff, 0x1040001b, 0x3c020800, 0x3c06000a, 0x244558c0, 0x94a8000a, - 0x8f870014, 0x03461021, 0x94430006, 0x00402021, 0xa4a30006, 0x94820006, - 0xa4a20006, 0x01021023, 0x00021400, 0x00021403, 0x04410006, 0x0047102b, - 0x0000000d, 0x00000000, 0x2400005a, 0x0a001550, 0x24020001, 0x14400002, - 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021, - 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, - 0x3c020800, 0x244558c0, 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0, - 0x00832021, 0xaf44003c, 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008, - 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x8f420000, 0x30420020, - 0x1040fffd, 0x00000000, 0x8f430400, 0x24c658c0, 0xacc30010, 0x8f420404, - 0x3c030020, 0xacc20014, 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a, - 0x94c5001e, 0x00832021, 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002, - 0xa4c40018, 0xa4c0001a, 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006, - 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, - 0x27430400, 0x8f420000, 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010, - 0xaf830018, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800, - 0x261058c0, 0x3c05000a, 0x02002021, 0x03452821, 0xafbf0014, 0x0e0015b0, - 0x2406000a, 0x96020002, 0x9603001e, 0x3042000f, 0x24420003, 0x00431804, - 0x24027fff, 0x0043102b, 0xaf830014, 0x10400004, 0x00000000, 0x0000000d, - 0x00000000, 0x24000043, 0x0e00155a, 0x00000000, 0x8fbf0014, 0x8fb00010, - 0x03e00008, 0x27bd0018, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, - 0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, - 0x0a0015c1, 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004, - 0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c036000, - 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582, 0x00042302, 0x308403ff, - 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b, 0x00451025, 0x1440000d, - 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c, 0xaf420030, 0x00000000, - 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030, - 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050, 0x34420004, 0xaf440038, - 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020, - 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008, 0x00000000, 0x00000000}; +static u8 bnx2_COM_b06FwText[] = { + 0x1f, 0x8b, 0x08, 0x08, 0x09, 0x83, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0x5b, 0x7d, 0x6c, + 0x5b, 0xd7, 0x75, 0x3f, 0xef, 0xf1, 0x51, 0x7a, 0x96, 0x68, 0xf9, 0x99, + 0x7e, 0x96, 0x59, 0x4f, 0xb1, 0x49, 0xf1, 0xc9, 0xd2, 0x62, 0x2d, 0x63, + 0x34, 0x35, 0xd1, 0x3a, 0x26, 0x66, 0x48, 0xda, 0x71, 0x36, 0x67, 0xa0, + 0x1d, 0x05, 0x51, 0x51, 0xaf, 0xd0, 0x48, 0xd9, 0xcd, 0xb2, 0x0c, 0x73, + 0x96, 0xb4, 0x70, 0xbc, 0xb4, 0xa1, 0x25, 0x79, 0xf5, 0x06, 0x45, 0xcf, + 0xb3, 0x34, 0x39, 0xc0, 0x82, 0x41, 0x10, 0x9d, 0x3a, 0x7f, 0x30, 0xa5, + 0xed, 0x7c, 0x19, 0xe8, 0x12, 0x29, 0xb2, 0x93, 0xb5, 0x43, 0xd0, 0xa6, + 0x68, 0xff, 0xe8, 0x8a, 0x6e, 0x30, 0x52, 0x0c, 0xf3, 0x3a, 0xa0, 0x30, + 0xfa, 0xc7, 0xe6, 0x2d, 0x1f, 0xdc, 0xef, 0xdc, 0x77, 0x1f, 0xf9, 0x48, + 0x51, 0x96, 0x1c, 0x34, 0x5d, 0xb7, 0x99, 0x80, 0xf0, 0xde, 0xbd, 0xf7, + 0xbc, 0x7b, 0xcf, 0x3d, 0xdf, 0xe7, 0xdc, 0xab, 0x5f, 0x53, 0xa9, 0x85, + 0xe4, 0x6f, 0x2d, 0xfe, 0xc2, 0x7f, 0xf4, 0xc7, 0xb9, 0xdb, 0x3e, 0x7d, + 0x5b, 0x1f, 0x5e, 0x07, 0x54, 0xdd, 0xaf, 0x72, 0xbf, 0x0f, 0x7f, 0x26, + 0xfe, 0xfa, 0xe4, 0x7b, 0xa3, 0x9f, 0x81, 0xbf, 0x2b, 0x18, 0x1c, 0xfe, + 0x09, 0x91, 0xb2, 0x0c, 0x8c, 0xf7, 0x57, 0x2e, 0x5f, 0x7f, 0x9c, 0x17, + 0x0e, 0xaf, 0x62, 0x9e, 0x9b, 0xbf, 0x9b, 0xbf, 0x9b, 0xbf, 0x9b, 0xbf, + 0x9b, 0xbf, 0x9b, 0xbf, 0x9b, 0xbf, 0xff, 0x3f, 0x3f, 0x9f, 0x13, 0x72, + 0x88, 0x98, 0x85, 0xff, 0x48, 0x57, 0xe3, 0x89, 0xa1, 0xa4, 0x45, 0xba, + 0x2f, 0x7e, 0x65, 0x28, 0x67, 0x11, 0x25, 0x8a, 0xdb, 0xc3, 0x29, 0xfa, + 0xb0, 0x9c, 0x37, 0x35, 0xe2, 0xfe, 0x5b, 0xe2, 0x1f, 0x3c, 0xfd, 0xfa, + 0x9d, 0x91, 0xab, 0xb3, 0x3e, 0xd2, 0x8d, 0xf8, 0xcb, 0xba, 0xb1, 0x8d, + 0xf4, 0x0e, 0x7c, 0xf3, 0x5c, 0xf7, 0x7f, 0xa8, 0xd4, 0xe6, 0xce, 0x75, + 0xa5, 0xfc, 0x7a, 0x37, 0xe5, 0x37, 0xc7, 0x75, 0x52, 0xe3, 0x5d, 0x3f, + 0x48, 0xfa, 0x8c, 0x61, 0x5f, 0xdc, 0xa0, 0xf9, 0x12, 0x65, 0x0e, 0x4c, + 0xf0, 0x1a, 0xb1, 0x75, 0xf7, 0x62, 0x2e, 0x2d, 0x3e, 0x3c, 0xf4, 0x67, + 0xd6, 0xd3, 0x65, 0xd5, 0xb2, 0x7a, 0xe6, 0x28, 0x30, 0xf0, 0x7c, 0x3f, + 0xc6, 0x8b, 0x91, 0x1e, 0xa2, 0x3b, 0x49, 0xb5, 0xf2, 0x01, 0x9f, 0xa5, + 0x53, 0xb2, 0x64, 0x51, 0xaa, 0x44, 0xf4, 0x77, 0x45, 0x85, 0x9e, 0xb7, + 0xda, 0x69, 0xae, 0xf7, 0x83, 0x72, 0x02, 0xb8, 0xbc, 0x6d, 0x0d, 0x0f, + 0x8d, 0x5b, 0x3c, 0x57, 0x7c, 0x9d, 0x83, 0x6f, 0x6f, 0x5b, 0xce, 0xd2, + 0x68, 0xb4, 0xc8, 0x7d, 0xbd, 0x2d, 0xdc, 0xe7, 0x8f, 0x3f, 0x1c, 0x7c, + 0xde, 0x0a, 0xc8, 0xbe, 0x1f, 0xa5, 0x92, 0x98, 0x6f, 0xac, 0xc8, 0xb0, + 0xcf, 0xde, 0x91, 0xb3, 0x4c, 0xd9, 0x6f, 0xc5, 0x93, 0x56, 0x08, 0xfd, + 0x1d, 0x72, 0x2c, 0xbd, 0x2e, 0x67, 0x59, 0x72, 0xac, 0x88, 0x6f, 0x7a, + 0x65, 0xff, 0x3b, 0xa9, 0x9c, 0x15, 0x93, 0xfd, 0x57, 0x93, 0x49, 0xab, + 0x5f, 0xf6, 0x1f, 0xbe, 0x2b, 0x67, 0xc5, 0x65, 0xff, 0xf7, 0x81, 0x8b, + 0x41, 0xc7, 0x8a, 0x61, 0xfc, 0x25, 0x30, 0xfe, 0x9a, 0x41, 0x6d, 0x19, + 0x8c, 0x61, 0xef, 0xb6, 0x4e, 0x97, 0x7d, 0x21, 0x7a, 0xbd, 0xfb, 0x32, + 0x68, 0x63, 0xd0, 0xd9, 0x12, 0x29, 0x99, 0xee, 0x10, 0x68, 0x62, 0xd2, + 0xb9, 0x52, 0x2b, 0xf9, 0x4e, 0xfa, 0xb0, 0xe7, 0xcf, 0x51, 0xd6, 0xd4, + 0x69, 0xfd, 0x8c, 0x42, 0x9d, 0x7d, 0x6b, 0x28, 0x61, 0xe4, 0x29, 0xd5, + 0x8d, 0x28, 0x6e, 0xd2, 0x24, 0x6d, 0x66, 0x71, 0xbd, 0x8a, 0x1e, 0x95, + 0x22, 0xa1, 0x2c, 0x28, 0x3c, 0x72, 0xfa, 0x5d, 0x8e, 0x39, 0xb1, 0x26, + 0xff, 0x85, 0x29, 0x35, 0x71, 0x2b, 0x0d, 0x1b, 0x8c, 0x0f, 0x80, 0x05, + 0x1f, 0x74, 0x25, 0x79, 0x2a, 0x44, 0xc7, 0xec, 0x80, 0x92, 0x3a, 0x75, + 0x37, 0x25, 0x63, 0x64, 0xaa, 0xd4, 0x25, 0xbe, 0x2d, 0x14, 0x43, 0x34, + 0x6e, 0x93, 0x92, 0xb4, 0x99, 0x5e, 0xed, 0x18, 0x6f, 0x13, 0xb0, 0xe8, + 0xeb, 0xf0, 0x51, 0x97, 0x91, 0x22, 0x9d, 0x71, 0x46, 0x7f, 0x50, 0x49, + 0x8b, 0x39, 0x44, 0x7f, 0x78, 0x8c, 0x02, 0x74, 0xba, 0x68, 0x4a, 0xd8, + 0x72, 0x39, 0x19, 0x33, 0x00, 0x07, 0xda, 0xd9, 0x26, 0x0d, 0xe3, 0x39, + 0x6a, 0xf3, 0xfa, 0x21, 0xc8, 0xcc, 0xb7, 0x87, 0xb2, 0xd3, 0x62, 0xbe, + 0xb0, 0x2f, 0xce, 0xf3, 0x75, 0x00, 0xee, 0x1d, 0xe0, 0xa5, 0x90, 0x26, + 0x78, 0x95, 0xa0, 0xec, 0x84, 0x02, 0x79, 0xc2, 0x53, 0xd0, 0x2d, 0x0d, + 0xfc, 0x35, 0xb2, 0xfa, 0x14, 0xca, 0x59, 0x9b, 0x28, 0x6f, 0xa0, 0x5d, + 0xbc, 0xa0, 0x26, 0xed, 0x66, 0x4a, 0x69, 0x61, 0xec, 0x5f, 0xc8, 0x0a, + 0x8d, 0xe1, 0x1b, 0xd5, 0x62, 0x98, 0x9f, 0x61, 0xef, 0xc3, 0x82, 0xfe, + 0x4d, 0xf1, 0xfd, 0x74, 0x69, 0x22, 0xaf, 0x26, 0x4b, 0xed, 0xe4, 0x9b, + 0x89, 0x40, 0x9a, 0xc7, 0xd5, 0xd4, 0x19, 0x8d, 0xfc, 0x93, 0x0a, 0x41, + 0x3e, 0x0c, 0x5f, 0xfc, 0xb8, 0xba, 0xb3, 0x74, 0x41, 0x4d, 0x95, 0xf8, + 0x1b, 0xc0, 0x16, 0x55, 0xd0, 0x96, 0xdf, 0xb7, 0x83, 0x96, 0x34, 0xac, + 0xc6, 0x75, 0x3d, 0x51, 0x64, 0x99, 0xe5, 0x6f, 0xc1, 0x0f, 0xec, 0xe5, + 0x9c, 0x0d, 0xfe, 0x08, 0x7e, 0x85, 0xc1, 0xaf, 0x6f, 0x82, 0x5f, 0xfd, + 0xe0, 0x53, 0x8c, 0xde, 0x28, 0xf5, 0xd2, 0x6b, 0xa5, 0x1e, 0x7a, 0x15, + 0x32, 0xf9, 0x4a, 0x29, 0x4c, 0x2f, 0x97, 0x3a, 0xe8, 0xa5, 0x52, 0x88, + 0xce, 0x0b, 0x1e, 0xa6, 0x21, 0xff, 0x82, 0xaf, 0xfa, 0x26, 0xf0, 0xa4, + 0x1d, 0x3c, 0x59, 0x0f, 0x79, 0xd9, 0x08, 0xf9, 0x9b, 0xee, 0xd6, 0x69, + 0xaa, 0x9b, 0x12, 0x41, 0xf4, 0x6f, 0x89, 0x6b, 0x82, 0x4e, 0x1a, 0xc6, + 0xc7, 0x26, 0xfc, 0x94, 0x32, 0x4e, 0xd3, 0x7b, 0x93, 0x1a, 0x8d, 0x95, + 0xa6, 0x36, 0x3a, 0x7c, 0xe3, 0xf6, 0x2c, 0x5d, 0x44, 0x5f, 0xca, 0x98, + 0xa5, 0x4b, 0xdb, 0x54, 0x1a, 0x9d, 0xfe, 0x1b, 0x4a, 0x9e, 0x39, 0x4d, + 0x3f, 0xfe, 0x3a, 0x51, 0x06, 0x34, 0x51, 0xfb, 0x7e, 0x5a, 0x4e, 0x18, + 0xa0, 0x45, 0x5f, 0xaf, 0x90, 0x08, 0xb5, 0x8f, 0x79, 0x19, 0x86, 0xae, + 0x68, 0x4a, 0xca, 0x7e, 0x01, 0xfa, 0xd2, 0xaa, 0x24, 0xa7, 0x88, 0x72, + 0x53, 0x65, 0xca, 0xc5, 0xfc, 0xf4, 0x98, 0x51, 0xa6, 0x74, 0xac, 0x89, + 0xbe, 0x68, 0xb4, 0xd3, 0x68, 0xef, 0x6f, 0xf8, 0xdc, 0x5c, 0x65, 0xba, + 0xd4, 0x8f, 0x77, 0xee, 0x23, 0x9a, 0x12, 0xef, 0x4e, 0x7f, 0xbe, 0xe4, + 0xa7, 0x84, 0x99, 0x0f, 0x69, 0xf4, 0x8e, 0xcf, 0xc1, 0x29, 0xe1, 0x8e, + 0x81, 0x57, 0xc3, 0xb0, 0x0f, 0x8e, 0x0c, 0x66, 0x27, 0xd6, 0x5c, 0x4b, + 0x88, 0x6e, 0xc0, 0x0b, 0xd9, 0xd3, 0x18, 0x8f, 0x61, 0x25, 0x6e, 0x52, + 0xa7, 0xd0, 0x8d, 0x7e, 0xc0, 0x0c, 0x28, 0xfb, 0x4a, 0xcc, 0x6b, 0xbc, + 0x17, 0x19, 0xd7, 0xcd, 0x80, 0xd5, 0xf0, 0x4c, 0x48, 0x9c, 0xbd, 0x78, + 0xf2, 0x5c, 0x8c, 0x27, 0x3f, 0x7f, 0xcf, 0x83, 0xe7, 0xe7, 0x2b, 0xef, + 0x53, 0x9e, 0xf7, 0x7c, 0xe9, 0x4f, 0x03, 0x0e, 0x7e, 0x4c, 0xcf, 0x01, + 0x1a, 0x9d, 0x38, 0x2c, 0xd7, 0xc2, 0x7b, 0x91, 0xd7, 0x38, 0x0d, 0x3a, + 0x09, 0xc8, 0x15, 0xd6, 0x3a, 0xec, 0x59, 0xeb, 0x49, 0xcf, 0x5a, 0x4f, + 0x7a, 0xd6, 0xca, 0x83, 0xb6, 0xb4, 0x4e, 0xb5, 0xfc, 0xd0, 0x51, 0xee, + 0x39, 0x8e, 0x39, 0x9f, 0x03, 0x5f, 0xbe, 0x0a, 0x98, 0x38, 0x2d, 0xda, + 0xa0, 0xc7, 0x94, 0x46, 0x7b, 0x4d, 0x7e, 0x7f, 0xb1, 0xd5, 0xc1, 0x8b, + 0xdf, 0x2f, 0x48, 0x9c, 0x5a, 0x1d, 0xb8, 0xd2, 0x15, 0xa1, 0xff, 0xf3, + 0x25, 0xd6, 0x4f, 0x8a, 0xf9, 0x2c, 0x3a, 0x94, 0x8e, 0xb5, 0xd3, 0x98, + 0xa1, 0xc4, 0x46, 0x7b, 0x9a, 0x99, 0x8e, 0x09, 0xd5, 0x6a, 0x85, 0x0e, + 0x50, 0x58, 0x65, 0xdb, 0x25, 0xf0, 0x7b, 0x49, 0xe2, 0x61, 0x70, 0x3b, + 0xa3, 0x5a, 0xc1, 0xba, 0x7e, 0x96, 0xdf, 0x57, 0xf0, 0xce, 0x32, 0x9c, + 0xd4, 0x9c, 0xb5, 0x5f, 0x45, 0x9b, 0xed, 0xce, 0x66, 0xd9, 0x76, 0xc7, + 0xff, 0xa0, 0xa9, 0xb6, 0xfd, 0x05, 0xb3, 0xb6, 0xed, 0xea, 0x82, 0xd7, + 0x66, 0xf1, 0xde, 0xc2, 0xe4, 0xb3, 0x58, 0x8e, 0xfc, 0xc0, 0x35, 0x06, + 0x3d, 0x6c, 0x96, 0x38, 0x7c, 0x4b, 0xe2, 0x00, 0x5c, 0x01, 0x37, 0x5a, + 0xe2, 0x6f, 0x04, 0x4b, 0xea, 0xda, 0x4c, 0x43, 0xf7, 0x7d, 0xad, 0x18, + 0xbf, 0xec, 0xe3, 0x75, 0xdc, 0x27, 0x29, 0x69, 0xe8, 0xc9, 0xd8, 0xb4, + 0x46, 0xd9, 0xd8, 0x26, 0x21, 0xd7, 0xd9, 0x58, 0xd5, 0x06, 0x8c, 0x4e, + 0xd4, 0xdb, 0x00, 0xfe, 0x8e, 0x6d, 0x80, 0xa3, 0xfb, 0x63, 0xd3, 0x6c, + 0x0b, 0x1c, 0xdd, 0x3f, 0x36, 0xc1, 0x36, 0x41, 0xcc, 0x09, 0xfd, 0x67, + 0x3b, 0xe0, 0xda, 0x00, 0xfe, 0x86, 0x6d, 0x80, 0x0f, 0xf2, 0xcd, 0xf3, + 0xb9, 0x6b, 0x8f, 0xd7, 0xcd, 0x3b, 0xce, 0xb6, 0x45, 0xd9, 0xd9, 0xcd, + 0x30, 0xc7, 0xb1, 0x76, 0x80, 0x0a, 0xd3, 0xcc, 0xc3, 0x48, 0xe8, 0x08, + 0x1d, 0x17, 0x36, 0xef, 0xf4, 0x04, 0x25, 0x0e, 0x9e, 0x18, 0xa0, 0x34, + 0x6c, 0xc0, 0xdc, 0xc4, 0xb5, 0x32, 0xf8, 0x78, 0x47, 0x13, 0x59, 0xb0, + 0x75, 0xf0, 0x93, 0xfd, 0x7e, 0xf2, 0xc5, 0xe3, 0x90, 0xb7, 0x98, 0xf0, + 0x5d, 0xd5, 0x9f, 0xa6, 0xed, 0xaa, 0x69, 0x37, 0xc1, 0x3f, 0x62, 0xde, + 0xfe, 0x98, 0x90, 0x4d, 0xef, 0x2f, 0x09, 0x1b, 0x94, 0x8c, 0x7d, 0x08, + 0xf9, 0x75, 0x69, 0xe4, 0xea, 0x1f, 0xdb, 0xfa, 0x2b, 0x1e, 0x1f, 0xb2, + 0x05, 0x76, 0xdf, 0x84, 0x3c, 0xb9, 0x76, 0x9f, 0xed, 0x71, 0x88, 0x6d, + 0x26, 0xf4, 0x8d, 0x6d, 0x70, 0x80, 0xd4, 0x19, 0x4d, 0xda, 0x69, 0x5d, + 0xda, 0xe9, 0x00, 0x6c, 0x34, 0xb7, 0x0d, 0xd9, 0x36, 0x45, 0x1b, 0xf6, + 0x1a, 0xf6, 0x70, 0x77, 0x3a, 0x35, 0xc1, 0xfe, 0x10, 0xbe, 0x7b, 0x86, + 0x75, 0xf8, 0xdb, 0x43, 0x23, 0xd3, 0xc2, 0x07, 0xb0, 0xff, 0x80, 0x65, + 0x66, 0x1b, 0xce, 0xb6, 0x1c, 0xfb, 0x2e, 0x62, 0xdd, 0x8a, 0xad, 0x64, + 0x39, 0xf1, 0xe2, 0xc5, 0x38, 0xad, 0x21, 0xf5, 0xa4, 0x43, 0x6b, 0x35, + 0xfe, 0xa8, 0x46, 0x2d, 0x4c, 0x63, 0xc6, 0x7f, 0x2b, 0x70, 0xe6, 0x7d, + 0xfd, 0x4f, 0xe0, 0xcc, 0xeb, 0xd6, 0xe3, 0x4d, 0x7a, 0x6b, 0xfc, 0xac, + 0xfe, 0xf0, 0x33, 0xa4, 0x37, 0xc7, 0xcf, 0xd2, 0xbf, 0x58, 0x74, 0x9f, + 0x0e, 0x3f, 0xdb, 0xad, 0xc0, 0xcf, 0x16, 0xa1, 0xef, 0x53, 0x3a, 0x1d, + 0x3c, 0x15, 0xc9, 0xfc, 0x2b, 0x45, 0x61, 0x3f, 0x76, 0xd0, 0xc8, 0x94, + 0x42, 0x7a, 0x17, 0xb5, 0xc3, 0x7f, 0xf4, 0x37, 0x61, 0xfe, 0x5d, 0x44, + 0x9b, 0x1d, 0xbf, 0xd9, 0x15, 0x1e, 0x05, 0xff, 0xd3, 0x2f, 0x7e, 0x05, + 0xdf, 0x3c, 0x4d, 0x07, 0xa7, 0x0e, 0x2b, 0x39, 0xfb, 0x08, 0xe0, 0x97, + 0x83, 0xd5, 0x01, 0x9b, 0x07, 0xec, 0x97, 0x31, 0xef, 0xd3, 0xa4, 0xdf, + 0x1e, 0x19, 0x48, 0x28, 0xc0, 0xe3, 0x45, 0x01, 0x2f, 0x7d, 0x71, 0x97, + 0xb1, 0x53, 0xf0, 0x3f, 0x40, 0xef, 0x15, 0x2f, 0x80, 0xbe, 0xbd, 0xf0, + 0x39, 0x91, 0x67, 0x61, 0x93, 0xe1, 0x8f, 0x22, 0x57, 0x31, 0x2d, 0x7c, + 0x11, 0x29, 0x0f, 0x76, 0xa7, 0x41, 0xef, 0x38, 0xfc, 0xd3, 0x00, 0xfc, + 0x53, 0x0c, 0xbe, 0xa9, 0x07, 0x7e, 0xc9, 0x82, 0x5f, 0x0a, 0x83, 0x1f, + 0x06, 0xcd, 0xc2, 0x47, 0xcd, 0x42, 0xfe, 0xe7, 0x66, 0x48, 0x19, 0x04, + 0xad, 0xcf, 0xc1, 0x3f, 0x26, 0x63, 0x77, 0x42, 0xcf, 0x22, 0x17, 0x66, + 0xd5, 0x41, 0xca, 0xc1, 0x9f, 0x77, 0x6e, 0x8b, 0x62, 0xbd, 0x26, 0x4a, + 0x84, 0x5c, 0x1d, 0xe5, 0xdf, 0x7e, 0x85, 0xac, 0x7f, 0x06, 0xef, 0x22, + 0x61, 0xa2, 0x3d, 0x94, 0xb5, 0xa3, 0x46, 0xa7, 0xda, 0x03, 0x18, 0x6e, + 0x87, 0x95, 0x03, 0x53, 0x11, 0x05, 0xfb, 0x03, 0xcd, 0x27, 0x60, 0xeb, + 0xcb, 0x34, 0x1e, 0x63, 0x3d, 0x29, 0xd3, 0xf3, 0xb1, 0xc8, 0x40, 0x9e, + 0x5a, 0xe9, 0x98, 0x39, 0x21, 0x7c, 0xbc, 0x16, 0x3f, 0x21, 0x74, 0x2c, + 0x67, 0xe1, 0x59, 0xec, 0x54, 0xb2, 0x53, 0xbc, 0x7e, 0x14, 0x5a, 0xee, + 0xc7, 0x93, 0xe7, 0x07, 0xdd, 0xfa, 0x49, 0x39, 0xd8, 0x9d, 0x87, 0x77, + 0x88, 0x18, 0x8b, 0x58, 0x39, 0x35, 0x11, 0x0d, 0x45, 0x55, 0x8d, 0x86, + 0x35, 0x85, 0x46, 0x61, 0x6f, 0xd2, 0xb1, 0xff, 0x2c, 0x1f, 0x33, 0x79, + 0xbc, 0x99, 0xbe, 0x2a, 0xfc, 0x0d, 0xd6, 0x2e, 0x4c, 0x63, 0x5d, 0x3f, + 0xf8, 0xcb, 0xeb, 0xf2, 0x3c, 0x68, 0xc3, 0xf6, 0x6b, 0x56, 0xe4, 0xd9, + 0x3c, 0xed, 0x00, 0x6d, 0xd9, 0x66, 0xc1, 0x3e, 0x0c, 0x60, 0xed, 0x5e, + 0xd8, 0x4f, 0x3c, 0x93, 0xbd, 0x1c, 0x07, 0x05, 0x68, 0xd8, 0x64, 0x79, + 0xd4, 0xe5, 0x98, 0xe9, 0x19, 0xf3, 0xcb, 0xb1, 0x20, 0xfe, 0xe0, 0x7f, + 0x4d, 0x96, 0x19, 0x6e, 0x73, 0x4c, 0xc6, 0x34, 0x09, 0xd3, 0xdc, 0x64, + 0x02, 0x34, 0x8b, 0x9c, 0x4d, 0x10, 0xd3, 0x0c, 0x46, 0x7b, 0x7f, 0x82, + 0xbe, 0x64, 0xaf, 0xf7, 0x3b, 0xb6, 0xb0, 0x55, 0x49, 0xc1, 0x17, 0xa8, + 0x56, 0x0b, 0x7c, 0x45, 0x98, 0x5e, 0x15, 0xb0, 0x64, 0xa8, 0xf1, 0x68, + 0xe8, 0x4b, 0x74, 0xab, 0xb0, 0x11, 0x09, 0xc3, 0x4b, 0xe3, 0xff, 0x52, + 0xc9, 0x72, 0xbf, 0x69, 0xa5, 0xec, 0x20, 0xf3, 0x89, 0xd7, 0x33, 0x68, + 0xae, 0xe4, 0xbc, 0xfb, 0x10, 0xa3, 0x16, 0x60, 0x6b, 0xce, 0x4f, 0xaa, + 0xf4, 0xf8, 0x1d, 0xf0, 0x65, 0xb1, 0x6d, 0x58, 0xcb, 0xc4, 0x78, 0x1e, + 0x6d, 0x15, 0x6d, 0xe8, 0x99, 0x11, 0x02, 0x8f, 0xb9, 0x9f, 0xe1, 0x4c, + 0xfc, 0xbd, 0xcf, 0xb1, 0x75, 0x3e, 0xab, 0xde, 0x4a, 0x14, 0x64, 0x7a, + 0xc5, 0x40, 0x2b, 0xcb, 0x50, 0xd5, 0x6d, 0xc2, 0x5f, 0x3b, 0xb6, 0xc4, + 0x82, 0x2e, 0xc2, 0xe6, 0xf6, 0x79, 0x75, 0x91, 0xe3, 0x09, 0x57, 0x17, + 0x23, 0xa1, 0x84, 0x0a, 0x5b, 0xdc, 0xa7, 0xd1, 0x09, 0xd1, 0x56, 0x28, + 0x31, 0x18, 0x09, 0x2d, 0xa8, 0x1c, 0x4b, 0x33, 0x6c, 0x18, 0xf1, 0x4a, + 0x40, 0xc2, 0x22, 0x9e, 0xb3, 0xdd, 0x98, 0x30, 0x84, 0x7e, 0x53, 0xf4, + 0x1f, 0xab, 0xe8, 0xa8, 0x13, 0xff, 0xa9, 0x88, 0x11, 0x0b, 0x88, 0x11, + 0x53, 0x42, 0x47, 0x8d, 0x04, 0x72, 0x04, 0xd0, 0xdc, 0xd1, 0xcf, 0x42, + 0x91, 0x71, 0xc9, 0xb1, 0x5c, 0x0e, 0x00, 0x99, 0x13, 0x8e, 0x7d, 0xa4, + 0x3c, 0xc7, 0x91, 0xa3, 0xea, 0x53, 0x34, 0x5c, 0x60, 0x3f, 0x8e, 0x3f, + 0x9b, 0x6d, 0x2d, 0xec, 0xa3, 0xf0, 0xc5, 0x51, 0xf0, 0x39, 0x0f, 0x1a, + 0xac, 0x97, 0x74, 0xdd, 0x4f, 0x07, 0xec, 0x3d, 0xa0, 0x79, 0x9c, 0x46, + 0x4e, 0x8d, 0xb0, 0xcc, 0xf6, 0x14, 0x28, 0xd2, 0x73, 0x8c, 0xb6, 0x1b, + 0x73, 0x2c, 0xdf, 0x83, 0xe5, 0x1d, 0xe0, 0x85, 0xd0, 0x51, 0xc8, 0x20, + 0x65, 0x0b, 0x23, 0xf4, 0x58, 0x89, 0xfb, 0xf2, 0xa0, 0x1d, 0xe2, 0xda, + 0xfe, 0xfd, 0x52, 0xce, 0x31, 0x9f, 0xe6, 0xce, 0x37, 0x22, 0xe7, 0x63, + 0x38, 0x86, 0xe1, 0x6f, 0xaa, 0xf3, 0xee, 0x14, 0x3c, 0x8d, 0x18, 0x5d, + 0x6a, 0x79, 0x87, 0x1f, 0xe3, 0xcf, 0xf7, 0xf3, 0x3b, 0xe6, 0x81, 0xef, + 0x6f, 0xb6, 0xf6, 0x00, 0x76, 0x10, 0x73, 0xfa, 0xa9, 0xb3, 0xdd, 0xc5, + 0x37, 0x81, 0xb5, 0xd9, 0xcf, 0x31, 0x9f, 0x1f, 0xa1, 0xec, 0xa9, 0x7c, + 0x8f, 0x0a, 0x19, 0x9b, 0xcd, 0x28, 0xe4, 0xb7, 0x1e, 0xa6, 0xdc, 0xa9, + 0xa3, 0x6c, 0x37, 0x40, 0xab, 0x3d, 0xb4, 0x6b, 0x22, 0xd2, 0x73, 0x80, + 0x34, 0xb1, 0xce, 0x5b, 0x24, 0xe8, 0x1f, 0x9b, 0x15, 0xbe, 0x20, 0x43, + 0xe9, 0x89, 0xed, 0xa1, 0x4b, 0xe8, 0x1b, 0x1e, 0x8c, 0x84, 0x17, 0xe8, + 0x09, 0xd0, 0xe5, 0x23, 0xf8, 0x22, 0xab, 0x67, 0x0c, 0x3a, 0x84, 0x9c, + 0x0a, 0xeb, 0x8f, 0x4a, 0xda, 0xe0, 0xbb, 0xcc, 0x51, 0xd0, 0x8f, 0xf2, + 0x0e, 0x4d, 0x99, 0x9e, 0x4c, 0xcb, 0xaf, 0xc0, 0xf6, 0x1c, 0x11, 0xb1, + 0x4b, 0x56, 0xd0, 0xee, 0xd2, 0x06, 0x47, 0x0e, 0x60, 0x8b, 0x30, 0xef, + 0xe5, 0x41, 0x85, 0xb6, 0x20, 0x4e, 0x3f, 0x24, 0x78, 0xeb, 0xa3, 0x7d, + 0x66, 0xd4, 0xd8, 0x47, 0xf3, 0x7e, 0x27, 0x56, 0xc0, 0x3c, 0x3d, 0xf7, + 0x60, 0x0f, 0x90, 0x53, 0xfb, 0xeb, 0xeb, 0xa8, 0x2d, 0x12, 0x4e, 0xa8, + 0x09, 0xfa, 0x93, 0xd2, 0xdd, 0xe4, 0xe8, 0x77, 0x2b, 0xdb, 0x7e, 0xf0, + 0xb0, 0xd3, 0x69, 0x5b, 0x78, 0x16, 0x3a, 0xb1, 0x1e, 0xe3, 0xfe, 0xac, + 0xc0, 0x7d, 0x84, 0xba, 0xa1, 0x6b, 0x22, 0x8f, 0x39, 0x51, 0x8b, 0x17, + 0xf3, 0xbc, 0x9e, 0xcf, 0x5f, 0xc6, 0x3c, 0xdc, 0xcf, 0x70, 0x78, 0x2f, + 0x3c, 0x41, 0x23, 0x90, 0xc7, 0x5c, 0x7f, 0x57, 0x68, 0x0c, 0xdf, 0xa4, + 0x4a, 0x4d, 0x74, 0x54, 0xe3, 0xf1, 0x48, 0x38, 0xaf, 0x1e, 0x42, 0xdc, + 0xf3, 0xb8, 0xea, 0xb7, 0x7e, 0xe6, 0x67, 0xbf, 0xe3, 0xb7, 0xae, 0x29, + 0xd5, 0xb9, 0x10, 0x87, 0x8a, 0xdc, 0x60, 0x41, 0x19, 0x2c, 0x5d, 0x52, + 0x92, 0x85, 0x6b, 0x4a, 0xaa, 0xc4, 0x30, 0x8e, 0xce, 0x67, 0xcf, 0x74, + 0x82, 0x4e, 0x1f, 0x89, 0xef, 0xe6, 0x7a, 0x8f, 0x50, 0xea, 0xd4, 0xad, + 0x94, 0x9e, 0xe6, 0xbc, 0x34, 0x02, 0x7c, 0x3f, 0x2a, 0xe7, 0x62, 0x41, + 0xca, 0x9d, 0xe1, 0x31, 0xb6, 0x5f, 0xd6, 0xd5, 0x45, 0x1f, 0xef, 0x9f, + 0xf9, 0x6f, 0x52, 0xc1, 0x7e, 0x53, 0xd2, 0x8f, 0xdf, 0x7d, 0x9c, 0x93, + 0xe1, 0xf7, 0x6f, 0x86, 0xd3, 0xb7, 0x95, 0x16, 0x36, 0xdc, 0xc8, 0x3e, + 0x57, 0xb3, 0xc7, 0x47, 0x7d, 0x7e, 0x6b, 0x7b, 0x13, 0xb5, 0x84, 0x80, + 0xc3, 0x4a, 0x7b, 0x64, 0x98, 0x5f, 0x87, 0x1c, 0xb0, 0x4d, 0xd9, 0x0d, + 0x7e, 0x5a, 0x6c, 0xc3, 0x60, 0x93, 0x76, 0x53, 0xae, 0xc4, 0xb2, 0x1d, + 0x35, 0x32, 0x90, 0xb1, 0x34, 0x75, 0xb1, 0x1e, 0xb9, 0xba, 0x07, 0xdb, + 0x9d, 0x87, 0xed, 0x46, 0x3c, 0x64, 0x53, 0xbe, 0x29, 0xce, 0x36, 0xbc, + 0x0b, 0xb2, 0x85, 0xbe, 0x62, 0x55, 0x17, 0x77, 0x2d, 0xc1, 0x5d, 0x5b, + 0xc2, 0xa3, 0x02, 0xd5, 0xe2, 0x3f, 0x4b, 0x8c, 0xff, 0x5f, 0x00, 0xff, + 0xcf, 0x01, 0x7f, 0xc6, 0xa9, 0x31, 0xfe, 0x3b, 0x2b, 0xf8, 0x33, 0x0c, + 0xfc, 0x1c, 0x64, 0xf1, 0x0d, 0xe8, 0xe2, 0x6b, 0x36, 0x7c, 0x9d, 0x0d, + 0xff, 0x67, 0xc3, 0xdf, 0xd9, 0xf0, 0x8b, 0x36, 0x7c, 0x1e, 0xf6, 0x74, + 0x0e, 0x36, 0xe9, 0xac, 0x9d, 0x34, 0x58, 0x9f, 0x92, 0x31, 0xf6, 0x9d, + 0xbb, 0x65, 0xde, 0x1d, 0x92, 0x71, 0xf7, 0xa7, 0x64, 0x2c, 0x7b, 0x00, + 0xb1, 0xec, 0x66, 0x1a, 0xed, 0xe1, 0x9c, 0xa4, 0x05, 0xcf, 0x75, 0x78, + 0x22, 0x6e, 0xed, 0x49, 0x48, 0xbd, 0xfc, 0x0c, 0x62, 0x5c, 0xd8, 0xff, + 0x1e, 0xe4, 0x37, 0x19, 0xc4, 0x6a, 0x56, 0x1f, 0xc7, 0xe5, 0xb0, 0x65, + 0xef, 0x37, 0x39, 0x76, 0xfe, 0x2e, 0x19, 0x03, 0xbb, 0xed, 0x56, 0xc0, + 0xa4, 0xd1, 0xd7, 0x8a, 0x6f, 0x7e, 0x07, 0xb2, 0xdf, 0x86, 0xf6, 0xce, + 0x3a, 0x18, 0xe4, 0xb3, 0x56, 0x16, 0x7d, 0x11, 0xc0, 0xb4, 0x61, 0x9d, + 0x0e, 0xb4, 0xf7, 0xa0, 0x7d, 0x8b, 0xb3, 0x8e, 0xf1, 0x2b, 0x68, 0xa7, + 0xea, 0xbe, 0xd9, 0x8a, 0xbe, 0x4c, 0x5d, 0xdf, 0x9b, 0xe8, 0x4b, 0xa2, + 0x6f, 0x51, 0x7e, 0x97, 0x47, 0x3b, 0x52, 0x07, 0xb3, 0x88, 0x3e, 0xc6, + 0xf1, 0x5b, 0x78, 0xde, 0x47, 0xa3, 0x19, 0x8e, 0x03, 0xdc, 0xb1, 0xdc, + 0x7a, 0x6a, 0xe3, 0xdc, 0xf7, 0x43, 0x21, 0x3b, 0xf3, 0xd2, 0x46, 0xa7, + 0x27, 0xd8, 0x4f, 0x8c, 0x20, 0xee, 0xe1, 0x71, 0xe1, 0x9c, 0x3c, 0xfd, + 0x1f, 0x00, 0xf6, 0x61, 0x8c, 0x21, 0x56, 0xb7, 0xcb, 0x4d, 0x8d, 0xc7, + 0x1f, 0xc5, 0xf8, 0x5f, 0xca, 0x6f, 0x2b, 0x73, 0x03, 0xfe, 0x1b, 0x75, + 0x7d, 0x6a, 0xb0, 0xb6, 0xbd, 0xd6, 0xf3, 0xbe, 0x4d, 0x5f, 0xfa, 0xfd, + 0x48, 0x1d, 0xfc, 0xef, 0x6e, 0xa8, 0x6d, 0x3f, 0xc5, 0xdf, 0x20, 0x87, + 0x70, 0xdb, 0x09, 0xc8, 0x1d, 0xdb, 0xa4, 0xfa, 0x79, 0x3e, 0x6b, 0xd4, + 0xf6, 0x6d, 0x32, 0x6b, 0xdb, 0x1c, 0x27, 0x31, 0x5c, 0x08, 0xf2, 0xde, + 0xa1, 0xec, 0xb2, 0x7f, 0x13, 0xe3, 0x61, 0xe5, 0x5e, 0xdb, 0x8b, 0x67, + 0x48, 0xe6, 0x46, 0xe1, 0x4a, 0xcc, 0x3b, 0x5f, 0x0a, 0x40, 0xae, 0x3e, + 0x0f, 0x9e, 0x73, 0xdc, 0x53, 0xd5, 0xf1, 0xf7, 0x68, 0x39, 0x1d, 0x67, + 0x1f, 0xc0, 0x31, 0xfe, 0x36, 0x11, 0x1f, 0xfb, 0xe2, 0x4f, 0x70, 0x0c, + 0xf6, 0xb4, 0xe3, 0x5b, 0x2c, 0xf8, 0x43, 0xb4, 0x4b, 0x7e, 0xc7, 0x6e, + 0x22, 0x9f, 0xc8, 0x16, 0xd8, 0x9f, 0xb1, 0x0f, 0x89, 0xc0, 0x4e, 0xb3, + 0x1f, 0xfd, 0x24, 0x7d, 0xc6, 0x5d, 0xcd, 0x6c, 0xfb, 0x34, 0xeb, 0x05, + 0xc4, 0x0b, 0x1c, 0xe7, 0xb1, 0xed, 0xc6, 0x7b, 0xd1, 0x8d, 0x57, 0xee, + 0xd7, 0xc8, 0xaa, 0xfa, 0x11, 0x67, 0x8f, 0x5b, 0x59, 0x37, 0x56, 0xb1, + 0xef, 0xc6, 0xb6, 0xed, 0xc7, 0x75, 0xb6, 0xe1, 0xb2, 0xb0, 0x0d, 0x0f, + 0x6a, 0x7e, 0xeb, 0xf7, 0x9b, 0x1d, 0x79, 0x6d, 0x6c, 0x1b, 0xee, 0xad, + 0xd8, 0x06, 0x57, 0x5e, 0xbd, 0x79, 0xeb, 0x0f, 0xc0, 0x1b, 0x0b, 0xbc, + 0xa9, 0xaf, 0xd5, 0x70, 0x8e, 0xe2, 0x87, 0x1f, 0xe2, 0x18, 0x91, 0x73, + 0xd9, 0x18, 0xe5, 0x62, 0x45, 0xc4, 0x6a, 0x91, 0xd9, 0xd9, 0x4a, 0x8e, + 0xf5, 0x35, 0x69, 0xbb, 0x6b, 0xe2, 0x22, 0x7a, 0xbc, 0x78, 0x09, 0xf8, + 0x73, 0xbc, 0xa5, 0x49, 0x1b, 0xc1, 0xfd, 0xe3, 0x12, 0x47, 0x7e, 0xe7, + 0x3a, 0x1e, 0x7c, 0x69, 0xf1, 0x47, 0xe0, 0x15, 0xc7, 0x7d, 0x51, 0x27, + 0xde, 0xab, 0x89, 0xa9, 0xd7, 0xf8, 0xc9, 0xe2, 0x78, 0x89, 0x61, 0x74, + 0x19, 0x2f, 0x05, 0x64, 0x5e, 0x63, 0xc8, 0x3c, 0x87, 0x63, 0x6d, 0xae, + 0xb1, 0xd6, 0xc7, 0x50, 0x0b, 0x43, 0xc1, 0x6d, 0xcc, 0x13, 0x8e, 0xa1, + 0xda, 0x28, 0x39, 0xe3, 0xc4, 0x50, 0x4e, 0x9d, 0xcd, 0xcd, 0x71, 0x5c, + 0x5c, 0xd9, 0x0f, 0xef, 0xc0, 0x3e, 0x45, 0x9e, 0x14, 0x74, 0xea, 0x7f, + 0x1a, 0xec, 0xf6, 0x51, 0xf4, 0x8f, 0xba, 0xfd, 0x9e, 0x5c, 0xc3, 0xc5, + 0x85, 0x7d, 0xbd, 0x1b, 0xd3, 0xed, 0x96, 0x31, 0x1d, 0x62, 0x18, 0xdb, + 0xc9, 0xbb, 0xf6, 0x16, 0x33, 0xe8, 0xe3, 0x75, 0x11, 0x1b, 0x12, 0xc7, + 0x49, 0x90, 0xaf, 0xfd, 0x91, 0x50, 0x58, 0xad, 0xc7, 0xab, 0x75, 0xa1, + 0x16, 0xaf, 0x41, 0xf1, 0xdd, 0xf8, 0x92, 0xef, 0x48, 0xc4, 0x92, 0xe3, + 0xf6, 0x10, 0xe8, 0xc5, 0xf8, 0xb9, 0xba, 0xe1, 0xc6, 0xc9, 0x8c, 0xd3, + 0x3f, 0x82, 0xc6, 0xbb, 0x15, 0xfe, 0x7e, 0xcc, 0xde, 0x2f, 0xe8, 0x96, + 0x15, 0xb8, 0x0e, 0x7b, 0x70, 0x1d, 0x91, 0xb8, 0xb2, 0x2e, 0xb0, 0x7e, + 0x78, 0x6b, 0x9a, 0xa6, 0xd8, 0x1b, 0x70, 0x0e, 0xf3, 0xb9, 0xb9, 0x6a, + 0x2d, 0x0c, 0xf9, 0xb6, 0xc1, 0x1f, 0x02, 0xd7, 0xac, 0x88, 0x43, 0x03, + 0x0b, 0xf5, 0x34, 0x1c, 0xc7, 0x5a, 0x88, 0xdb, 0x81, 0x8f, 0xcb, 0xf3, + 0x26, 0x89, 0xcf, 0x37, 0xc5, 0xdc, 0x63, 0xa2, 0x06, 0xea, 0xd3, 0x39, + 0x77, 0xc9, 0x0a, 0xde, 0x69, 0x92, 0x77, 0x8f, 0x56, 0xf0, 0x73, 0x78, + 0x1c, 0x90, 0x74, 0xe5, 0xdc, 0x95, 0x75, 0x5a, 0xf0, 0xa7, 0x9d, 0x73, + 0xd3, 0x41, 0x6a, 0x14, 0x23, 0x2f, 0x0c, 0xa9, 0xdb, 0x1c, 0x3a, 0x3a, + 0x31, 0xf2, 0xda, 0xba, 0x18, 0xf9, 0xb6, 0x20, 0xc7, 0x5a, 0xc3, 0x50, + 0x82, 0x79, 0xf8, 0xba, 0x97, 0x6d, 0xc8, 0x36, 0x70, 0x3d, 0x5f, 0x53, + 0xbb, 0xec, 0x59, 0xa6, 0xd6, 0x1c, 0x20, 0xdf, 0x0c, 0xfb, 0x0e, 0x0b, + 0x79, 0x06, 0x91, 0x36, 0xc9, 0x3a, 0xcb, 0xbe, 0xbd, 0x1a, 0x67, 0xcf, + 0x51, 0xa3, 0x18, 0xfb, 0x46, 0xfd, 0xfa, 0x79, 0xbf, 0xdf, 0x3a, 0xac, + 0x3b, 0x36, 0x73, 0x25, 0xbf, 0xee, 0xc2, 0xed, 0x41, 0x9c, 0xad, 0x50, + 0x93, 0x55, 0xc0, 0xfe, 0xde, 0xf0, 0x37, 0x5b, 0xae, 0x2e, 0x06, 0x68, + 0xfd, 0xcc, 0x2d, 0x42, 0x1f, 0x8d, 0xc9, 0xaa, 0x3e, 0x8e, 0x82, 0x37, + 0x19, 0xa7, 0x06, 0x60, 0xae, 0xa7, 0xeb, 0xd7, 0x0b, 0xc6, 0xed, 0x37, + 0xfd, 0xaa, 0xe5, 0xca, 0xc0, 0xf5, 0xf2, 0x91, 0x4f, 0xd5, 0xd1, 0xba, + 0x51, 0x4d, 0xf8, 0x2c, 0xe8, 0x1a, 0x47, 0xde, 0x1d, 0x79, 0x81, 0x10, + 0x3b, 0x39, 0x79, 0x78, 0x1a, 0xb9, 0x77, 0xe4, 0x02, 0xe7, 0xe3, 0x6e, + 0x7e, 0xfe, 0x6a, 0x29, 0x72, 0x36, 0x8f, 0x9c, 0x79, 0x1e, 0x39, 0xf9, + 0xcb, 0xc8, 0xc9, 0xcf, 0x97, 0x7a, 0x41, 0xff, 0x1e, 0x99, 0x8f, 0xb3, + 0x8e, 0x99, 0x74, 0x11, 0xb9, 0xd3, 0x77, 0x67, 0xd8, 0x46, 0x74, 0xd1, + 0x3d, 0xc8, 0x35, 0xbe, 0x3f, 0xa9, 0x68, 0x9d, 0x7d, 0x01, 0x5f, 0xc2, + 0xb8, 0x91, 0x38, 0x71, 0x29, 0x4f, 0x1a, 0xc7, 0x8a, 0x23, 0x4d, 0x7e, + 0x6b, 0xae, 0x95, 0x5a, 0xf6, 0x2c, 0xcb, 0x93, 0x6a, 0xac, 0xe8, 0xc2, + 0x19, 0xd4, 0xd9, 0xf7, 0x87, 0x9c, 0xdb, 0xc4, 0x48, 0xe4, 0xd3, 0xeb, + 0xe8, 0xed, 0x93, 0x65, 0xda, 0x19, 0xbb, 0x56, 0xbe, 0x68, 0xad, 0xa3, + 0x6c, 0xef, 0x43, 0x32, 0x97, 0x5c, 0x78, 0x28, 0x69, 0xe5, 0x43, 0x3e, + 0xf7, 0x7c, 0x62, 0x42, 0x47, 0x84, 0xc8, 0xbf, 0x20, 0xcd, 0x0d, 0x20, + 0x71, 0x6e, 0xd9, 0xfe, 0x02, 0x1f, 0x10, 0xb1, 0x6d, 0x9c, 0x33, 0x03, + 0xa2, 0xd6, 0xb6, 0xd1, 0xe2, 0x7e, 0x03, 0xfc, 0xbe, 0x8f, 0xe6, 0x90, + 0x43, 0x14, 0x44, 0x1e, 0xde, 0x0e, 0x78, 0x37, 0x0f, 0xbf, 0x1f, 0xb9, + 0x01, 0xd3, 0xd8, 0x04, 0xfc, 0x6f, 0x03, 0xc6, 0x6b, 0x43, 0x9f, 0x6b, + 0x22, 0xf1, 0x3d, 0x8f, 0xb7, 0x13, 0xd7, 0x65, 0xab, 0xf3, 0xf2, 0x9c, + 0x3c, 0xf6, 0x61, 0xf9, 0xf6, 0xbe, 0x3e, 0xcf, 0xdc, 0x6d, 0x9e, 0xb9, + 0xef, 0xf0, 0xcc, 0xed, 0xc3, 0xb7, 0x2e, 0x3e, 0x41, 0x7c, 0xeb, 0xae, + 0xf1, 0xb7, 0x9e, 0x35, 0x5c, 0xdc, 0xdb, 0x3d, 0xb8, 0xbf, 0x8f, 0xf9, + 0xb9, 0xcf, 0xf4, 0xf4, 0xf1, 0x9a, 0x1b, 0x68, 0x6e, 0xb0, 0x8d, 0x16, + 0x4f, 0x72, 0x5f, 0xd0, 0x83, 0x0b, 0xe3, 0x17, 0x90, 0x63, 0x6d, 0x74, + 0xf1, 0x64, 0x8b, 0xc0, 0x9b, 0xfd, 0xf9, 0xc6, 0xca, 0x9a, 0x57, 0xb0, + 0xa6, 0x3b, 0x97, 0x89, 0x6f, 0x19, 0x96, 0xf1, 0xe3, 0x31, 0xee, 0xe3, + 0xb1, 0x37, 0xcb, 0x5f, 0x33, 0x82, 0xce, 0x9e, 0x0d, 0xc6, 0xcd, 0xfd, + 0x56, 0x6b, 0x26, 0x8b, 0xdb, 0x9d, 0x34, 0x1b, 0xd4, 0xc0, 0x37, 0x55, + 0xfa, 0x28, 0xae, 0x23, 0xa8, 0x4a, 0xb4, 0x8f, 0xf9, 0xbc, 0x4e, 0xd6, + 0xaf, 0x5b, 0x30, 0x6f, 0xd8, 0xcd, 0xd1, 0x88, 0xe5, 0x38, 0x27, 0xec, + 0xbe, 0x26, 0xc7, 0xd9, 0xee, 0xb3, 0xdf, 0xc7, 0x53, 0xc8, 0xaa, 0x3c, + 0xaf, 0x29, 0xed, 0xa0, 0x83, 0x50, 0xcf, 0x8b, 0xb2, 0x9e, 0xb2, 0xe8, + 0xad, 0x99, 0x18, 0x4e, 0x1c, 0xe3, 0x9c, 0xed, 0xac, 0x85, 0xfe, 0xe0, + 0xbd, 0x98, 0x00, 0x1e, 0x61, 0x8a, 0xe2, 0xaf, 0x50, 0xca, 0xe3, 0x69, + 0xe1, 0xa9, 0xe0, 0xc9, 0xf5, 0x0c, 0x1d, 0x4f, 0xe8, 0x18, 0xec, 0x53, + 0xb4, 0xef, 0x92, 0x93, 0x3f, 0x41, 0x37, 0xde, 0x9e, 0x74, 0xea, 0x51, + 0x8b, 0xd6, 0x72, 0xf5, 0xa8, 0x3f, 0x67, 0x9e, 0x9c, 0x70, 0xeb, 0x51, + 0x8b, 0x24, 0xea, 0x51, 0x27, 0x56, 0xa8, 0x47, 0x25, 0x56, 0x5f, 0x8f, + 0xe2, 0xf9, 0x35, 0xda, 0xd7, 0x4f, 0xca, 0x17, 0x64, 0x3d, 0xea, 0x3d, + 0x72, 0xea, 0x51, 0x17, 0xa9, 0x71, 0x3d, 0xea, 0x78, 0x5d, 0x3d, 0x2a, + 0x28, 0xea, 0x51, 0x3c, 0x8f, 0x53, 0x8f, 0x12, 0xed, 0xbe, 0x88, 0xa7, + 0xee, 0x42, 0xf4, 0xee, 0x64, 0x07, 0x68, 0x66, 0xd0, 0xf7, 0x1a, 0xda, + 0x34, 0x45, 0xc8, 0xdb, 0x4a, 0x35, 0xd0, 0x07, 0x6e, 0xb8, 0xbe, 0xa2, + 0xd0, 0x06, 0xcc, 0x9b, 0xec, 0x7b, 0xd8, 0x53, 0x63, 0x61, 0x9a, 0xff, + 0x62, 0xea, 0x2c, 0x07, 0x45, 0x9d, 0xe5, 0x87, 0x6b, 0xbc, 0x75, 0x96, + 0x45, 0xba, 0x7e, 0x9d, 0xe5, 0x60, 0x83, 0x3a, 0xcb, 0x5b, 0x54, 0xad, + 0xb3, 0xbc, 0x45, 0xd5, 0x3a, 0xcb, 0xc1, 0x12, 0xe7, 0xe2, 0x3e, 0x89, + 0x5f, 0x06, 0xed, 0x41, 0xf1, 0xc7, 0xb5, 0x97, 0xc5, 0xca, 0x1e, 0x7e, + 0xd9, 0x6a, 0x2f, 0x6c, 0x03, 0x22, 0x17, 0x2e, 0xd7, 0xd4, 0x5e, 0xb8, + 0x0d, 0x9d, 0xb1, 0xd7, 0x08, 0x19, 0x99, 0x83, 0x7f, 0x5f, 0x9c, 0x0c, + 0x61, 0xce, 0x0e, 0xf8, 0x8c, 0x0e, 0xe4, 0x06, 0x61, 0xb4, 0x15, 0xda, + 0x64, 0x0d, 0xa1, 0x8f, 0xc7, 0xd9, 0x0e, 0x43, 0xb7, 0x6c, 0x77, 0x7f, + 0x0f, 0x48, 0x1a, 0x44, 0x68, 0xb8, 0x9d, 0xf4, 0x20, 0xfb, 0x8e, 0xc9, + 0x3d, 0x74, 0xc8, 0xde, 0x22, 0xf6, 0xbd, 0xc1, 0xaa, 0x95, 0xb9, 0xc1, + 0x1b, 0x90, 0xb9, 0xcc, 0xaa, 0x65, 0x8e, 0xe5, 0xcd, 0x39, 0xf7, 0xdd, + 0x60, 0xf1, 0xfa, 0x1d, 0x02, 0xa7, 0x77, 0x1b, 0xc8, 0xfb, 0x18, 0xec, + 0x8e, 0x33, 0xbf, 0x2e, 0xd7, 0xab, 0x8f, 0x87, 0x9f, 0x6d, 0x66, 0xff, + 0xbd, 0x72, 0x3d, 0xb1, 0xde, 0x7f, 0xaf, 0xe4, 0x47, 0x15, 0x61, 0x93, + 0xb3, 0x25, 0xae, 0xed, 0x7b, 0xf9, 0x33, 0x8f, 0x9c, 0x00, 0x7d, 0x42, + 0x0f, 0x98, 0xae, 0x41, 0xf0, 0x01, 0xeb, 0xd8, 0x4f, 0xc9, 0x5a, 0x16, + 0x9e, 0x05, 0x97, 0x7f, 0xad, 0xb0, 0x99, 0xee, 0x18, 0xdb, 0x01, 0x0b, + 0xfe, 0x8f, 0xeb, 0x28, 0x7c, 0x8e, 0xca, 0xfd, 0x2e, 0x5f, 0xbb, 0x2e, + 0xbc, 0xa7, 0x72, 0xbb, 0x5c, 0xce, 0x8a, 0x7a, 0x2d, 0xa9, 0x9d, 0x7d, + 0xd3, 0x2d, 0x6c, 0x6b, 0xb6, 0x58, 0xae, 0xcc, 0x26, 0xf0, 0xce, 0x7c, + 0x7d, 0x17, 0x36, 0x9c, 0xcf, 0xaa, 0xbf, 0x23, 0x6a, 0x04, 0x73, 0x36, + 0xdb, 0x6b, 0x8e, 0x41, 0x7f, 0x0b, 0xb2, 0xc4, 0xef, 0x51, 0x71, 0x2e, + 0x21, 0x6a, 0xf8, 0x83, 0xdc, 0x76, 0xed, 0x4a, 0x94, 0xed, 0x30, 0xf6, + 0x5c, 0xa5, 0x31, 0xe2, 0x23, 0xc8, 0x0c, 0xc7, 0xb1, 0x0c, 0xe7, 0xc6, + 0x9e, 0x9a, 0xa7, 0x66, 0xab, 0xcb, 0xb8, 0x88, 0x75, 0x39, 0x00, 0x9a, + 0xed, 0x10, 0x31, 0xea, 0xb8, 0x5d, 0xa6, 0xea, 0x19, 0x3f, 0xd3, 0xdc, + 0x39, 0xe7, 0x3f, 0x66, 0x2f, 0x47, 0xfb, 0xcd, 0x37, 0x48, 0x7b, 0x47, + 0x1f, 0x6b, 0xe9, 0xae, 0x23, 0x7e, 0x71, 0xe9, 0xee, 0xfa, 0xa8, 0x49, + 0x49, 0x83, 0xa8, 0xac, 0x2b, 0x7e, 0x5a, 0x9e, 0x29, 0xfd, 0x5f, 0xd8, + 0xaf, 0xe2, 0xd9, 0xaf, 0xab, 0xbb, 0xfb, 0xe4, 0x7e, 0xc3, 0x75, 0xba, + 0x1b, 0x97, 0x75, 0xb9, 0x5f, 0x84, 0xee, 0xba, 0x7b, 0xe2, 0xb5, 0xb7, + 0x5c, 0x67, 0xdd, 0x67, 0x48, 0x8d, 0xaf, 0x14, 0x7b, 0xff, 0xb4, 0xf9, + 0xe3, 0xc5, 0xde, 0x1f, 0x87, 0x9e, 0x5e, 0xbd, 0x65, 0x1a, 0xb6, 0x89, + 0xb8, 0xc2, 0xd1, 0x1f, 0xd8, 0xe3, 0x82, 0x9f, 0x16, 0x1e, 0xd2, 0xe9, + 0x9f, 0xee, 0xe4, 0xfa, 0xac, 0x26, 0x73, 0x7c, 0x6e, 0x7f, 0xb1, 0x95, + 0x63, 0xab, 0x4d, 0xd6, 0x77, 0x44, 0x6e, 0x95, 0x57, 0x4d, 0x8f, 0x1f, + 0x31, 0x30, 0xce, 0x63, 0x61, 0xba, 0x1c, 0xbc, 0x91, 0xb8, 0xbc, 0xcb, + 0x58, 0xf4, 0xad, 0x26, 0x2e, 0xbf, 0x55, 0xf7, 0x5b, 0x7f, 0xdd, 0x7a, + 0xbd, 0x3a, 0x47, 0x35, 0x2e, 0xe7, 0x7c, 0x3e, 0xe8, 0xd4, 0x18, 0x4c, + 0x8e, 0xcf, 0xd7, 0x4a, 0x9e, 0xf0, 0x3b, 0x72, 0x11, 0x1b, 0x79, 0x08, + 0x64, 0xfc, 0x55, 0xc8, 0xca, 0x2b, 0x36, 0xf2, 0x0e, 0x1b, 0xf9, 0x88, + 0x8d, 0xdc, 0xc3, 0x46, 0xee, 0x61, 0xf7, 0xc8, 0x1c, 0x26, 0x23, 0xeb, + 0x56, 0x7c, 0x46, 0xcb, 0xf9, 0x61, 0x5e, 0xc9, 0xd8, 0xe3, 0x7c, 0x1f, + 0x41, 0x4d, 0xc6, 0x36, 0xca, 0x78, 0xf0, 0x38, 0xdf, 0x77, 0x28, 0xab, + 0x71, 0xae, 0x45, 0x91, 0xaa, 0xc6, 0x6f, 0x87, 0x8f, 0xda, 0x0e, 0xbc, + 0x9a, 0x79, 0xdc, 0xa7, 0xc6, 0x5b, 0x99, 0x76, 0x8a, 0x1a, 0x5f, 0x2b, + 0xcf, 0x0d, 0x7a, 0x03, 0x0e, 0xfe, 0xdd, 0xdc, 0xd6, 0xd4, 0xf8, 0xdd, + 0xec, 0xd3, 0xc2, 0xa4, 0xba, 0xfd, 0xb7, 0x07, 0x98, 0xae, 0xa4, 0xde, + 0x16, 0xe0, 0xb8, 0x76, 0xde, 0xf6, 0x8b, 0x3b, 0x05, 0xc9, 0x18, 0xd7, + 0xcc, 0xb8, 0x5d, 0xa5, 0xab, 0xba, 0x2c, 0x5d, 0xfd, 0x95, 0xfa, 0x3f, + 0xd3, 0xd2, 0xc7, 0x70, 0xa2, 0x36, 0xc6, 0x34, 0x75, 0xe7, 0xe3, 0xf3, + 0x66, 0x5e, 0x47, 0xdc, 0x63, 0xc0, 0xf3, 0x60, 0x33, 0xb5, 0x0d, 0x0e, + 0xf9, 0x2d, 0xef, 0xba, 0x6c, 0x43, 0x76, 0x90, 0x37, 0xc7, 0x5a, 0x7e, + 0xcd, 0xa8, 0x38, 0x1b, 0x49, 0xf6, 0x47, 0x85, 0xec, 0xb0, 0xac, 0x69, + 0xe2, 0xce, 0xd5, 0x47, 0xe2, 0x1e, 0x09, 0xcb, 0x19, 0xcb, 0xf2, 0x78, + 0x7f, 0x57, 0x58, 0x53, 0x5b, 0xb0, 0x46, 0x98, 0xd2, 0x25, 0x71, 0x56, + 0x80, 0x7c, 0xe9, 0xdc, 0x3a, 0x6a, 0xfb, 0x07, 0xbd, 0x9a, 0xc7, 0x46, + 0x9d, 0xb3, 0x7a, 0xbb, 0xde, 0xff, 0x8d, 0x8a, 0x73, 0x65, 0xc7, 0x06, + 0xb9, 0xe7, 0xc3, 0xab, 0x3b, 0xff, 0xbe, 0xbe, 0x3e, 0xb5, 0xd4, 0xd7, + 0x0d, 0x24, 0x0d, 0x98, 0x36, 0x8d, 0xcf, 0xee, 0xe7, 0x4b, 0x7c, 0xaf, + 0x25, 0x12, 0xe3, 0xdc, 0x6d, 0x44, 0xdc, 0xf9, 0x50, 0x21, 0x85, 0x3a, + 0x8d, 0x19, 0x9c, 0xf3, 0x85, 0x86, 0x7d, 0x71, 0xca, 0x64, 0x27, 0x48, + 0x43, 0xac, 0x98, 0xa9, 0xd6, 0x03, 0x1f, 0x5c, 0x43, 0x96, 0x2b, 0x97, + 0x51, 0xce, 0x1f, 0x6a, 0xce, 0xed, 0x16, 0xe9, 0xb0, 0x72, 0xa0, 0x74, + 0x84, 0x0e, 0x34, 0x8c, 0x29, 0x1b, 0xd7, 0x03, 0x2f, 0xd6, 0xd5, 0x14, + 0x16, 0x44, 0x4d, 0x21, 0xb7, 0xc6, 0x6f, 0x3d, 0x19, 0x70, 0xee, 0xb5, + 0x34, 0xd6, 0x93, 0x5d, 0x15, 0x3d, 0x71, 0xe1, 0xf8, 0x2c, 0xbe, 0x8d, + 0x76, 0x8a, 0xb5, 0x0e, 0x2b, 0x59, 0xbb, 0x95, 0x76, 0x1a, 0x0e, 0xd6, + 0xa3, 0x36, 0xe3, 0x75, 0x58, 0x39, 0x68, 0xe7, 0x95, 0xb4, 0xa8, 0x3d, + 0x70, 0x8c, 0xbf, 0xe6, 0xda, 0x30, 0x95, 0xe9, 0xed, 0x98, 0xfb, 0x3d, + 0xc3, 0x78, 0x6b, 0x8a, 0x2e, 0x9d, 0xf8, 0x2e, 0x51, 0x58, 0xe6, 0x6f, + 0xce, 0x7c, 0xb9, 0x29, 0xae, 0x25, 0xde, 0x8f, 0xfd, 0x33, 0xfc, 0x6e, + 0x25, 0x39, 0x55, 0x2e, 0xa7, 0x31, 0x3e, 0xd6, 0x7b, 0xaf, 0xc8, 0x8d, + 0xd4, 0x38, 0x0d, 0x71, 0x8e, 0xac, 0x2d, 0xc9, 0x91, 0xd3, 0xd0, 0x35, + 0xc4, 0x20, 0x76, 0x13, 0xbe, 0x75, 0xe3, 0x91, 0xcf, 0xae, 0x75, 0x64, + 0xe4, 0xbb, 0x12, 0x0f, 0x1e, 0xff, 0xfb, 0x80, 0x7b, 0x0f, 0x28, 0x77, + 0x2a, 0x8d, 0xfd, 0x37, 0x51, 0xca, 0x74, 0xf2, 0xbb, 0xec, 0x99, 0x23, + 0x1b, 0x6a, 0xe1, 0xd1, 0x77, 0xca, 0x85, 0x0f, 0xd6, 0xc1, 0xf3, 0x19, + 0xd7, 0x5f, 0xd5, 0xc1, 0x07, 0x3d, 0xf0, 0x66, 0x1d, 0x3c, 0xe2, 0xae, + 0x33, 0xdf, 0xa8, 0x83, 0x37, 0x3d, 0xf0, 0xed, 0x75, 0xf0, 0xed, 0x80, + 0x7f, 0xa3, 0x0e, 0x1e, 0x7d, 0xa7, 0x90, 0x13, 0x08, 0xda, 0x70, 0x8c, + 0x74, 0x48, 0xe6, 0x89, 0x78, 0x2e, 0xb9, 0x1f, 0xc9, 0xf2, 0xd3, 0x01, + 0x1a, 0x7b, 0xeb, 0xb5, 0x09, 0xd8, 0xa8, 0xaa, 0x4c, 0x39, 0xfa, 0xea, + 0x95, 0x25, 0x96, 0xbd, 0x3c, 0xe4, 0x15, 0x7a, 0x54, 0x80, 0x3e, 0x15, + 0x5c, 0x5f, 0xca, 0x77, 0xaa, 0x22, 0xc7, 0x1d, 0x3d, 0x56, 0x68, 0xbd, + 0x35, 0x2f, 0x73, 0x91, 0xab, 0x8c, 0x3b, 0xfc, 0x86, 0xeb, 0x3b, 0xe8, + 0x84, 0x63, 0x57, 0x58, 0xbf, 0x79, 0x7e, 0x69, 0x5f, 0x4a, 0x2c, 0x87, + 0xce, 0x3a, 0xe9, 0x25, 0x32, 0x1b, 0x5e, 0x52, 0x77, 0xf1, 0xd5, 0xd9, + 0x77, 0x12, 0xf6, 0x3d, 0xd7, 0xe2, 0xb7, 0x36, 0xac, 0xbd, 0x9e, 0x7d, + 0xcf, 0x78, 0xec, 0x7b, 0x38, 0x58, 0xf5, 0xf9, 0x8f, 0x09, 0x9f, 0xdf, + 0xd1, 0xc0, 0x66, 0xac, 0xde, 0xe7, 0xef, 0xfd, 0xd8, 0x3e, 0x7f, 0xb9, + 0x75, 0x57, 0xe3, 0xf3, 0x1f, 0x69, 0xf9, 0x78, 0x3e, 0x9f, 0xd7, 0xac, + 0xaf, 0x65, 0x7a, 0xcf, 0x59, 0x8e, 0xca, 0x18, 0x7b, 0xb7, 0x27, 0xc6, + 0x66, 0xfc, 0xbe, 0x27, 0xef, 0x02, 0x9e, 0x5e, 0xeb, 0xc8, 0xdb, 0x51, + 0x19, 0xa7, 0x73, 0xec, 0x8d, 0xf7, 0xc2, 0x23, 0x90, 0xd1, 0x7c, 0x8f, + 0x8f, 0x54, 0x9a, 0x35, 0x9d, 0xb3, 0xed, 0x9f, 0x6f, 0xae, 0x17, 0xa1, + 0xcb, 0xc2, 0x9f, 0x24, 0x3e, 0x81, 0x5a, 0xea, 0x49, 0xc8, 0x8f, 0xbb, + 0xaf, 0x95, 0x6a, 0xa9, 0xf5, 0xe7, 0x1f, 0x7c, 0xee, 0x41, 0xca, 0x03, + 0x95, 0x73, 0x10, 0xaf, 0x4e, 0xe9, 0x94, 0x9d, 0x21, 0xdd, 0x8c, 0x93, + 0xb2, 0x8f, 0x71, 0x8e, 0xfd, 0xb0, 0x52, 0x6f, 0x3f, 0x24, 0x6b, 0x30, + 0xea, 0xb2, 0x77, 0x82, 0x7e, 0x02, 0x7c, 0x58, 0xaf, 0x9c, 0x1a, 0x8c, + 0xea, 0xdc, 0x09, 0x3a, 0xfe, 0xf3, 0xbb, 0x13, 0xc4, 0xf3, 0x6b, 0xb4, + 0xb7, 0xc1, 0x9d, 0x20, 0xdf, 0x2a, 0xef, 0x04, 0xad, 0x17, 0x35, 0x18, + 0x9e, 0xc7, 0xa9, 0xc1, 0x70, 0xbb, 0xb3, 0x8f, 0xe5, 0x3a, 0x4c, 0xa3, + 0x93, 0xb7, 0x88, 0x7b, 0xa8, 0x9d, 0x7d, 0xb5, 0xf2, 0xbd, 0xef, 0x13, + 0x8d, 0xa5, 0x79, 0xbd, 0xa3, 0x0d, 0xef, 0xb6, 0x24, 0x3f, 0xc1, 0x9a, + 0xcb, 0x21, 0x51, 0x73, 0xb9, 0xb3, 0xcd, 0x5b, 0x73, 0x51, 0x57, 0xb8, + 0xdb, 0x72, 0xa8, 0x41, 0xcd, 0xc5, 0xef, 0xb9, 0xdb, 0xe2, 0xf7, 0xdc, + 0x6d, 0x39, 0x24, 0xeb, 0x2b, 0xea, 0x2f, 0xd1, 0xdd, 0x96, 0xe4, 0x8a, + 0x77, 0x5b, 0xb6, 0x4a, 0x7d, 0xf5, 0xc2, 0xaf, 0xfe, 0xbc, 0x32, 0x55, + 0x67, 0xe7, 0x13, 0xc2, 0xce, 0xdf, 0xd5, 0xea, 0xb7, 0x9e, 0x69, 0xbb, + 0x9e, 0x9d, 0xdf, 0x57, 0xd1, 0x53, 0xbe, 0xa3, 0xcd, 0x77, 0xbe, 0x58, + 0x16, 0xf9, 0x7c, 0xa6, 0x89, 0x72, 0x03, 0xbf, 0x2a, 0x68, 0xf6, 0x58, + 0x6f, 0xed, 0x99, 0x63, 0xf5, 0x5e, 0xa4, 0xee, 0xb9, 0x17, 0x69, 0xa2, + 0x5f, 0xaf, 0xab, 0x87, 0x04, 0xe4, 0xdd, 0x7e, 0xf8, 0xc2, 0x19, 0x43, + 0xda, 0x5e, 0xc4, 0x70, 0x98, 0xae, 0x50, 0xe4, 0x3b, 0x95, 0x6d, 0xe4, + 0x9b, 0x71, 0xce, 0x4b, 0x54, 0x11, 0x63, 0x42, 0x8e, 0x8b, 0x7e, 0xe1, + 0x6f, 0xd4, 0xb8, 0x23, 0xb3, 0xe3, 0xf6, 0x05, 0xe0, 0xbf, 0x21, 0x51, + 0x6d, 0x9b, 0x95, 0x5a, 0xce, 0x58, 0xe5, 0x0e, 0xbf, 0x09, 0xfb, 0xe0, + 0xdc, 0x07, 0xca, 0x98, 0x7c, 0x67, 0xe4, 0x62, 0x5b, 0xf5, 0x3e, 0xd0, + 0x67, 0xa4, 0x9c, 0x3a, 0xf7, 0x81, 0x48, 0x4d, 0x40, 0x3e, 0x6e, 0xe4, + 0x3e, 0x50, 0xd7, 0x92, 0xfb, 0x40, 0x2b, 0xf3, 0x66, 0xe9, 0x7d, 0xa0, + 0xc6, 0xfc, 0xe1, 0xfb, 0x40, 0xff, 0xde, 0xe6, 0xdc, 0x43, 0x5d, 0x89, + 0x3f, 0x6e, 0x9c, 0xf4, 0x11, 0xe0, 0xf9, 0x3e, 0x50, 0xe5, 0x1e, 0x90, + 0xe7, 0x0e, 0x10, 0xdf, 0x25, 0x59, 0xee, 0x0c, 0xce, 0x7b, 0xff, 0xa4, + 0xa7, 0x72, 0xff, 0xe4, 0x7c, 0xc9, 0xf5, 0xed, 0xee, 0xb9, 0x1c, 0xc7, + 0x39, 0xbb, 0x44, 0x8e, 0x7a, 0xae, 0x54, 0x5b, 0xc3, 0x60, 0xbe, 0x8f, + 0x16, 0xcf, 0x81, 0x3e, 0x6f, 0x89, 0xdc, 0x00, 0x7c, 0xde, 0xe2, 0x23, + 0xe6, 0x1d, 0x29, 0xa0, 0x8b, 0x38, 0xcb, 0x75, 0xf8, 0xdd, 0x21, 0x64, + 0xc1, 0x91, 0x8b, 0xdd, 0x9e, 0xf3, 0xd0, 0xaa, 0x1c, 0x38, 0x67, 0xba, + 0x0e, 0xef, 0x6a, 0x65, 0x46, 0x9c, 0xdd, 0x0c, 0xed, 0xb5, 0x9c, 0xf3, + 0xc6, 0xa8, 0x38, 0xb7, 0x6d, 0xaf, 0xb3, 0x5b, 0x3a, 0xe4, 0x06, 0x31, + 0x67, 0x8c, 0xeb, 0xd5, 0x8c, 0xfb, 0x66, 0xc1, 0xe3, 0x46, 0x67, 0x71, + 0x2b, 0xd7, 0xf1, 0xdc, 0x9a, 0x0a, 0x21, 0x97, 0xd8, 0x9d, 0xce, 0x09, + 0xbb, 0xe9, 0xac, 0xdd, 0x29, 0xd6, 0xde, 0x58, 0x77, 0x96, 0xcd, 0x72, + 0xb5, 0x5c, 0x4c, 0x70, 0x3d, 0x9a, 0xde, 0xb3, 0x84, 0xa6, 0xb5, 0xba, + 0x84, 0xdc, 0xb5, 0x62, 0xe3, 0x3b, 0x2a, 0xba, 0x34, 0x2e, 0xee, 0x21, + 0xbb, 0xe7, 0xb5, 0x0e, 0xfd, 0xaa, 0xba, 0xb7, 0x5c, 0x3c, 0x53, 0x4f, + 0xbf, 0x4d, 0xff, 0x4b, 0xe8, 0x77, 0x15, 0xf4, 0xe3, 0x77, 0x03, 0xef, + 0xef, 0x8a, 0x7a, 0xc0, 0xb9, 0x52, 0xe4, 0x78, 0x9e, 0x38, 0x4e, 0x88, + 0xcc, 0x2e, 0x50, 0x0f, 0xe8, 0xc8, 0xff, 0xeb, 0xe2, 0xde, 0x9d, 0x60, + 0xfa, 0xb2, 0x7d, 0x8f, 0xbc, 0x70, 0x99, 0xd8, 0xc6, 0xdf, 0x8d, 0x7d, + 0x94, 0xcb, 0x2f, 0xc5, 0x5c, 0xfa, 0xb3, 0xee, 0x73, 0x9d, 0xaa, 0x76, + 0x5f, 0x7b, 0x57, 0xed, 0x53, 0x1d, 0xf9, 0xcc, 0x34, 0x90, 0xcf, 0x8c, + 0xdc, 0xa3, 0x6f, 0xa6, 0x71, 0xbc, 0x9a, 0x9a, 0xfc, 0xef, 0x5e, 0xae, + 0x26, 0xb6, 0x8d, 0x22, 0x0a, 0xbf, 0xac, 0xd7, 0x4e, 0xe3, 0xa4, 0x61, + 0x93, 0x3a, 0xad, 0x69, 0xd2, 0x60, 0xc7, 0x4b, 0x12, 0x29, 0xa5, 0xa4, + 0x52, 0x55, 0x45, 0x60, 0xa9, 0x21, 0x4e, 0xda, 0x0a, 0x71, 0x70, 0x0b, + 0x48, 0x51, 0xc5, 0x21, 0x4d, 0xd3, 0x7b, 0x85, 0x84, 0x54, 0xa1, 0x8a, + 0x46, 0x4e, 0x02, 0x15, 0x4a, 0xe5, 0x0a, 0x96, 0x72, 0x41, 0xa2, 0xd8, + 0x8e, 0x02, 0x52, 0x2a, 0xf7, 0xca, 0x85, 0xba, 0xbf, 0x08, 0x89, 0x03, + 0x70, 0x06, 0x29, 0x2a, 0x3f, 0xe2, 0xc0, 0x8d, 0x1b, 0x54, 0x5d, 0xde, + 0x37, 0xb3, 0x63, 0xaf, 0x77, 0xd7, 0x8e, 0x03, 0x11, 0x07, 0x27, 0xbb, + 0xf6, 0xcc, 0xce, 0xec, 0xcc, 0x37, 0x6f, 0xbe, 0xf7, 0x37, 0xfd, 0xbe, + 0x78, 0x8d, 0x5a, 0xdb, 0x5b, 0xf3, 0x55, 0xec, 0xe7, 0xaf, 0x37, 0x18, + 0x57, 0xed, 0xba, 0xe4, 0xa9, 0xf5, 0xe3, 0x9a, 0x72, 0xd9, 0x1b, 0xf0, + 0xfe, 0xc7, 0x68, 0x51, 0xd8, 0x86, 0x94, 0xad, 0xee, 0xc5, 0x40, 0x9b, + 0xd9, 0xff, 0x33, 0x16, 0x03, 0x3e, 0x9b, 0x68, 0xad, 0x6d, 0x8a, 0xed, + 0x71, 0xd9, 0x16, 0xde, 0xda, 0xc2, 0xb6, 0x10, 0x3c, 0x16, 0xfd, 0x9e, + 0xb1, 0xa8, 0xc9, 0xea, 0xa1, 0x16, 0xed, 0x74, 0x88, 0x21, 0xbf, 0x9d, + 0x67, 0x6c, 0x05, 0xca, 0xce, 0x4f, 0x5d, 0x36, 0x3c, 0xe0, 0x73, 0xdc, + 0x59, 0xeb, 0xc0, 0x27, 0xb5, 0x9d, 0x1a, 0x51, 0xed, 0x01, 0x8f, 0xc9, + 0xc5, 0x45, 0x82, 0xbe, 0x86, 0x36, 0xe3, 0x82, 0xe3, 0xfa, 0x39, 0x14, + 0x8f, 0xf1, 0xfa, 0x1b, 0x88, 0xe5, 0x70, 0xda, 0x3f, 0xd9, 0x76, 0xae, + 0x9c, 0xe5, 0xbd, 0x42, 0xd4, 0x63, 0xbd, 0xef, 0x52, 0xdb, 0x82, 0xa8, + 0x27, 0xe3, 0x20, 0x1c, 0x1d, 0xd0, 0xe1, 0xe2, 0x8d, 0x74, 0x3f, 0xff, + 0x9e, 0x13, 0xcc, 0xdd, 0x7f, 0xdd, 0x1d, 0x36, 0x3f, 0x34, 0x64, 0xae, + 0xde, 0x56, 0xdc, 0x5d, 0xd9, 0x89, 0x06, 0x85, 0xaf, 0xc1, 0xad, 0x7b, + 0x41, 0x76, 0x5d, 0xe0, 0x3d, 0x7c, 0xa8, 0xba, 0x7f, 0xef, 0x84, 0x7d, + 0xe8, 0x99, 0x16, 0x62, 0x1d, 0x44, 0x8e, 0xe5, 0x2b, 0x53, 0xc8, 0x45, + 0xaa, 0xe6, 0xef, 0x78, 0xf3, 0x3c, 0x20, 0x3f, 0x55, 0x9e, 0x87, 0xca, + 0x23, 0xc5, 0x7b, 0x24, 0x02, 0xf2, 0x3c, 0xdc, 0x32, 0x18, 0xf5, 0xea, + 0xdf, 0xc3, 0x2d, 0x7f, 0x57, 0x1c, 0xf9, 0x5b, 0xf0, 0xd8, 0xe3, 0x97, + 0xf3, 0x6a, 0x2d, 0x20, 0xe7, 0x43, 0xf1, 0x94, 0xde, 0x00, 0x9e, 0x12, + 0x9c, 0xeb, 0xa1, 0xa5, 0x2f, 0xf2, 0x5e, 0x7e, 0x08, 0x7b, 0xb9, 0x51, + 0x8b, 0xe9, 0x95, 0x72, 0xf0, 0xdc, 0x3a, 0x64, 0xa2, 0xca, 0xb9, 0x81, + 0x5c, 0x44, 0x2c, 0x3c, 0xe6, 0xba, 0xe4, 0x60, 0x11, 0xbf, 0xa9, 0x58, + 0x52, 0xa5, 0x47, 0xbd, 0x23, 0xf2, 0x0c, 0xbe, 0x1b, 0x3f, 0xcc, 0x1c, + 0x18, 0xf2, 0x13, 0x76, 0xa6, 0x43, 0x0e, 0x1f, 0xbe, 0xcc, 0xbf, 0x8d, + 0x39, 0xd7, 0x92, 0x8b, 0xca, 0x6b, 0xa5, 0x4b, 0xfd, 0xd0, 0x41, 0xe6, + 0x6f, 0x0e, 0x2f, 0xad, 0xb3, 0x41, 0xc4, 0x53, 0xda, 0xdb, 0x74, 0xa1, + 0xd8, 0x0c, 0x83, 0xf5, 0xf8, 0x4b, 0x79, 0x38, 0x4f, 0x42, 0x70, 0x9e, + 0x9f, 0x3a, 0xc2, 0xe6, 0x44, 0x4f, 0xb3, 0x38, 0x9c, 0x53, 0x55, 0xfc, + 0xa9, 0x72, 0xaa, 0x6f, 0x8f, 0x3a, 0x10, 0xa7, 0xe6, 0xc7, 0x04, 0xe6, + 0x1f, 0xfa, 0x9c, 0x5a, 0x87, 0xd0, 0xeb, 0x10, 0xf3, 0x87, 0x76, 0x8d, + 0x06, 0x6b, 0xb0, 0x66, 0x13, 0x2f, 0x50, 0x2b, 0xb1, 0x7f, 0xc9, 0xd1, + 0x0a, 0x9d, 0xed, 0x69, 0xa6, 0xf3, 0x9e, 0x08, 0xd4, 0x79, 0x83, 0x72, + 0xa4, 0xcc, 0x80, 0x1c, 0x29, 0x37, 0x0e, 0x75, 0x17, 0x0e, 0xe3, 0x2e, + 0x2e, 0x30, 0xc0, 0xdc, 0xb9, 0x8b, 0xf1, 0x04, 0xee, 0x1c, 0xa5, 0xd0, + 0x07, 0x6e, 0xee, 0xec, 0xf7, 0x13, 0x49, 0x5c, 0xfe, 0xdb, 0xdc, 0xa9, + 0xa0, 0x7e, 0x27, 0x7c, 0xfd, 0x86, 0x1c, 0x9f, 0x6c, 0xc8, 0x13, 0x82, + 0x38, 0xfe, 0x4e, 0xf7, 0xd3, 0xbb, 0xf6, 0xd1, 0xa6, 0x09, 0xfd, 0x70, + 0x74, 0xb1, 0xba, 0xee, 0x5f, 0xf0, 0xd9, 0xb9, 0xc1, 0x67, 0x43, 0xc2, + 0x27, 0xd7, 0x25, 0xf6, 0x90, 0x9d, 0x93, 0x61, 0x9d, 0x1e, 0x19, 0x66, + 0xf7, 0xd4, 0xec, 0xfc, 0x88, 0x21, 0xec, 0x73, 0x74, 0x0e, 0xb9, 0xef, + 0x14, 0x1a, 0xc6, 0xa5, 0xe2, 0x3b, 0xe9, 0x1b, 0x38, 0x77, 0x04, 0xb2, + 0x1b, 0xf2, 0xfc, 0xf4, 0x6c, 0xd8, 0x34, 0x1c, 0x1f, 0x03, 0xfc, 0x08, + 0xc0, 0xa9, 0x7a, 0x7e, 0x90, 0x0d, 0x3d, 0x68, 0x0e, 0x87, 0x7c, 0x73, + 0x28, 0xf1, 0x06, 0x6e, 0x8f, 0x58, 0xbc, 0x83, 0x9e, 0x38, 0xc5, 0x9d, + 0x18, 0x93, 0xee, 0x80, 0x78, 0x41, 0xc4, 0xfa, 0xf9, 0xfa, 0xcb, 0xef, + 0x7c, 0x51, 0xf3, 0xaf, 0xad, 0x49, 0x6d, 0xba, 0x3c, 0xad, 0x4d, 0x15, + 0x51, 0xee, 0xa2, 0x56, 0xdb, 0x97, 0x36, 0x5d, 0x1c, 0x11, 0x7c, 0x30, + 0x79, 0xad, 0x42, 0x78, 0x4f, 0xdb, 0xbe, 0x25, 0xb8, 0xed, 0x80, 0x0f, + 0xab, 0x8a, 0x73, 0x18, 0x2d, 0xbc, 0x97, 0xb4, 0xbd, 0xb8, 0xb9, 0x8e, + 0x5b, 0xbe, 0x3f, 0x1d, 0x20, 0xdf, 0x9b, 0xd9, 0x0a, 0x91, 0xbf, 0x29, + 0xe2, 0xb2, 0xa9, 0x68, 0x21, 0xde, 0xf1, 0x30, 0xe2, 0x7b, 0xe1, 0xd7, + 0xa8, 0x62, 0xe1, 0x6e, 0x30, 0x16, 0xaa, 0xf6, 0x60, 0x1d, 0xb9, 0xa3, + 0x2c, 0x8b, 0xc3, 0xe9, 0x5e, 0x0a, 0x99, 0x28, 0xff, 0x6c, 0xe2, 0x3e, + 0x1d, 0x73, 0x78, 0x09, 0xfc, 0x3c, 0xb2, 0xde, 0x4c, 0x0b, 0x76, 0xe1, + 0x60, 0x7f, 0x46, 0x84, 0x65, 0xf3, 0x67, 0xbd, 0xad, 0xf9, 0x33, 0x54, + 0x39, 0xd4, 0xed, 0xa2, 0x35, 0x0b, 0x71, 0x92, 0xf0, 0x2f, 0x75, 0x77, + 0xb4, 0x9b, 0x41, 0xf2, 0x4f, 0xc5, 0x7e, 0x82, 0x1f, 0xc9, 0xb9, 0xba, + 0x41, 0x98, 0x3b, 0x9b, 0xbe, 0x6f, 0x30, 0x57, 0xdb, 0xb1, 0x29, 0x37, + 0x9f, 0x2b, 0xc3, 0x33, 0x57, 0xd8, 0x8b, 0x9a, 0xcd, 0x95, 0xf2, 0x43, + 0x2a, 0xdf, 0xdc, 0x51, 0xc8, 0x93, 0x45, 0xf7, 0x5c, 0xed, 0x8c, 0x7f, + 0x4e, 0xce, 0xd9, 0x4e, 0xfb, 0xe0, 0x1a, 0x8f, 0x43, 0x34, 0xd0, 0x76, + 0x12, 0x2c, 0x33, 0xfc, 0x6b, 0xeb, 0x86, 0x5c, 0x5b, 0xcc, 0x2b, 0x9e, + 0x6f, 0xb8, 0xb6, 0xb0, 0x0f, 0x5c, 0x70, 0xf6, 0x81, 0xd3, 0x3e, 0x7d, + 0x51, 0xd9, 0xbc, 0xff, 0xab, 0xed, 0x0d, 0xcf, 0x7d, 0x22, 0xce, 0xe9, + 0xc8, 0x91, 0xdc, 0x47, 0xce, 0x37, 0xe4, 0x61, 0x3d, 0xdb, 0x5c, 0xa7, + 0x6a, 0xee, 0x91, 0x73, 0x01, 0x79, 0x99, 0xa5, 0xf3, 0xf9, 0xc7, 0x06, + 0x75, 0xf7, 0x53, 0xa4, 0x1a, 0xd3, 0x72, 0x40, 0xf0, 0x61, 0xb7, 0xbe, + 0xbc, 0xec, 0xe4, 0x28, 0xe6, 0x5c, 0x63, 0xb0, 0x9c, 0xcf, 0x36, 0x89, + 0xa7, 0x6f, 0x25, 0x9e, 0x63, 0xc0, 0x23, 0x37, 0xbd, 0x73, 0x35, 0xa1, + 0x65, 0xf2, 0xa8, 0xb3, 0x87, 0xce, 0xea, 0x9f, 0xf0, 0x18, 0x3d, 0xb1, + 0x23, 0xe2, 0x9c, 0x11, 0xe0, 0xd2, 0xb6, 0x97, 0xcd, 0x0e, 0x5a, 0x94, + 0x7e, 0x46, 0x9a, 0xfa, 0xf8, 0x12, 0x15, 0x85, 0x7f, 0x0b, 0xb9, 0x51, + 0xb0, 0x71, 0xc3, 0x47, 0x87, 0xe7, 0xf0, 0xf7, 0x1b, 0x13, 0x8e, 0xcc, + 0xfd, 0x93, 0x31, 0x8c, 0x7a, 0x38, 0x0b, 0x01, 0xeb, 0x9d, 0x34, 0xc9, + 0x31, 0xb9, 0x1d, 0x71, 0x4e, 0x80, 0x8c, 0xcd, 0xbb, 0x5d, 0xde, 0x8e, + 0x4f, 0xa1, 0x55, 0xbd, 0xe4, 0xeb, 0x68, 0xd8, 0xfc, 0x72, 0xcf, 0xf6, + 0x7d, 0x0a, 0x2a, 0x77, 0x5f, 0x71, 0x58, 0x75, 0x2d, 0x73, 0x69, 0xc1, + 0x99, 0xe7, 0xd7, 0x55, 0xde, 0x6d, 0x77, 0x40, 0xde, 0x6d, 0x88, 0xe6, + 0x84, 0xaf, 0x2e, 0x44, 0x39, 0x47, 0x37, 0x93, 0x9c, 0x5a, 0xd9, 0x6a, + 0x23, 0x4e, 0xfc, 0x29, 0xee, 0xdd, 0x39, 0xf9, 0x7c, 0x5f, 0x04, 0xcf, + 0x46, 0x4e, 0xb5, 0x2d, 0x62, 0xf1, 0x33, 0xa2, 0x5c, 0xa7, 0xa7, 0x1c, + 0xdf, 0x17, 0xd5, 0x33, 0x3b, 0xb9, 0x7c, 0x8a, 0x64, 0x0e, 0x7d, 0x27, + 0xcd, 0x15, 0x9b, 0xf5, 0x6b, 0x1f, 0xe2, 0x81, 0xe3, 0xf0, 0x95, 0x0a, + 0xbf, 0x95, 0xa1, 0xfa, 0x80, 0x3e, 0xb5, 0x57, 0xfb, 0x04, 0xf9, 0x14, + 0x12, 0x7e, 0x05, 0xbe, 0x76, 0xda, 0x99, 0x23, 0x77, 0xbf, 0xc2, 0xdc, + 0x2f, 0x3c, 0xa7, 0xd3, 0x55, 0xb6, 0xd3, 0x55, 0xb6, 0x36, 0x5e, 0x3a, + 0xeb, 0x54, 0x0b, 0xe5, 0x1f, 0x59, 0x2f, 0xfd, 0x56, 0xd8, 0xe6, 0xe6, + 0xb3, 0x06, 0x2d, 0xac, 0xf7, 0xf2, 0x27, 0xc6, 0x1f, 0x94, 0xdb, 0xcb, + 0xff, 0xdd, 0x9c, 0xa2, 0x5f, 0xc4, 0x02, 0xb6, 0xce, 0x07, 0x83, 0xf1, + 0x1f, 0xbc, 0x6e, 0x13, 0x01, 0xeb, 0xb6, 0xf9, 0xbe, 0x22, 0xf7, 0x93, + 0xe4, 0x95, 0x8a, 0x23, 0xaf, 0x36, 0x69, 0xd0, 0x27, 0xa7, 0x82, 0xd6, + 0x29, 0xfa, 0x78, 0xca, 0xe9, 0xe3, 0x9b, 0xa2, 0x3f, 0xe3, 0x54, 0xa8, + 0xe6, 0x0d, 0x1f, 0xe1, 0xeb, 0x98, 0xb2, 0xd1, 0x35, 0x90, 0xab, 0xdf, + 0x6c, 0x43, 0xc6, 0x04, 0x71, 0xb2, 0x03, 0x01, 0xfa, 0x80, 0xee, 0xd2, + 0x07, 0xe2, 0x55, 0x7d, 0x60, 0x45, 0xe8, 0x09, 0xbb, 0x1c, 0x1d, 0x34, + 0xd8, 0x16, 0x97, 0xcb, 0xe3, 0xcc, 0x1b, 0xd8, 0xf8, 0xa4, 0x1d, 0x7d, + 0xda, 0xaa, 0x9e, 0x99, 0xc3, 0xba, 0x65, 0x8d, 0x4b, 0xfb, 0xe5, 0x09, + 0xce, 0xac, 0xa8, 0xcc, 0x3e, 0x30, 0xa3, 0xa4, 0xa5, 0x93, 0xf1, 0xa9, + 0x50, 0x84, 0x16, 0xac, 0x28, 0x15, 0xac, 0x14, 0x73, 0x70, 0xf0, 0xe3, + 0xd0, 0x80, 0x46, 0x11, 0x96, 0x35, 0x11, 0x2a, 0x95, 0x94, 0x4e, 0x76, + 0x86, 0xc8, 0x2c, 0xc6, 0xa4, 0x0d, 0x9b, 0x71, 0x9a, 0x1f, 0x33, 0xe6, + 0x49, 0x43, 0xcc, 0x8b, 0x93, 0xa3, 0x0e, 0x0c, 0x8a, 0x38, 0x4b, 0xfd, + 0xe5, 0x91, 0x28, 0xb5, 0xa7, 0xa5, 0xcd, 0x68, 0x86, 0xdb, 0xf8, 0xc2, + 0x8a, 0xd1, 0x95, 0x7c, 0xd2, 0x38, 0xc1, 0xed, 0x64, 0xac, 0x64, 0x62, + 0x92, 0x9f, 0x5d, 0x2c, 0x45, 0x28, 0x67, 0x45, 0xa8, 0x50, 0x4a, 0x19, + 0x43, 0x6d, 0xa2, 0xcd, 0x18, 0xda, 0x7c, 0x49, 0x1f, 0x33, 0x4e, 0x92, + 0xbb, 0xcd, 0xaf, 0x9c, 0x36, 0xbd, 0x6d, 0xfd, 0x61, 0xe3, 0xfe, 0x44, + 0xa8, 0x32, 0x7b, 0x9f, 0xf1, 0x92, 0x5b, 0x9d, 0x60, 0xd9, 0x14, 0x13, + 0x67, 0xdb, 0x68, 0xe9, 0x34, 0xcb, 0x1d, 0x9c, 0x6d, 0x61, 0xd0, 0x62, + 0x39, 0x4e, 0xef, 0x57, 0xed, 0x07, 0x12, 0x43, 0x39, 0x91, 0x43, 0x84, + 0x33, 0x17, 0x2a, 0xb3, 0xbf, 0x9b, 0x5e, 0x7f, 0x3f, 0xeb, 0x5b, 0x1f, + 0xc5, 0x28, 0x72, 0x15, 0x71, 0xdd, 0x36, 0x5d, 0x1b, 0x4f, 0x5e, 0xd9, + 0x14, 0x79, 0x68, 0x09, 0x5a, 0x33, 0xa5, 0x3c, 0xcd, 0x71, 0xf9, 0x15, + 0x94, 0x5b, 0x4b, 0xd0, 0x3d, 0x91, 0x8f, 0xd6, 0x4e, 0x77, 0xf4, 0x18, + 0x85, 0x6e, 0x9a, 0xc6, 0xbc, 0xf0, 0x0b, 0x57, 0x66, 0x87, 0x86, 0x0d, + 0xd2, 0xae, 0xa2, 0x1e, 0xff, 0xbf, 0x89, 0xfb, 0x28, 0x61, 0x7e, 0x66, + 0xac, 0x31, 0x5e, 0x49, 0xc3, 0xf1, 0x12, 0x64, 0xf3, 0x41, 0x89, 0xa5, + 0x39, 0x23, 0x42, 0xd0, 0x5f, 0x61, 0x7b, 0xeb, 0x35, 0x27, 0x7b, 0xa4, + 0xfe, 0xe4, 0x3b, 0x9b, 0x43, 0x9f, 0x19, 0x71, 0x9f, 0xcf, 0x51, 0x7b, + 0x66, 0xc6, 0x92, 0xef, 0xb9, 0x52, 0xee, 0xa5, 0x25, 0x6e, 0x7b, 0x64, + 0xf8, 0x8c, 0x73, 0xa6, 0x0f, 0xff, 0xd9, 0x8b, 0x7b, 0x85, 0xb7, 0x7d, + 0x7d, 0x14, 0xc5, 0x3d, 0x0d, 0xe8, 0x3c, 0xc7, 0xb0, 0xe9, 0x87, 0xc5, + 0xb8, 0xa7, 0xe2, 0x98, 0xcb, 0xb9, 0xb8, 0x3a, 0x97, 0x08, 0x65, 0xba, + 0xe9, 0x91, 0xd5, 0x45, 0x3f, 0x8b, 0xf3, 0x47, 0xf8, 0xba, 0x84, 0x9c, + 0xa3, 0x36, 0xca, 0x64, 0xbb, 0x69, 0xb3, 0x14, 0x66, 0x71, 0x05, 0xec, + 0x44, 0xb9, 0x4c, 0x81, 0xa6, 0xd6, 0x5f, 0xeb, 0x83, 0x1f, 0x66, 0x52, + 0xab, 0x61, 0xe9, 0x51, 0x00, 0x96, 0x7e, 0xa9, 0xc3, 0xd2, 0xd1, 0xbe, + 0xe6, 0x58, 0xea, 0x77, 0x62, 0xd6, 0xa3, 0x14, 0x71, 0x70, 0xf4, 0x39, + 0xe3, 0xe8, 0x3d, 0xc6, 0xd1, 0xf1, 0x06, 0x38, 0xd2, 0x3c, 0x38, 0x3a, + 0x51, 0x87, 0xa3, 0x6c, 0x5f, 0x33, 0x1c, 0x1d, 0x0f, 0xa1, 0xff, 0xcd, + 0xd6, 0x32, 0xfa, 0xb0, 0x9f, 0x39, 0xbd, 0x49, 0xa5, 0xd5, 0xe4, 0xf8, + 0x24, 0x55, 0x90, 0x73, 0x92, 0x58, 0xa2, 0xb4, 0xe0, 0x76, 0x05, 0x81, + 0xbf, 0x2c, 0x8f, 0xc9, 0xae, 0x06, 0xe7, 0xaa, 0x24, 0x9c, 0x79, 0x93, + 0x73, 0x99, 0xc9, 0x57, 0x66, 0x1f, 0x32, 0x36, 0xee, 0x6d, 0xe8, 0x3a, + 0x7e, 0x0b, 0xb1, 0x8c, 0xbc, 0xbb, 0x81, 0x73, 0x5b, 0xe2, 0x74, 0xdf, + 0x1a, 0xa0, 0x7b, 0xd6, 0x7e, 0xba, 0x6b, 0x0d, 0xd2, 0x03, 0x0b, 0x6d, + 0x60, 0x0e, 0xf8, 0x5e, 0xcc, 0x81, 0x46, 0x33, 0x31, 0x2e, 0x53, 0xda, + 0x4f, 0x95, 0x92, 0xc2, 0x35, 0xb0, 0x03, 0x0c, 0x35, 0xc6, 0x4e, 0xa6, + 0x0e, 0x3b, 0xb2, 0x0e, 0x30, 0xb3, 0xe4, 0xb7, 0xad, 0xed, 0x32, 0xf8, + 0x5d, 0x0d, 0xc6, 0x56, 0x58, 0xc4, 0x91, 0x24, 0x47, 0x67, 0x42, 0x90, + 0x59, 0xb7, 0x18, 0x53, 0x3c, 0x17, 0x3c, 0x7e, 0xda, 0xf5, 0x41, 0x96, + 0x39, 0x4f, 0x09, 0x1b, 0xf4, 0x94, 0xa9, 0xc7, 0x33, 0x64, 0x5f, 0xd6, + 0xcc, 0x31, 0x91, 0xeb, 0xb6, 0x54, 0xf6, 0x9e, 0x31, 0x91, 0xe1, 0xb1, + 0x57, 0x78, 0xf4, 0xca, 0xa1, 0x76, 0xaa, 0x38, 0x31, 0x4c, 0x85, 0x55, + 0xdb, 0x7e, 0xc8, 0xfc, 0x7f, 0xcd, 0x84, 0xcc, 0xfe, 0xdb, 0xae, 0xc4, + 0x74, 0x5a, 0x36, 0x55, 0xdf, 0xee, 0x08, 0x7c, 0x31, 0x47, 0xa4, 0x77, + 0x37, 0xaa, 0xaf, 0xc4, 0xbf, 0xe3, 0xbb, 0xbf, 0x04, 0x97, 0x59, 0xab, + 0x96, 0x85, 0xed, 0xf8, 0xd2, 0xd8, 0xc2, 0x2a, 0xce, 0x7e, 0x7b, 0xfc, + 0xea, 0xf9, 0xd5, 0x5c, 0x1f, 0x4b, 0xd8, 0x94, 0x4e, 0x76, 0x68, 0x79, + 0x3c, 0xf7, 0x5c, 0x98, 0x86, 0x19, 0x97, 0x38, 0x83, 0x6b, 0x6c, 0x34, + 0x2c, 0xce, 0x38, 0xd9, 0xcd, 0x78, 0xc8, 0x0a, 0x3b, 0xfd, 0xd4, 0x91, + 0x09, 0x9a, 0x2c, 0xa7, 0xf9, 0x53, 0x3f, 0x7e, 0xb5, 0xb9, 0xe3, 0xe1, + 0x48, 0xe3, 0x37, 0x37, 0xff, 0xa8, 0xd5, 0x9d, 0xe6, 0xba, 0x33, 0x5b, + 0xd6, 0x55, 0xe7, 0x12, 0xfd, 0x03, 0x69, 0xae, 0x1b, 0xa3, 0xbc, 0x57, + 0x00, 0x00, 0x00 }; static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 }; static u32 bnx2_COM_b06FwRodata[(0x58/4) + 1] = { @@ -989,952 +687,368 @@ static u32 bnx2_RXP_b06FwBssAddr = 0x08005900; static int bnx2_RXP_b06FwBssLen = 0x13a4; static u32 bnx2_RXP_b06FwSbssAddr = 0x080058e0; static int bnx2_RXP_b06FwSbssLen = 0x1c; -static u32 bnx2_RXP_b06FwText[(0x588c/4) + 1] = { - 0x0a000c61, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e362e, - 0x31000000, 0x02060103, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, - 0x3c020800, 0x244258e0, 0x3c030800, 0x24636ca4, 0xac400000, 0x0043202b, - 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, - 0x26103184, 0x3c1c0800, 0x279c58e0, 0x0e00104a, 0x00000000, 0x0000000d, - 0x27bdffe8, 0xafb00010, 0xafbf0014, 0x0e000f1d, 0x00808021, 0x1440000d, - 0x00000000, 0x8f820010, 0x10400005, 0x00000000, 0x9743011c, 0x9742011e, - 0x0a000c89, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, - 0xaf830004, 0x8f840008, 0x3c020020, 0x34424000, 0x00821824, 0x54620004, - 0x3c020020, 0x8f820014, 0x0a000c9a, 0x34421000, 0x34428000, 0x00821824, - 0x14620004, 0x00000000, 0x8f820014, 0x34428000, 0xaf820014, 0x8f820008, - 0x9743010c, 0x00403021, 0x30421000, 0x10400010, 0x3069ffff, 0x30c20020, - 0x1440000e, 0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff, - 0x3463ffff, 0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001, - 0x0a000cb2, 0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d, - 0x00405821, 0x8f820014, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01, - 0x00c24024, 0x3c031000, 0x15030015, 0x3c020001, 0x31220200, 0x14400012, - 0x3c020001, 0x9744010e, 0x24020003, 0xa342018b, 0x97850016, 0x24020002, - 0x34e30002, 0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff, - 0xa744018e, 0xa74501a6, 0xaf4801b8, 0x0a000f19, 0x00001021, 0x3c020001, - 0x00c21024, 0x1040002f, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9784000a, - 0x8f850004, 0x8f870014, 0x24020080, 0x24030002, 0xaf420180, 0x24020003, - 0xa743018c, 0xa746018e, 0xa7420188, 0x30e28000, 0xa7440190, 0x1040000c, - 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, - 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014, - 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, - 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, - 0x00001021, 0x8f820014, 0x30434000, 0x10600016, 0x00404021, 0x3c020f00, - 0x00c21024, 0x14400012, 0x00000000, 0x93420116, 0x34424000, 0x03421821, - 0x94650002, 0x2ca21389, 0x1040000b, 0x3c020800, 0x24425900, 0x00051942, - 0x00031880, 0x00621821, 0x30a5001f, 0x8c640000, 0x24020001, 0x00a21004, - 0x00822024, 0x02048025, 0x12000030, 0x3c021000, 0x9742010e, 0x34e80002, - 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180, - 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, - 0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, - 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, - 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, - 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, - 0xaf4201b8, 0x0a000f19, 0x00001021, 0x00c21024, 0x104000c0, 0x3c020800, - 0x8c430030, 0x10600037, 0x31024000, 0x10400035, 0x3c030f00, 0x00c31824, - 0x3c020100, 0x0043102b, 0x14400031, 0x3c030800, 0x9742010e, 0x34e80002, - 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020080, - 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, - 0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, - 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, - 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, - 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, - 0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008, - 0x10400035, 0x34ea0002, 0x3c020f00, 0x00c21024, 0x14400032, 0x8d620034, - 0x31220200, 0x1040002f, 0x8d620034, 0x9742010e, 0x30e8fffb, 0x3c038000, - 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, - 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180, 0x24030002, - 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, 0xa7440190, - 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, - 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024, - 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, - 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, - 0x8d620034, 0x8f860008, 0x10400012, 0x30c20100, 0x10400010, 0x3c020f00, - 0x00c21024, 0x3c030200, 0x1043000c, 0x3c020800, 0x8c430038, 0x8f840004, - 0x3c020800, 0x2442003c, 0x2463ffff, 0x00832024, 0x00822021, 0x90830000, - 0x24630004, 0x0a000de1, 0x000329c0, 0x00000000, 0x00061602, 0x3042000f, - 0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300, 0x0062182b, 0x50600001, - 0x24050800, 0x9742010e, 0x3148ffff, 0x3c038000, 0x24420004, 0x3046ffff, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a, - 0x8f840004, 0x8f870014, 0x24020002, 0xaf450180, 0xa742018c, 0xa746018e, - 0xa7480188, 0x30e28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, - 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, - 0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, - 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, - 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x8f424000, - 0x30420100, 0x104000d5, 0x3c020800, 0x8c440024, 0x24030001, 0x1483002f, - 0x00405021, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3045ffff, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a, - 0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c, 0xa745018e, - 0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, - 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, - 0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016, 0x9743010c, - 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, - 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x30820001, - 0x1040002e, 0x30eb0004, 0x9742010e, 0x30e9fffb, 0x3c038000, 0x24420004, - 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, - 0x9783000a, 0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c, - 0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8, - 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, - 0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016, - 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, - 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3127ffff, 0x8d420024, - 0x30420004, 0x10400030, 0x8d420024, 0x9742010e, 0x30e9fffb, 0x3c038000, - 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, - 0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020100, 0x24030002, - 0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000, 0xa7440190, - 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, - 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x01021024, - 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, - 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, - 0x3127ffff, 0x8d420024, 0x30420008, 0x1040002d, 0x00000000, 0x9742010e, - 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020180, - 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000, - 0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, - 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, - 0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, - 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, - 0xaf4201b8, 0x15600041, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b, - 0xa4800010, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800, - 0x8c620024, 0x30420001, 0x1040002e, 0x00001021, 0x9742010e, 0x34e70002, - 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x24020003, 0xa342018b, 0x9783000a, 0x8f840004, 0x8f860014, 0x24020002, - 0xaf400180, 0xa742018c, 0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190, - 0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, - 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024, - 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, - 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, - 0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x8f4b0070, - 0x93420112, 0x8f840008, 0x00022882, 0x30820100, 0x14400003, 0x24a30003, - 0x03e00008, 0x00001021, 0x30824000, 0x10400010, 0x27424000, 0x00031880, - 0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021, - 0x8c490000, 0x93430116, 0x27424000, 0x306300fc, 0x00431021, 0x8c4a0000, - 0x0a000f45, 0x3c030800, 0x30822000, 0x1040ffea, 0x00031880, 0x27424000, - 0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021, - 0x8c490000, 0x00005021, 0x3c030800, 0x24680100, 0x00071602, 0x00021080, - 0x00481021, 0x8c460000, 0x00071b82, 0x306303fc, 0x01031821, 0x8c640400, - 0x00071182, 0x304203fc, 0x01021021, 0x8c450800, 0x30e300ff, 0x00031880, - 0x01031821, 0x00091602, 0x00021080, 0x01021021, 0x00c43026, 0x8c640c00, - 0x8c431000, 0x00c53026, 0x00091382, 0x304203fc, 0x01021021, 0x8c451400, - 0x312200ff, 0x00021080, 0x01021021, 0x00c43026, 0x00c33026, 0x00091982, - 0x306303fc, 0x01031821, 0x8c641800, 0x8c431c00, 0x00c53026, 0x00c43026, - 0x11400015, 0x00c33026, 0x000a1602, 0x00021080, 0x01021021, 0x8c432000, - 0x000a1382, 0x304203fc, 0x01021021, 0x8c452400, 0x314200ff, 0x00021080, - 0x01021021, 0x00c33026, 0x000a1982, 0x306303fc, 0x01031821, 0x8c642800, - 0x8c432c00, 0x00c53026, 0x00c43026, 0x00c33026, 0x8f430070, 0x3c050800, - 0x8ca43100, 0x2c820020, 0x10400008, 0x006b5823, 0x3c020800, 0x24423104, - 0x00041880, 0x00621821, 0x24820001, 0xac6b0000, 0xaca23100, 0xaf860004, - 0x03e00008, 0x24020001, 0x27bdffe8, 0xafbf0010, 0x8f460128, 0x8f840010, - 0xaf460020, 0x8f450104, 0x8f420100, 0x24030800, 0xaf850008, 0xaf820014, - 0xaf4301b8, 0x1080000a, 0x3c020800, 0x8c430034, 0x10600007, 0x30a22000, - 0x10400005, 0x34a30100, 0x8f82000c, 0xaf830008, 0x24420001, 0xaf82000c, - 0x3c020800, 0x8c4300c0, 0x10600006, 0x3c030800, 0x8c6200c4, 0x24040001, - 0x24420001, 0x0a000fd5, 0xac6200c4, 0x8f820008, 0x3c030010, 0x00431024, - 0x14400009, 0x3c02001f, 0x3c030800, 0x8c620020, 0x00002021, 0x24420001, - 0x0e000c78, 0xac620020, 0x0a000fd5, 0x00402021, 0x3442ff00, 0x14c20009, - 0x2403bfff, 0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e000c78, - 0xac620020, 0x0a000fd5, 0x00402021, 0x8f820014, 0x00431024, 0x14400006, - 0x00000000, 0xaf400048, 0x0e0011a9, 0xaf400040, 0x0a000fd5, 0x00402021, - 0x0e001563, 0x00000000, 0x00402021, 0x10800005, 0x3c024000, 0x8f430124, - 0x3c026020, 0xac430014, 0x3c024000, 0xaf420138, 0x00000000, 0x8fbf0010, - 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010, - 0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000, 0x00621824, 0x3c023000, - 0x10620021, 0x0043102b, 0x14400006, 0x3c024000, 0x3c022000, 0x10620009, - 0x3c024000, 0x0a001040, 0x00000000, 0x10620045, 0x3c025000, 0x10620047, - 0x3c024000, 0x0a001040, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x00000000, 0x8f420148, 0x24030002, 0xa083000b, - 0x00021402, 0xa4820008, 0x8f430148, 0xa4830010, 0x8f420144, 0x3c031000, - 0xac820024, 0xaf4301b8, 0x0a001040, 0x3c024000, 0x8f420148, 0x24030002, - 0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, - 0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001027, 0x3c038000, - 0x12020007, 0x00000000, 0x0a001034, 0x00000000, 0x0e00112c, 0x00000000, - 0x0a001025, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000, - 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, - 0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, - 0x0a001040, 0x3c024000, 0x0000000d, 0x00000000, 0x240002bf, 0x0a001040, - 0x3c024000, 0x0e001441, 0x00000000, 0x0a001040, 0x3c024000, 0x0e0015ea, - 0x00000000, 0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8, - 0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, - 0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, - 0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800, - 0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001, - 0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000, - 0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, - 0x8e021980, 0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd, - 0x32020001, 0x10400004, 0x32020002, 0x0e000f92, 0x00000000, 0x32020002, - 0x1040fff6, 0x00000000, 0x0e000fe0, 0x00000000, 0x0a001071, 0x00000000, - 0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, - 0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, - 0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800, - 0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001, - 0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000, - 0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, - 0x8e021980, 0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008, - 0x27bd0018, 0x00804821, 0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a, - 0x8f840004, 0x8f880014, 0xaf490180, 0xa745018c, 0xa746018e, 0xa7470188, - 0x31028000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc, - 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, - 0x34427fff, 0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, - 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, - 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, - 0xa083000b, 0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, - 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, - 0x8f420148, 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148, - 0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8, - 0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, - 0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, - 0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001117, 0x3c038000, - 0x12020007, 0x00000000, 0x0a001124, 0x00000000, 0x0e00112c, 0x00000000, - 0x0a001115, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000, - 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, - 0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, - 0x0a001128, 0x8fbf0018, 0x0000000d, 0x00000000, 0x240002bf, 0x8fbf0018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, - 0x1040000d, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880, - 0x00a32821, 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, - 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, - 0x1040000e, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880, - 0x00a32821, 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, - 0x00832024, 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x9482000c, - 0x24870014, 0x00021302, 0x00021080, 0x00824021, 0x00e8182b, 0x1060004f, - 0x00000000, 0x90e30000, 0x2c620009, 0x10400047, 0x3c020800, 0x24425890, - 0x00031880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000, 0x0a0011a4, - 0x24e70001, 0x90e30001, 0x2402000a, 0x54620024, 0x01003821, 0x01071023, - 0x2c42000a, 0x54400020, 0x01003821, 0x3c050800, 0x8ca26c98, 0x24e70002, - 0x34420100, 0xaca26c98, 0x90e30000, 0x90e20001, 0x90e40002, 0x90e60003, - 0x24e70004, 0x24a56c98, 0x00031e00, 0x00021400, 0x00621825, 0x00042200, - 0x00641825, 0x00661825, 0xaca30004, 0x90e20000, 0x90e30001, 0x90e40002, - 0x90e60003, 0x24e70004, 0x00021600, 0x00031c00, 0x00431025, 0x00042200, - 0x00441025, 0x00461025, 0x0a0011a4, 0xaca20008, 0x90e30001, 0x24020004, - 0x1062000e, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020003, - 0x10620008, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020002, - 0x14620003, 0x01001021, 0x00601021, 0x00e21021, 0x0a0011a4, 0x00403821, - 0x90e20001, 0x0a0011a4, 0x00e23821, 0x01003821, 0x00e8102b, 0x5440ffb4, - 0x90e30000, 0x03e00008, 0x24020001, 0x27bdff90, 0x3c030800, 0xafbf006c, - 0xafbe0068, 0xafb70064, 0xafb60060, 0xafb5005c, 0xafb40058, 0xafb30054, - 0xafb20050, 0xafb1004c, 0xafb00048, 0xac606c98, 0x93620023, 0x30420010, - 0x1440027c, 0x24020001, 0x93420116, 0x93630005, 0x34424000, 0x30630001, - 0x14600005, 0x0342b021, 0x0e0015e0, 0x00000000, 0x0a001436, 0x8fbf006c, - 0x93420112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x10600012, - 0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1, - 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000, 0x0a0011f1, 0xa0a3000a, - 0x8f420104, 0x3c030040, 0x00431024, 0x1040001d, 0x3c038000, 0x27450180, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, - 0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a3000a, - 0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010, 0xa0a00012, 0xa0a00013, - 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x0e0015e0, - 0xaf4201b8, 0x0a001436, 0x8fbf006c, 0x8f820000, 0x10400016, 0x00000000, - 0x8f420104, 0x3c030001, 0x00431024, 0x10400011, 0x00000000, 0x8ca3000c, - 0x8f620030, 0x1462022d, 0x24020001, 0x8ca30010, 0x8f62002c, 0x14620229, - 0x24020001, 0x9763003a, 0x96c20000, 0x14430225, 0x24020001, 0x97630038, - 0x96c20002, 0x14430221, 0x24020001, 0xaf400048, 0xaf400054, 0xaf400040, - 0x8f740040, 0x8f650048, 0x00b43023, 0x04c10004, 0x00000000, 0x0000000d, - 0x00000000, 0x240001af, 0x9742011a, 0x3052ffff, 0x12400004, 0x8ed30004, - 0x02721021, 0x0a001228, 0x2451ffff, 0x02608821, 0x92d7000d, 0xa7a00020, - 0xa3a0001a, 0xafa00028, 0x9362003f, 0x32e30004, 0x1060003a, 0x305000ff, - 0x24040012, 0x16040006, 0x24020001, 0x3c040800, 0x8c830028, 0x24630001, - 0x0a001328, 0xac830028, 0x8f620044, 0x16620010, 0x27a60010, 0x27450180, - 0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020, 0xafb40028, 0xa3b00022, - 0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, - 0x0a00130d, 0x00000000, 0x8f620044, 0x02621023, 0x0440001a, 0x02651023, - 0x044100d9, 0x24020001, 0x3c020800, 0x8c4300d8, 0x10600004, 0x24020001, - 0xa7a20020, 0x0a00125e, 0xafb40028, 0x2402001a, 0xa7a20020, 0x24020020, - 0xafb40028, 0xa3b00022, 0xa3a40023, 0xa3a2001a, 0x27a60010, 0x27450180, - 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, - 0x00000000, 0x0a001328, 0x24020001, 0x0293f023, 0x1bc00016, 0x025e102a, - 0x54400007, 0x32f700fe, 0x57d2000f, 0x027e9821, 0x32e20001, 0x5440000c, - 0x027e9821, 0x32f700fe, 0x0240f021, 0x3c040800, 0x8c8300c8, 0x00009021, - 0x24020001, 0xa7a20020, 0xafb40028, 0x24630001, 0x0a001282, 0xac8300c8, - 0x025e1023, 0x0a001282, 0x3052ffff, 0x0000f021, 0x24a2ffff, 0x02221823, - 0x1860001f, 0x0072102a, 0x54400019, 0x00a08821, 0x97a20020, 0x3c040800, - 0x8c8300cc, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020, 0x02741026, - 0x2c420001, 0xac8300cc, 0x2cc30001, 0x00431024, 0x1440000a, 0x02401821, - 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x00000000, 0x0a00130d, 0x00000000, 0x00a08821, 0x02431023, 0x3052ffff, - 0x0a0012ae, 0x32f700f6, 0x02741023, 0x18400008, 0x97a20020, 0x3c040800, - 0x8c8300d4, 0xafb30028, 0x34420400, 0x24630001, 0xa7a20020, 0xac8300d4, - 0x32e20002, 0x1040001c, 0x32e20010, 0x8f620044, 0x1662000d, 0x27a60010, - 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000, - 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000, - 0x54400003, 0x8ed50008, 0x0a001328, 0x24020001, 0x8f630054, 0x26a2ffff, - 0x00431023, 0x18400011, 0x27a60010, 0x97a20020, 0x3c040800, 0x8c8300d0, - 0x27450180, 0x3c078000, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020, - 0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000, 0x0a00130d, - 0x00000000, 0x32e20020, 0x10400011, 0x00000000, 0x96c20012, 0x0052102b, - 0x10400008, 0x97a20020, 0x96d20012, 0x12400003, 0x02721021, 0x0a0012f2, - 0x2451ffff, 0x02608821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004, - 0xa7a20020, 0xa3a3001a, 0x8f420104, 0x3c030080, 0x00431024, 0x10400037, - 0x3a03000a, 0x0e001151, 0x02c02021, 0x24030002, 0x1443002b, 0x3c030800, - 0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, - 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, - 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a, - 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012, - 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024, - 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000, - 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a001436, 0x8fbf006c, - 0x8c626c98, 0x30420100, 0x10400003, 0x24636c98, 0x8c620004, 0xaf62017c, - 0x3a03000a, 0x2c630001, 0x3a02000c, 0x2c420001, 0x00621825, 0x14600003, - 0x2402000e, 0x56020030, 0x00009021, 0x52400008, 0x96c4000e, 0x12400004, - 0xa7b20040, 0x02721021, 0x0a001343, 0x2451ffff, 0x02608821, 0x96c4000e, - 0x93630035, 0x8f62004c, 0x00642004, 0x00952021, 0x00821023, 0x18400015, - 0x00000000, 0x8f620018, 0x02621023, 0x1c400015, 0x97a20020, 0x8f620018, - 0x1662001c, 0x00000000, 0x8f62001c, 0x02a21023, 0x1c40000e, 0x97a20020, - 0x8f62001c, 0x16a20015, 0x00000000, 0x8f620058, 0x00821023, 0x18400011, - 0x97a20020, 0x0a001364, 0xafb10028, 0x8f620058, 0x00821023, 0x0441000b, - 0x97a20020, 0xafb10028, 0xafb30034, 0xafb50038, 0xafa4003c, 0x34420020, - 0x0a00136d, 0xa7a20020, 0x02809821, 0x02608821, 0x8f640058, 0x8f62004c, - 0x02a21023, 0x18400009, 0x00000000, 0x8f620054, 0x02a21023, 0x1c400005, - 0x97a20020, 0xafb10028, 0xafb50024, 0x0a001385, 0x34420040, 0x9742011a, - 0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c, - 0x8f620054, 0x10620004, 0x97a20020, 0xafb10028, 0x34420080, 0xa7a20020, - 0x24020014, 0x1202000a, 0x2a020015, 0x10400005, 0x2402000c, 0x12020006, - 0x32e20001, 0x0a0013c6, 0x00000000, 0x24020016, 0x16020035, 0x32e20001, - 0x8f620084, 0x24420001, 0x16a20031, 0x32e20001, 0x24020014, 0x12020021, - 0x2a020015, 0x10400005, 0x2402000c, 0x12020008, 0x32e20001, 0x0a0013c6, - 0x00000000, 0x24020016, 0x1202000c, 0x32e20001, 0x0a0013c6, 0x00000000, - 0x97a30020, 0x2402000e, 0xafb10028, 0xa3b00022, 0xa3a20023, 0xafb50024, - 0x34630054, 0x0a0013c5, 0xa7a30020, 0x97a20020, 0x93a4001a, 0x24030010, - 0xafb10028, 0xa3b00022, 0xa3a30023, 0xafb50024, 0x3442005d, 0x34840002, - 0xa7a20020, 0x0a0013c5, 0xa3a4001a, 0x97a20020, 0x24030012, 0xa3a30023, - 0x93a3001a, 0xafb10028, 0xa3b00022, 0xafb50024, 0x3042fffe, 0x3442005c, - 0x34630002, 0xa7a20020, 0xa3a3001a, 0x32e20001, 0x10400030, 0x2402000c, - 0x12020013, 0x2a02000d, 0x10400005, 0x2402000a, 0x12020008, 0x97a20020, - 0x0a0013f8, 0x32e20009, 0x2402000e, 0x1202001b, 0x32e20009, 0x0a0013f9, - 0x0002102b, 0x93a4001a, 0x24030008, 0xafb10028, 0xa3b00022, 0xa3a30023, - 0x0a0013f4, 0x34420013, 0x97a30020, 0x30620004, 0x14400005, 0x93a2001a, - 0x3463001b, 0xa7a30020, 0x0a0013e7, 0x24030016, 0x3463001b, 0xa7a30020, - 0x24030010, 0xafb10028, 0xa3b00022, 0xa3a30023, 0x34420002, 0x0a0013f7, - 0xa3a2001a, 0x97a20020, 0x93a4001a, 0x24030010, 0xafb10028, 0xa3b00022, - 0xa3a30023, 0x3442001b, 0x34840002, 0xa7a20020, 0xa3a4001a, 0x32e20009, - 0x0002102b, 0x00021023, 0x30420007, 0x12400015, 0x34450003, 0x8f820018, - 0x24030800, 0x27440180, 0x24420001, 0xaf820018, 0x24020004, 0xaf4301b8, - 0xa4850008, 0xa082000b, 0x93430120, 0x00003021, 0x3c021000, 0xa492000e, - 0xac950024, 0xac930028, 0x007e1821, 0xa483000c, 0xaf4201b8, 0x0a001413, - 0x97a20020, 0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, - 0x8fa30028, 0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002, - 0xa0a2000b, 0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012, - 0x93a20023, 0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024, - 0x8fa30038, 0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8, - 0x00c01021, 0x8fbf006c, 0x8fbe0068, 0x8fb70064, 0x8fb60060, 0x8fb5005c, - 0x8fb40058, 0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048, 0x03e00008, - 0x27bd0070, 0x8f470140, 0x8f460148, 0x3c028000, 0x00c24024, 0x00062c02, - 0x30a300ff, 0x24020019, 0x106200e7, 0x27440180, 0x2862001a, 0x1040001f, - 0x24020008, 0x106200be, 0x28620009, 0x1040000d, 0x24020001, 0x10620046, - 0x28620002, 0x50400005, 0x24020006, 0x1060002e, 0x00a01821, 0x0a00155e, - 0x00000000, 0x1062005b, 0x00a01821, 0x0a00155e, 0x00000000, 0x2402000b, - 0x10620084, 0x2862000c, 0x10400005, 0x24020009, 0x106200bc, 0x00061c02, - 0x0a00155e, 0x00000000, 0x2402000e, 0x106200b7, 0x00061c02, 0x0a00155e, - 0x00000000, 0x28620021, 0x10400009, 0x2862001f, 0x104000c1, 0x2402001b, - 0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02, 0x0a00155e, 0x00000000, - 0x240200c2, 0x106200ca, 0x286200c3, 0x10400005, 0x24020080, 0x1062005a, - 0x00a01821, 0x0a00155e, 0x00000000, 0x240200c9, 0x106200cd, 0x30c5ffff, - 0x0a00155e, 0x00000000, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, - 0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a, - 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024, - 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808, 0x11000009, 0x00a01821, - 0x3c020800, 0x24030002, 0xa0436c88, 0x24426c88, 0xac470008, 0x8f430144, - 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, - 0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b, - 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x3c026000, - 0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800, 0x3c058000, 0x8f4201b8, - 0x00451024, 0x1440fffd, 0x00000000, 0xac870000, 0x91026c88, 0x00002821, - 0x10400002, 0x25076c88, 0x8ce50008, 0xac850004, 0xa4830008, 0x91036c88, - 0x24020002, 0xa082000b, 0xa4860010, 0x34630001, 0xa083000a, 0x8f420144, - 0xac820024, 0x91036c88, 0x10600002, 0x00001021, 0x8ce20004, 0xac820028, - 0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006c88, 0x03e00008, 0xac400808, - 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xa082000b, - 0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008, - 0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02, 0x93620005, 0x30420004, - 0x14400020, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020, 0x3c038000, - 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, - 0x34630001, 0x00e31825, 0x34420004, 0xa3620005, 0xaf430020, 0x93620005, - 0x30420004, 0x14400003, 0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x24020005, 0x3c031000, 0xac870000, 0xa082000b, - 0xaf4301b8, 0x0a00150d, 0x00061c02, 0x0000000d, 0x03e00008, 0x00000000, - 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, - 0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a, 0xa083000b, - 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024, 0x03e00008, - 0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, - 0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4860010, - 0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8, - 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, - 0xa4830008, 0x24030002, 0xa082000a, 0x3c021000, 0xac870000, 0xac800004, - 0xa083000b, 0xa4860010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8, - 0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, - 0xac870000, 0xac800004, 0xa4830008, 0xa080000a, 0x0a001518, 0xa082000b, - 0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, - 0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4401a4, - 0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8, 0x0000000d, 0x03e00008, - 0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011, - 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000, - 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040, - 0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008, - 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, - 0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4501a4, - 0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8, 0x3c029000, 0x34420001, - 0x00822025, 0xaf440020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, - 0x00000000, 0x03e00008, 0x00000000, 0x3c028000, 0x34420001, 0x00822025, - 0x03e00008, 0xaf440020, 0x308600ff, 0x27450180, 0x3c038000, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040, - 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000, - 0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024, - 0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008, 0xaf4201b8, 0x24020001, - 0xacc40000, 0x03e00008, 0xa4e50000, 0x24020001, 0xaf400044, 0x03e00008, - 0xaf400050, 0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, - 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, - 0xa4a20008, 0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, - 0x94c20010, 0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, - 0x8cc30014, 0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, - 0x8cc2002c, 0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, - 0x03e00008, 0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e001047, 0x00000000, - 0x00002021, 0x0e000c78, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, - 0x8f460148, 0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, - 0x00061c02, 0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, - 0xaca30024, 0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, - 0x24020005, 0x54e20005, 0xa0a0000a, 0x24020001, 0x0a001609, 0xa0a2000a, - 0xa0a0000a, 0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, - 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, - 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00161f, 0x00a01021, - 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, - 0x24a5ffff, 0x03e00008, 0x00000000, 0x00000000 }; +static u8 bnx2_RXP_b06FwText[] = { + 0x1f, 0x8b, 0x08, 0x08, 0x07, 0x87, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xed, 0x5c, 0x5d, 0x6c, + 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x71, 0x49, 0x91, 0xd4, 0x70, 0xb9, + 0x62, 0x57, 0x12, 0x65, 0xed, 0x8a, 0x43, 0x71, 0x6d, 0x31, 0xce, 0x50, + 0x58, 0xdb, 0x82, 0xb1, 0x48, 0xc7, 0xb3, 0xa4, 0xc8, 0x24, 0x02, 0x42, + 0x1b, 0x42, 0xab, 0xa4, 0xa9, 0xc1, 0x90, 0x72, 0x91, 0x22, 0x2c, 0xa0, + 0x1a, 0x79, 0xf0, 0x43, 0x10, 0x2f, 0x56, 0x3f, 0xa6, 0xd1, 0x8d, 0x96, + 0xb6, 0x1c, 0x53, 0x08, 0x82, 0x82, 0xe5, 0x52, 0x52, 0x0b, 0x2c, 0xb4, + 0x96, 0xed, 0x36, 0x7e, 0xa8, 0x23, 0x9a, 0x92, 0x8d, 0xa6, 0x68, 0x81, + 0x22, 0xad, 0xd1, 0xf4, 0x4d, 0x95, 0x9a, 0x4a, 0x75, 0x5f, 0xd4, 0xa2, + 0x48, 0xda, 0x46, 0xcd, 0xf4, 0xfb, 0xee, 0xcc, 0x88, 0xd4, 0x9a, 0xb2, + 0x2c, 0x3b, 0x0d, 0x62, 0x74, 0x0e, 0x30, 0xd8, 0xb9, 0x7f, 0xe7, 0xef, + 0x9e, 0x73, 0xee, 0x39, 0x77, 0x28, 0x7d, 0xa5, 0x43, 0xda, 0x25, 0x84, + 0x4e, 0x3c, 0x99, 0xc3, 0xcf, 0x3c, 0xfd, 0xe0, 0xc3, 0x0f, 0xee, 0xc1, + 0xeb, 0xb0, 0xa1, 0x6d, 0xd0, 0xa3, 0xfe, 0x18, 0x62, 0x88, 0x21, 0x86, + 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, + 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, + 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, + 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, + 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0xff, 0xef, 0x60, 0x88, 0x58, + 0xfc, 0xed, 0x0c, 0x1f, 0x49, 0xe8, 0x85, 0xcb, 0x07, 0x3d, 0x5b, 0x12, + 0x46, 0x61, 0x69, 0x66, 0xda, 0x16, 0x71, 0xeb, 0xbb, 0x33, 0x45, 0xf9, + 0x1f, 0xbf, 0x94, 0x32, 0x85, 0xfd, 0xdb, 0x0b, 0x37, 0x9f, 0x7d, 0xf3, + 0x91, 0xec, 0x8d, 0x05, 0x43, 0x12, 0x56, 0xe1, 0xe8, 0xb0, 0xb5, 0x4b, + 0x12, 0x7d, 0x58, 0xf3, 0xdd, 0xc1, 0xcf, 0x59, 0xd2, 0x15, 0xe1, 0xba, + 0xee, 0xbf, 0x39, 0x68, 0xc9, 0x2b, 0x8d, 0x94, 0x5c, 0x68, 0x6c, 0xdf, + 0x24, 0x5d, 0xd9, 0x52, 0x09, 0xfd, 0x6e, 0x8a, 0xe3, 0x96, 0x94, 0xab, + 0x2d, 0xe2, 0x2a, 0xba, 0x7d, 0x5a, 0x71, 0xfe, 0x3e, 0xcd, 0x9b, 0x7f, + 0x9e, 0xff, 0x1e, 0x24, 0xa5, 0xcb, 0x7d, 0x68, 0xf7, 0xa1, 0xcd, 0xf7, + 0x81, 0xf4, 0x94, 0x98, 0x72, 0xa4, 0x91, 0x90, 0xa3, 0xd5, 0x8c, 0xe8, + 0x05, 0x71, 0xbd, 0xbc, 0x9d, 0x2e, 0xa3, 0x6f, 0xea, 0x00, 0xdb, 0x29, + 0xe0, 0xf9, 0x0e, 0xd7, 0x59, 0x5e, 0x5e, 0x4a, 0xb7, 0xc6, 0x14, 0x0d, + 0x8e, 0xb1, 0x0f, 0xbf, 0x58, 0x5f, 0xae, 0x76, 0x00, 0x6f, 0xd6, 0x71, + 0x41, 0xdc, 0x73, 0x2c, 0xd0, 0xf6, 0xfd, 0xdf, 0x75, 0x32, 0xb2, 0xe2, + 0x74, 0x81, 0xa7, 0x16, 0x69, 0xb5, 0xc5, 0xd2, 0x0b, 0xb6, 0xb5, 0x22, + 0x6d, 0x1c, 0xeb, 0x34, 0x0a, 0xbe, 0x3f, 0x9d, 0x97, 0xae, 0xa0, 0x6f, + 0xb7, 0xe2, 0x63, 0x72, 0x42, 0xc3, 0xbc, 0x57, 0x49, 0x0f, 0x3a, 0xe2, + 0x3b, 0x7f, 0xf3, 0x52, 0xac, 0x6c, 0x97, 0xc9, 0x54, 0xf6, 0xa0, 0x1b, + 0xd0, 0x74, 0x3d, 0x67, 0x2b, 0x70, 0x6a, 0xe0, 0x4f, 0xdb, 0x81, 0xf5, + 0xee, 0x0a, 0x68, 0x1a, 0x85, 0xcd, 0x62, 0x6c, 0x66, 0x9f, 0xe8, 0x3b, + 0x87, 0x93, 0xe1, 0x78, 0x97, 0x36, 0x32, 0x6f, 0x88, 0x6e, 0xff, 0x81, + 0xe6, 0xd5, 0x7a, 0xe5, 0xd8, 0xbc, 0x8e, 0x77, 0x5d, 0xae, 0xe6, 0x4b, + 0x9a, 0xdb, 0xa8, 0x68, 0xde, 0xd9, 0x59, 0xad, 0x78, 0xd6, 0x94, 0xa3, + 0xb6, 0x7f, 0xe1, 0xb4, 0x73, 0x42, 0x1b, 0x39, 0x7b, 0x46, 0x1b, 0x3d, + 0xfb, 0x86, 0x36, 0xde, 0xd8, 0xb2, 0x49, 0xda, 0xb3, 0xd0, 0x1e, 0x71, + 0x90, 0xbf, 0x4f, 0x87, 0xba, 0xec, 0xa2, 0xde, 0x4a, 0xe4, 0x7d, 0x9f, + 0xf3, 0x86, 0xe6, 0x55, 0x6d, 0x8b, 0xfb, 0xe6, 0xa6, 0x22, 0x1a, 0xed, + 0x72, 0x74, 0xde, 0x94, 0x63, 0xd5, 0x94, 0x3c, 0x57, 0x2d, 0x29, 0x5a, + 0x86, 0x5d, 0xd2, 0xbc, 0x06, 0xc7, 0x2b, 0xa0, 0x75, 0x42, 0xdb, 0x07, + 0x9a, 0xde, 0x59, 0x29, 0x5d, 0x71, 0xe6, 0x40, 0xaf, 0x03, 0x78, 0xff, + 0x58, 0x1b, 0x6d, 0xf4, 0x6a, 0xde, 0xc9, 0x9b, 0xe2, 0x39, 0x59, 0xeb, + 0x4b, 0x62, 0xba, 0xb0, 0x01, 0xc8, 0x0c, 0xfd, 0x38, 0xd0, 0x49, 0xca, + 0xf7, 0xf5, 0x82, 0xff, 0x2c, 0x74, 0x6f, 0x5d, 0xa1, 0xfc, 0x8d, 0x5e, + 0x29, 0xcf, 0x53, 0xd7, 0xa6, 0x36, 0x52, 0xf5, 0x2f, 0x78, 0x8e, 0xf4, + 0x19, 0xe2, 0xfb, 0x47, 0x9d, 0x81, 0xf4, 0x21, 0x39, 0x03, 0xdc, 0x75, + 0xad, 0xd8, 0xa0, 0xae, 0xc1, 0xdf, 0x2d, 0x39, 0x02, 0xbd, 0x15, 0x9d, + 0x5e, 0x99, 0xb4, 0xb2, 0x2e, 0xf6, 0x68, 0x53, 0x20, 0x57, 0x32, 0xb4, + 0x17, 0xd2, 0xe7, 0xde, 0x67, 0xd3, 0x9e, 0xa1, 0xcb, 0x53, 0x2f, 0x3d, + 0xdf, 0xb3, 0x38, 0xb4, 0x91, 0x32, 0x43, 0xff, 0xf2, 0x45, 0xcf, 0xf6, + 0xb6, 0xb4, 0x48, 0x29, 0x6d, 0x48, 0x16, 0xfb, 0xb4, 0x43, 0x4e, 0x3b, + 0x22, 0x87, 0x2a, 0xd0, 0x8d, 0x6d, 0x5a, 0x8b, 0x62, 0x67, 0xca, 0x32, + 0x50, 0x32, 0x75, 0x74, 0x26, 0x49, 0x97, 0x3a, 0xd2, 0xe5, 0x7a, 0x9e, + 0x7a, 0xa2, 0x3d, 0x7f, 0x28, 0x5d, 0x69, 0xab, 0xba, 0x5a, 0xd5, 0xd3, + 0xf8, 0x2f, 0x5d, 0x4f, 0xd4, 0xc9, 0x72, 0x28, 0xb7, 0x03, 0xdc, 0x8f, + 0x40, 0x5f, 0xe2, 0xea, 0xc3, 0x0f, 0xb1, 0x6f, 0x93, 0x51, 0xb0, 0xd3, + 0x17, 0x61, 0x14, 0x7a, 0x61, 0x37, 0x64, 0x19, 0xa6, 0xee, 0xe0, 0xc3, + 0x1f, 0x49, 0x5e, 0xf9, 0xd5, 0x90, 0x97, 0xfc, 0xdb, 0x32, 0x55, 0x49, + 0x80, 0x06, 0x65, 0xd4, 0xe5, 0xbd, 0x7c, 0x64, 0x1b, 0x7b, 0x20, 0x5f, + 0x5e, 0xa6, 0xbe, 0x45, 0x7f, 0xa2, 0xfd, 0xf3, 0x9d, 0xb2, 0xfe, 0xcc, + 0xbf, 0xee, 0x7c, 0x92, 0xf6, 0x96, 0x7c, 0x27, 0xe4, 0x78, 0x35, 0xc9, + 0x3d, 0xd4, 0x56, 0x54, 0x6c, 0x8a, 0x64, 0x14, 0xdd, 0x28, 0x74, 0x48, + 0x51, 0xed, 0xf7, 0x5e, 0xd0, 0x43, 0x2c, 0xa8, 0xf2, 0xbd, 0xa0, 0x64, + 0x9b, 0xb6, 0xed, 0xcc, 0x11, 0xc9, 0xc2, 0xbe, 0x45, 0x8e, 0xcc, 0x99, + 0x32, 0x6d, 0xff, 0x63, 0xa7, 0xb4, 0x2f, 0xdf, 0x6f, 0xa8, 0xb8, 0xae, + 0xf7, 0x6e, 0x90, 0x4d, 0xe0, 0x77, 0xf9, 0x7e, 0x5d, 0xe4, 0xa6, 0x59, + 0xc8, 0x5a, 0x23, 0x08, 0xf6, 0x46, 0x81, 0xb1, 0x4c, 0x43, 0x2c, 0x93, + 0x44, 0x8b, 0x4d, 0x7d, 0xf9, 0xfe, 0xf8, 0xf0, 0xdd, 0xf5, 0x75, 0x64, + 0x9e, 0xb4, 0xa9, 0x2f, 0xc6, 0xa8, 0x12, 0xf4, 0xc1, 0xf8, 0x74, 0xbb, + 0xae, 0x8a, 0xa1, 0xae, 0x46, 0xfe, 0xef, 0xed, 0xc2, 0xf5, 0xaa, 0xa2, + 0x79, 0xce, 0xbb, 0xa1, 0x2f, 0xd8, 0x32, 0x02, 0x7f, 0x37, 0xec, 0x4f, + 0xcb, 0x91, 0x54, 0x76, 0xc2, 0x95, 0xc0, 0xe6, 0xaf, 0xad, 0xb1, 0xf9, + 0xd1, 0xbb, 0xc8, 0x75, 0x3c, 0x94, 0xcb, 0x0d, 0xe5, 0x1a, 0x85, 0x5c, + 0x63, 0x90, 0x6b, 0xe5, 0x23, 0xc8, 0xb5, 0xf2, 0x91, 0xe5, 0xd2, 0xa4, + 0xec, 0x3c, 0x08, 0x5a, 0xa6, 0xfc, 0xab, 0x13, 0xd8, 0xf2, 0xbf, 0x38, + 0x9f, 0x14, 0x19, 0x7c, 0x7f, 0x70, 0xd8, 0x16, 0xef, 0x5b, 0xe0, 0xd5, + 0x71, 0x40, 0x8b, 0xef, 0xef, 0x97, 0xe1, 0x6e, 0xfe, 0x38, 0x8b, 0x7d, + 0x5d, 0xcf, 0x1f, 0x29, 0x87, 0x3e, 0x7c, 0xef, 0xfe, 0xa8, 0x6b, 0x1f, + 0x55, 0x0e, 0xc6, 0x9c, 0x4f, 0x35, 0x9d, 0xab, 0x1f, 0x56, 0x86, 0xf5, + 0x63, 0xca, 0x2f, 0x4f, 0x86, 0xc7, 0x64, 0x72, 0x33, 0xed, 0xa9, 0xa4, + 0x8d, 0x0c, 0x92, 0xef, 0xb5, 0xfc, 0x4a, 0x26, 0xe0, 0x0d, 0x39, 0xd1, + 0xd2, 0x46, 0x39, 0xb2, 0x60, 0x49, 0x69, 0xe9, 0x4e, 0x71, 0x57, 0x03, + 0x6f, 0xb4, 0x47, 0xf6, 0x7d, 0xd2, 0x7c, 0x2a, 0xc8, 0x2b, 0x2e, 0x54, + 0x91, 0x83, 0x56, 0x13, 0x72, 0xd9, 0x48, 0xcb, 0x9b, 0x83, 0x87, 0xe5, + 0xf3, 0xd5, 0x24, 0xe8, 0x31, 0x9f, 0x2c, 0xe7, 0x10, 0x17, 0xb5, 0xb2, + 0x63, 0x08, 0x79, 0xaf, 0xd9, 0x9c, 0x13, 0xc4, 0x96, 0x72, 0x10, 0x83, + 0x5d, 0x6f, 0x50, 0xe5, 0x14, 0x90, 0x4f, 0x64, 0x0c, 0xb1, 0xb7, 0x66, + 0xb3, 0xcd, 0xfe, 0xa0, 0xef, 0xb3, 0x95, 0x5e, 0xad, 0xc8, 0xbc, 0x64, + 0xf0, 0xa6, 0x4c, 0x3b, 0x41, 0xdf, 0xe7, 0x2a, 0xa3, 0x9b, 0x98, 0x1f, + 0x1a, 0x05, 0xc9, 0x94, 0x9d, 0xf7, 0x7c, 0xd7, 0xba, 0x7d, 0xcd, 0xfa, + 0x78, 0xb2, 0x13, 0x81, 0xce, 0x45, 0xfb, 0xaa, 0xad, 0xf7, 0xb6, 0x4a, + 0x09, 0x27, 0x5d, 0xd6, 0x1a, 0x47, 0xe7, 0xbe, 0x4a, 0x79, 0x5b, 0xab, + 0xdc, 0x34, 0x80, 0x3f, 0x6d, 0x68, 0x62, 0x1e, 0xaa, 0x94, 0xbb, 0xd9, + 0xa6, 0xbe, 0x74, 0x4d, 0x12, 0xa3, 0x15, 0x5f, 0xae, 0x3a, 0x41, 0xee, + 0x63, 0x68, 0x7a, 0x6f, 0x5b, 0xb8, 0x56, 0xd7, 0x76, 0x39, 0x97, 0x44, + 0x3a, 0x0e, 0x55, 0xc4, 0x2a, 0x56, 0x76, 0x39, 0x6f, 0x4b, 0xb9, 0xa7, + 0x6d, 0x75, 0x5d, 0x8a, 0xeb, 0x76, 0x0e, 0xaf, 0x9d, 0xbb, 0xcb, 0xb9, + 0x28, 0xe5, 0x2d, 0x6d, 0xab, 0xb4, 0xd2, 0x58, 0xdb, 0x17, 0xac, 0xe5, + 0xf8, 0x66, 0x71, 0xbb, 0x39, 0x47, 0xef, 0x6d, 0xbf, 0x45, 0x43, 0x32, + 0xc5, 0x4a, 0xb9, 0xa7, 0x7d, 0x15, 0xaf, 0x4d, 0xbc, 0xde, 0x1a, 0xbc, + 0xc4, 0xd9, 0xbe, 0x8a, 0x33, 0x07, 0x9c, 0x43, 0xab, 0x38, 0x39, 0x7e, + 0x58, 0x8a, 0x38, 0xd3, 0x5a, 0x0a, 0x32, 0xbc, 0x54, 0xc9, 0x48, 0x79, + 0x28, 0x01, 0xdd, 0xf7, 0x1f, 0xfc, 0x9a, 0xaa, 0x43, 0xcc, 0x61, 0x0f, + 0xba, 0x32, 0x55, 0x5e, 0x87, 0xd8, 0x08, 0xdb, 0xf8, 0x5a, 0x5d, 0x86, + 0x17, 0xeb, 0xa6, 0x1c, 0x6f, 0x70, 0xbf, 0x98, 0xe3, 0x05, 0x75, 0xc6, + 0x85, 0x46, 0x4e, 0xdb, 0x87, 0xbd, 0x66, 0x9d, 0xb0, 0xaf, 0x61, 0x6a, + 0xa3, 0x3c, 0x1f, 0x80, 0x97, 0x76, 0x7e, 0xac, 0x41, 0xdb, 0x79, 0x03, + 0xb6, 0x41, 0xce, 0xa3, 0x9c, 0xbd, 0x95, 0xb9, 0x53, 0x66, 0xd1, 0x51, + 0x75, 0x88, 0x56, 0xcb, 0x77, 0x20, 0x07, 0x4d, 0xa0, 0xd6, 0x80, 0xcd, + 0xdb, 0x78, 0x6f, 0x70, 0xde, 0x32, 0xe6, 0x6d, 0xe0, 0x3c, 0xec, 0xcd, + 0x25, 0xe5, 0x0f, 0xa6, 0xcd, 0xf1, 0x77, 0xb1, 0xc7, 0x68, 0xd7, 0x59, + 0x57, 0x58, 0x02, 0x5f, 0xc1, 0x3e, 0xa2, 0x6e, 0x48, 0xed, 0x60, 0x7e, + 0x8f, 0xb9, 0x19, 0xcc, 0xcd, 0x66, 0x18, 0xcf, 0x3d, 0xfb, 0x99, 0x0e, + 0xe9, 0x42, 0xbb, 0xce, 0x35, 0xd9, 0x0c, 0x72, 0x5b, 0xdf, 0xcb, 0xb7, + 0xc9, 0x4a, 0xca, 0xbf, 0x60, 0xd8, 0xd1, 0xdc, 0x08, 0x6f, 0xf3, 0x5c, + 0xe6, 0xc5, 0xc4, 0xbd, 0x21, 0xcc, 0x83, 0xc7, 0xc5, 0x6d, 0xfc, 0x49, + 0xb7, 0x74, 0xb9, 0xf8, 0x8d, 0xe6, 0x4c, 0x6f, 0x0e, 0x6a, 0x2e, 0xbe, + 0xb7, 0x50, 0x3e, 0x17, 0xe7, 0xa1, 0x56, 0xac, 0x66, 0x26, 0x59, 0x1f, + 0x15, 0xeb, 0x6c, 0xef, 0x85, 0x3f, 0x04, 0x75, 0xd7, 0x85, 0x5b, 0xbe, + 0x70, 0x19, 0x7a, 0x4b, 0x43, 0x6f, 0x29, 0x39, 0xdf, 0x60, 0x9d, 0xe6, + 0x42, 0x5f, 0x19, 0xf1, 0x1a, 0xe3, 0x58, 0x2b, 0x87, 0x81, 0x03, 0x3a, + 0x17, 0x47, 0x2f, 0x64, 0x65, 0xca, 0xda, 0x1d, 0xf1, 0x00, 0x5c, 0x88, + 0x1f, 0x85, 0x36, 0xf4, 0xf1, 0x1d, 0x9a, 0x53, 0xff, 0x86, 0x7f, 0x94, + 0xed, 0x09, 0xbd, 0x30, 0xd6, 0xd4, 0xbf, 0x6e, 0xfc, 0xa1, 0x1c, 0x68, + 0x33, 0x06, 0x31, 0xfe, 0xe8, 0xa8, 0xf3, 0x18, 0x8b, 0x48, 0xd7, 0x92, + 0x23, 0x4b, 0x23, 0xdc, 0x37, 0x8b, 0xf1, 0xa7, 0x5c, 0xe7, 0x9e, 0x29, + 0x5c, 0xc0, 0x19, 0xad, 0xf1, 0xfd, 0x11, 0x87, 0x6b, 0x7c, 0x99, 0x70, + 0x3a, 0xc4, 0x48, 0x96, 0xb4, 0xc7, 0x07, 0x11, 0x7b, 0x1e, 0xe0, 0x3e, + 0x32, 0x06, 0x6d, 0x17, 0xb0, 0xea, 0xb4, 0x3c, 0x3c, 0xc8, 0x75, 0xa0, + 0xdd, 0x2a, 0x7a, 0x92, 0x34, 0xf3, 0x21, 0x4f, 0x43, 0xdd, 0x81, 0xbe, + 0x06, 0xac, 0x40, 0x7f, 0x9f, 0xe9, 0x5e, 0xd5, 0x1f, 0xd7, 0x35, 0xf3, + 0xcb, 0x18, 0x96, 0x90, 0x81, 0x33, 0x1b, 0x65, 0xe7, 0xa2, 0x25, 0xf6, + 0x99, 0x55, 0xfe, 0x76, 0x9e, 0x5b, 0xcb, 0x5f, 0xf4, 0x7f, 0x15, 0x5c, + 0xd0, 0xc5, 0x8e, 0xfa, 0x1e, 0x4b, 0x05, 0xb8, 0xa3, 0xf6, 0x7b, 0xe1, + 0x5e, 0xf1, 0xfd, 0x99, 0x70, 0x4f, 0xb0, 0x07, 0x88, 0x95, 0xe7, 0x6f, + 0xc5, 0xa9, 0x0c, 0xf6, 0x06, 0xb6, 0xa7, 0xe2, 0x11, 0xe3, 0x18, 0xed, + 0xbb, 0x63, 0xd2, 0x2c, 0xb0, 0x8e, 0xe6, 0x3e, 0xc9, 0x44, 0xb9, 0x22, + 0xa5, 0xad, 0x85, 0x67, 0x7d, 0xd8, 0xcf, 0xa4, 0xa5, 0x6c, 0xaf, 0x63, + 0xaf, 0x97, 0x37, 0xa0, 0x1b, 0x8c, 0xc1, 0x26, 0xf5, 0x42, 0x42, 0x8a, + 0x8d, 0x44, 0xc2, 0x3c, 0x31, 0xf0, 0x23, 0xcf, 0x48, 0x24, 0xf4, 0x13, + 0x81, 0x9d, 0x4d, 0xd6, 0x6f, 0x20, 0x56, 0x6a, 0x72, 0x74, 0xe8, 0x86, + 0xcf, 0x1a, 0xd8, 0xdb, 0x0b, 0x9b, 0x1b, 0x82, 0xcf, 0x80, 0x8f, 0x72, + 0xa3, 0xa3, 0x37, 0xe0, 0xed, 0x2b, 0x11, 0x8f, 0xa6, 0x8e, 0xdc, 0xd3, + 0xcb, 0xfb, 0xbe, 0x51, 0xd8, 0x90, 0x98, 0xce, 0x8f, 0x6f, 0xd1, 0xcf, + 0xed, 0xdf, 0x62, 0x9c, 0x2b, 0x6d, 0x01, 0x3e, 0xdd, 0xcb, 0xe3, 0xf7, + 0x9c, 0xc8, 0x44, 0x15, 0x3a, 0xdf, 0x03, 0x3d, 0x59, 0xf0, 0xc5, 0x3d, + 0xa6, 0xca, 0xd1, 0xf5, 0x3d, 0x2f, 0x6e, 0x0a, 0x70, 0xf0, 0xfd, 0x27, + 0x7e, 0x70, 0x86, 0x5e, 0x0e, 0xfb, 0x7e, 0x3f, 0xdc, 0x87, 0x5f, 0x45, + 0xb9, 0x78, 0x5e, 0x44, 0xb2, 0xad, 0x3d, 0x37, 0xb2, 0xe3, 0x25, 0x9c, + 0x33, 0xa7, 0x1d, 0xdf, 0x7f, 0x07, 0xcf, 0x35, 0xa7, 0xd9, 0x46, 0xde, + 0x7f, 0xf6, 0x31, 0x07, 0xf8, 0x2c, 0xce, 0xbd, 0xd1, 0xa6, 0xb3, 0xff, + 0x5e, 0xcf, 0xbd, 0x7b, 0x3f, 0xfb, 0xc9, 0xf3, 0x1d, 0x7d, 0xef, 0x03, + 0xce, 0xfe, 0x0f, 0x5c, 0x77, 0x0f, 0x3e, 0x1b, 0xd8, 0x6d, 0xb1, 0xd1, + 0x1c, 0x5f, 0xee, 0xd5, 0x7f, 0x7f, 0xad, 0xfb, 0x76, 0xff, 0xb5, 0xbb, + 0x6f, 0xf7, 0xdf, 0xcd, 0xdd, 0xbf, 0x18, 0xff, 0xcd, 0x01, 0x0f, 0x7d, + 0x70, 0xad, 0xff, 0xae, 0xe7, 0x93, 0xd4, 0xf7, 0xf3, 0x3d, 0xe5, 0xa1, + 0xce, 0x30, 0x1f, 0x52, 0xe7, 0xf5, 0x17, 0xa7, 0x6d, 0xef, 0x7e, 0x53, + 0x4a, 0xb9, 0x16, 0xc9, 0xe6, 0x6a, 0xb2, 0x43, 0x8e, 0x3b, 0x22, 0x4b, + 0xaa, 0x16, 0x31, 0x51, 0x8b, 0x0f, 0xa0, 0x3e, 0x0b, 0xf4, 0xba, 0xa4, + 0xf4, 0xf2, 0x02, 0x78, 0x89, 0xf0, 0x74, 0xdd, 0x05, 0x0f, 0x71, 0x10, + 0x17, 0xf1, 0x0c, 0xe2, 0x7c, 0xb7, 0xd7, 0xc1, 0x85, 0x73, 0xea, 0x25, + 0xd4, 0x64, 0xb6, 0xde, 0xa3, 0x07, 0x67, 0xb2, 0x5b, 0x96, 0xdd, 0xe9, + 0xeb, 0xf2, 0x05, 0x9e, 0x59, 0x0a, 0xae, 0xce, 0x21, 0x56, 0x0f, 0x8d, + 0x85, 0x75, 0xd2, 0xdc, 0x41, 0xcf, 0x8e, 0xee, 0x49, 0x78, 0x47, 0x92, + 0x90, 0x92, 0x9a, 0xb5, 0x04, 0x1d, 0x68, 0x72, 0x0d, 0x67, 0xd0, 0xd5, + 0xb9, 0x76, 0xe0, 0x45, 0xee, 0x77, 0x20, 0xbb, 0x57, 0xb4, 0x7e, 0xab, + 0x55, 0x6b, 0x87, 0x2f, 0x65, 0xc4, 0x55, 0x6d, 0x9e, 0xd3, 0xa7, 0x66, + 0x16, 0x2b, 0xc8, 0x03, 0x6d, 0x9c, 0xaf, 0x79, 0xbc, 0xd7, 0x49, 0x43, + 0x93, 0x2b, 0x73, 0xba, 0xfc, 0xd3, 0x9c, 0x21, 0xff, 0x8c, 0x3a, 0xf4, + 0x9a, 0x7d, 0x6a, 0xe6, 0xb4, 0x2d, 0xf7, 0x81, 0xd5, 0xf0, 0x0e, 0x4f, + 0x76, 0x9a, 0x42, 0x5b, 0x1d, 0x48, 0xff, 0x8e, 0x20, 0xff, 0xc1, 0x9a, + 0x2b, 0x73, 0xa4, 0xb5, 0x76, 0x8d, 0xf4, 0x22, 0x1f, 0x83, 0x5d, 0x0f, + 0x30, 0x27, 0xe2, 0x7c, 0xd4, 0xab, 0x03, 0xd6, 0x3e, 0xc5, 0x5b, 0x42, + 0x16, 0xeb, 0x9c, 0x6f, 0x82, 0xb7, 0x2e, 0x9c, 0x31, 0x59, 0x6b, 0x52, + 0xfe, 0xb0, 0x5b, 0xe5, 0xaa, 0x1a, 0xfb, 0x0d, 0xb5, 0xc7, 0xef, 0xef, + 0xe7, 0xde, 0x1b, 0x32, 0x95, 0x62, 0x9b, 0x63, 0x59, 0xd4, 0x9c, 0xc4, + 0x97, 0xdd, 0xeb, 0x0a, 0x79, 0x0e, 0xde, 0xaf, 0x08, 0x65, 0xdb, 0x6d, + 0x5d, 0x97, 0xd7, 0x7d, 0xf7, 0x00, 0xe5, 0x89, 0x72, 0x8b, 0x39, 0x9f, + 0xb1, 0xd8, 0x28, 0xcc, 0xc0, 0x8e, 0xbf, 0x2a, 0xdf, 0x6f, 0x1c, 0x92, + 0xef, 0x35, 0x26, 0xe5, 0xcf, 0x1a, 0x5f, 0x96, 0x3f, 0x6d, 0x1c, 0x94, + 0xd7, 0x1b, 0x07, 0xe4, 0xb5, 0xc6, 0x84, 0xbc, 0xda, 0xd8, 0x0f, 0x1b, + 0x1f, 0x87, 0x8d, 0x9f, 0x9a, 0x99, 0xac, 0xf7, 0xcb, 0xd4, 0x49, 0xc4, + 0x20, 0xe7, 0x1b, 0xba, 0xba, 0xe3, 0xb3, 0xe9, 0xe7, 0x2d, 0x32, 0xad, + 0xee, 0xaf, 0x34, 0xe4, 0x89, 0x2d, 0xbc, 0x2b, 0x7c, 0xc5, 0x33, 0x2e, + 0x87, 0xf1, 0xe8, 0xe1, 0x94, 0xb4, 0x03, 0xbf, 0xca, 0x4b, 0x4d, 0x9e, + 0xdb, 0x62, 0x86, 0xf7, 0x9c, 0x87, 0x24, 0xc9, 0xfb, 0xb0, 0x9c, 0x67, + 0xa0, 0xde, 0x5e, 0xd7, 0x27, 0x73, 0xb4, 0x65, 0xe8, 0xc6, 0x95, 0x43, + 0xb0, 0x53, 0xc3, 0x7e, 0xcb, 0xa5, 0x1e, 0x16, 0x97, 0x28, 0xf7, 0x46, + 0x59, 0x5c, 0xa0, 0x6f, 0xff, 0x1b, 0x64, 0x6c, 0x97, 0xda, 0x82, 0x89, + 0xb9, 0x6e, 0x98, 0xab, 0x6c, 0xa7, 0x3d, 0x00, 0x1f, 0xf1, 0x7e, 0x10, + 0x4e, 0xab, 0x09, 0x27, 0xf1, 0x24, 0x54, 0x0c, 0x08, 0x70, 0x5b, 0x52, + 0x5b, 0x4a, 0xca, 0xc2, 0x42, 0x0f, 0x9e, 0x94, 0x2c, 0xd4, 0x6d, 0x3c, + 0x39, 0x3c, 0x43, 0x78, 0xd2, 0xb0, 0x53, 0xca, 0xc8, 0xd8, 0x12, 0xc9, + 0x88, 0x78, 0x5c, 0xed, 0x0d, 0x6b, 0x2a, 0xf2, 0xa3, 0x85, 0xfc, 0x74, + 0x87, 0x7d, 0x1d, 0x52, 0xab, 0x38, 0x32, 0x55, 0xfd, 0x94, 0x3e, 0xa5, + 0x74, 0x07, 0xfc, 0x95, 0x21, 0xb4, 0xef, 0x0f, 0xdb, 0x8f, 0xca, 0xf4, + 0xbc, 0xc8, 0xca, 0xcb, 0x03, 0x7a, 0x51, 0xb5, 0xf7, 0xa2, 0xad, 0xa3, + 0x9d, 0x0d, 0xdb, 0xcc, 0x8f, 0x0e, 0xe0, 0x71, 0xd5, 0xf3, 0xf5, 0xea, + 0xb8, 0x3c, 0x55, 0xed, 0x77, 0x5e, 0x87, 0xcd, 0xbd, 0x65, 0x46, 0xf7, + 0xd2, 0x04, 0x24, 0x79, 0xf6, 0x56, 0x75, 0xf7, 0xf1, 0x04, 0xe2, 0xad, + 0x9b, 0x34, 0xe5, 0x6f, 0x4f, 0x64, 0xad, 0xa7, 0xf5, 0x5c, 0x52, 0xda, + 0x7d, 0xff, 0x71, 0x3b, 0x3b, 0x3b, 0xa9, 0x77, 0xca, 0xdf, 0xbf, 0x98, + 0x91, 0x85, 0xb3, 0x5b, 0x65, 0xa1, 0x06, 0x99, 0x1a, 0xbf, 0x8e, 0x7d, + 0x35, 0xe5, 0xea, 0x9e, 0x47, 0xb1, 0x27, 0x8c, 0x5d, 0x49, 0xe4, 0x6c, + 0x1b, 0xc4, 0xec, 0x25, 0x5d, 0x49, 0x98, 0x85, 0x9c, 0x1c, 0x81, 0xdf, + 0x4f, 0xdb, 0xb9, 0x1e, 0x69, 0xc7, 0x7b, 0x7d, 0x04, 0x7c, 0x5b, 0x32, + 0xd5, 0x6b, 0xc9, 0x99, 0xc1, 0x68, 0xff, 0xb6, 0x62, 0x6e, 0x46, 0x16, + 0xcf, 0x66, 0xf0, 0x9b, 0x83, 0xfd, 0xec, 0x94, 0x57, 0x6a, 0xfd, 0xb2, + 0x54, 0xdb, 0x2a, 0x8b, 0xb5, 0xe6, 0x7d, 0xe8, 0xec, 0x09, 0xe2, 0x1d, + 0xf1, 0xf4, 0x5b, 0x53, 0xfa, 0x56, 0x71, 0xcd, 0x7e, 0xeb, 0x29, 0xfd, + 0x1f, 0xe4, 0x31, 0x33, 0xa0, 0xa9, 0x17, 0x7e, 0xa4, 0xee, 0x84, 0x26, + 0x79, 0xf6, 0x2a, 0xbc, 0x4f, 0x26, 0x49, 0xfb, 0xf5, 0xc6, 0x07, 0xd1, + 0x59, 0xcb, 0xcf, 0x9d, 0x68, 0x52, 0x06, 0xe2, 0xec, 0xbf, 0x71, 0x52, + 0xef, 0x95, 0xe5, 0x6d, 0x0f, 0x58, 0x4f, 0xea, 0xad, 0x88, 0x01, 0x3f, + 0x97, 0x9f, 0xee, 0xd9, 0x24, 0x3f, 0xfc, 0xcd, 0xec, 0xa9, 0x6f, 0x22, + 0xd9, 0xbf, 0xb2, 0xa7, 0x83, 0x71, 0x01, 0xef, 0xec, 0xcf, 0xde, 0x70, + 0x75, 0xea, 0xe1, 0x2f, 0xa0, 0x87, 0xec, 0x9c, 0xba, 0x9b, 0x56, 0x3c, + 0x90, 0x3e, 0xf5, 0x52, 0x06, 0x6f, 0x18, 0xab, 0xf7, 0x03, 0x57, 0x59, + 0xe9, 0xf9, 0x09, 0x27, 0x7b, 0x03, 0xe9, 0xb0, 0xbf, 0x68, 0xf7, 0xa7, + 0x77, 0xea, 0x3b, 0x64, 0x32, 0xfd, 0x80, 0xf5, 0xb4, 0x6c, 0x21, 0xce, + 0xd9, 0x05, 0xc1, 0xda, 0x79, 0xe2, 0xfb, 0x2b, 0xe0, 0x0b, 0x70, 0x28, + 0xff, 0x51, 0x38, 0x77, 0x59, 0x5f, 0xd7, 0x79, 0xc6, 0x63, 0x0c, 0x71, + 0xe1, 0xe2, 0x10, 0x65, 0x40, 0x82, 0x95, 0xca, 0xa6, 0x5d, 0xfd, 0xc3, + 0xc8, 0x47, 0xfc, 0xfd, 0x56, 0x51, 0x27, 0x0f, 0xe7, 0xc0, 0xcb, 0x4f, + 0xc0, 0x7f, 0x3f, 0x70, 0xa2, 0xf6, 0x48, 0x47, 0x74, 0xff, 0x4e, 0xd1, + 0x7d, 0xad, 0x21, 0xe6, 0x2a, 0x5d, 0xf4, 0xd5, 0x75, 0xc8, 0xdd, 0x07, + 0x7b, 0xb5, 0xf0, 0xcb, 0xbd, 0xe9, 0x0c, 0xf7, 0x98, 0xeb, 0x22, 0xba, + 0x11, 0xbf, 0x5c, 0x73, 0x27, 0x1e, 0xee, 0x75, 0x3e, 0xea, 0xd4, 0x03, + 0x09, 0x79, 0xf7, 0x44, 0xb4, 0x37, 0x07, 0x64, 0xba, 0x0a, 0xdd, 0xed, + 0xea, 0x0f, 0xfc, 0x27, 0x1d, 0xf1, 0x40, 0xde, 0xff, 0x06, 0xbc, 0x07, + 0xb8, 0x5b, 0x0b, 0xcd, 0xba, 0xc3, 0x58, 0x3d, 0xa0, 0x31, 0xb6, 0x0e, + 0x4f, 0x57, 0xf6, 0x44, 0xbe, 0x98, 0x84, 0x5f, 0xed, 0xb6, 0x9e, 0x10, + 0xd6, 0x63, 0xc4, 0x9b, 0x94, 0x1f, 0xbe, 0x0c, 0x1e, 0x92, 0xf4, 0x93, + 0x7f, 0x5f, 0xe3, 0x27, 0x1c, 0xdb, 0x2a, 0x35, 0xd4, 0xd4, 0x5e, 0xde, + 0x94, 0x69, 0x25, 0x03, 0xda, 0x35, 0xfa, 0x77, 0x29, 0xf4, 0xef, 0x47, + 0x80, 0xa3, 0x5d, 0x8c, 0x47, 0x1f, 0xc7, 0x59, 0x9d, 0xcd, 0x2c, 0xeb, + 0xcc, 0x03, 0x76, 0x4b, 0x51, 0xdd, 0x4f, 0xdf, 0x8b, 0xee, 0xa2, 0xd8, + 0x94, 0x96, 0x8b, 0x95, 0x28, 0x2e, 0xa5, 0x71, 0x9e, 0xb4, 0xcb, 0xa5, + 0xb9, 0x28, 0xe6, 0xb5, 0xcb, 0x12, 0xf2, 0x9a, 0x95, 0x97, 0x2c, 0x8c, + 0x25, 0xe5, 0xe2, 0x5c, 0x12, 0x31, 0xab, 0x47, 0x56, 0xe6, 0x7a, 0x30, + 0x96, 0xc2, 0xba, 0x14, 0xe6, 0xdb, 0xb2, 0x52, 0xb1, 0x81, 0x27, 0x87, + 0x76, 0x0e, 0xed, 0x21, 0xb9, 0xa4, 0xbe, 0x17, 0x30, 0x2f, 0x18, 0x42, + 0xdc, 0x62, 0x5e, 0x30, 0x82, 0x18, 0x32, 0x81, 0x27, 0x8a, 0x5d, 0xa7, + 0x66, 0xa6, 0x2a, 0xbc, 0x73, 0x84, 0x0e, 0xac, 0x53, 0x33, 0xd3, 0xb6, + 0x89, 0xba, 0xed, 0x1b, 0xda, 0x54, 0x83, 0x72, 0x41, 0xb7, 0x43, 0x1d, + 0xa2, 0x3f, 0x4a, 0x9b, 0xe4, 0x79, 0x67, 0x20, 0xc6, 0x77, 0x01, 0x9f, + 0x23, 0xfa, 0x6f, 0xd0, 0x17, 0xa0, 0xc3, 0x27, 0xba, 0xe4, 0xd2, 0xcb, + 0x8c, 0x35, 0xae, 0xbc, 0x7a, 0x96, 0x3a, 0x2c, 0xf6, 0xac, 0xea, 0x90, + 0x63, 0x0f, 0xe1, 0x8c, 0xd8, 0x0f, 0x7b, 0x32, 0x33, 0x87, 0x90, 0xcb, + 0x7c, 0x1b, 0xf6, 0x59, 0x66, 0xcd, 0x9d, 0x0e, 0x6a, 0x84, 0x20, 0x06, + 0xa0, 0xdd, 0x47, 0x5d, 0xb1, 0xdd, 0x07, 0xbb, 0xe3, 0x58, 0x9f, 0x1a, + 0x5b, 0x04, 0x8e, 0x60, 0x8c, 0xed, 0xcd, 0xb2, 0xa8, 0xc6, 0x0e, 0xaa, + 0xb1, 0xb2, 0xb2, 0x0f, 0x8e, 0x1d, 0x52, 0xb1, 0xe9, 0x7c, 0x23, 0xea, + 0xdf, 0x88, 0x58, 0xc2, 0x7e, 0xf6, 0xe5, 0x61, 0xeb, 0x7b, 0x71, 0xae, + 0x15, 0x64, 0xa9, 0x81, 0x3a, 0x30, 0xff, 0x7b, 0x98, 0xcb, 0x3d, 0xc8, + 0x9e, 0x2a, 0xe9, 0xe4, 0xf1, 0x20, 0xce, 0x83, 0xfd, 0x21, 0xad, 0xb6, + 0x90, 0xaf, 0x03, 0x61, 0xbb, 0x25, 0xa4, 0x4d, 0x3c, 0x36, 0x70, 0x1c, + 0xc3, 0x5a, 0x17, 0x38, 0x18, 0x63, 0x11, 0x23, 0x52, 0x29, 0xe8, 0x82, + 0x34, 0xdb, 0xa4, 0xac, 0xde, 0xf7, 0xc3, 0x76, 0xb9, 0x16, 0x3a, 0xb4, + 0xa2, 0x75, 0xa5, 0x70, 0xcf, 0x53, 0xea, 0x9c, 0xd1, 0x93, 0x9b, 0xc3, + 0x9c, 0x10, 0x7a, 0x45, 0x9c, 0xd5, 0x93, 0x8c, 0x37, 0xef, 0x84, 0x76, + 0xda, 0x8b, 0xbe, 0x87, 0x44, 0xef, 0x65, 0xdf, 0x51, 0xe0, 0x61, 0xed, + 0x3c, 0x0c, 0x99, 0xd9, 0xe6, 0xfa, 0x6c, 0xd3, 0xfa, 0xc4, 0x3a, 0xeb, + 0x3b, 0x9a, 0xfa, 0x32, 0x52, 0x9b, 0xef, 0x52, 0xf1, 0xf2, 0x7c, 0x18, + 0x2f, 0x17, 0x6b, 0x94, 0x05, 0x7e, 0x96, 0x7f, 0x5b, 0xe9, 0xa2, 0x76, + 0x36, 0xb0, 0xf5, 0xa5, 0x93, 0x3c, 0x17, 0x57, 0xe7, 0xd5, 0xd4, 0xbc, + 0xdf, 0x06, 0xff, 0xba, 0x1c, 0x55, 0x32, 0x70, 0x3e, 0xe6, 0xd5, 0x02, + 0xbf, 0x31, 0x6c, 0xce, 0xa1, 0x8f, 0x44, 0x6b, 0x38, 0xff, 0xe7, 0xa8, + 0x55, 0xbe, 0xac, 0xd6, 0xac, 0xfa, 0x0c, 0xf9, 0x71, 0x42, 0x9e, 0x7b, + 0xc0, 0x5f, 0x67, 0x28, 0x43, 0x7b, 0x28, 0x03, 0xf1, 0xfd, 0x27, 0x70, + 0xb7, 0x61, 0x1e, 0x79, 0xdd, 0x86, 0x3e, 0xbe, 0xff, 0x17, 0xfa, 0x76, + 0x23, 0xff, 0x23, 0x6f, 0x89, 0x26, 0xde, 0xfe, 0x03, 0x63, 0x3d, 0x4a, + 0xb7, 0x35, 0xd4, 0x26, 0x53, 0xbc, 0xef, 0x48, 0xe1, 0x1c, 0x38, 0xb9, + 0x4d, 0xd1, 0xad, 0x9d, 0xbd, 0x86, 0xf1, 0x5e, 0xac, 0x89, 0xda, 0xcd, + 0xb2, 0xe9, 0x58, 0xfb, 0x53, 0x25, 0xcf, 0x62, 0xed, 0x4e, 0xf2, 0x6f, + 0x5b, 0x23, 0x3b, 0xe5, 0x26, 0x4f, 0xe4, 0xa7, 0x1f, 0x4f, 0x2b, 0x72, + 0x21, 0xd8, 0x6d, 0xd2, 0x90, 0xd1, 0x7c, 0x9a, 0xdf, 0xf9, 0x12, 0xbc, + 0x17, 0x1d, 0x19, 0xe4, 0x9e, 0xa1, 0xdd, 0x60, 0x4e, 0x47, 0x7f, 0x4b, + 0xc8, 0x31, 0xd4, 0x24, 0xe5, 0x85, 0x8c, 0x56, 0x3c, 0x99, 0x45, 0x16, + 0xad, 0xbe, 0xd5, 0xc9, 0x8b, 0x4b, 0xb6, 0x7c, 0x1b, 0x7e, 0x7a, 0xb2, + 0x9e, 0x4d, 0x7f, 0x13, 0xf9, 0xc1, 0x91, 0x25, 0xe6, 0x13, 0x3d, 0x29, + 0x65, 0x9b, 0xf3, 0x9a, 0x6c, 0x60, 0x4c, 0x9b, 0x47, 0x7e, 0x6a, 0xdd, + 0x2d, 0x47, 0x82, 0x9f, 0x57, 0xd7, 0xc6, 0x0c, 0xca, 0xb1, 0x36, 0x66, + 0x10, 0x0f, 0x63, 0xc6, 0x4e, 0xec, 0x13, 0x63, 0x06, 0xf6, 0xff, 0x24, + 0x63, 0x86, 0x8d, 0x75, 0x8c, 0x19, 0x79, 0x59, 0xac, 0x32, 0x66, 0xec, + 0x45, 0x9b, 0x31, 0xa3, 0x80, 0x76, 0x10, 0x2f, 0x16, 0x55, 0xbc, 0xc8, + 0x5a, 0xcb, 0xc2, 0x38, 0x81, 0x3c, 0xb1, 0x8a, 0x3c, 0xb1, 0x8a, 0x3c, + 0xb1, 0x8a, 0x3c, 0xb1, 0x8a, 0x3c, 0x11, 0xb6, 0xfe, 0x5a, 0x15, 0x79, + 0x22, 0xfc, 0xe7, 0x3c, 0x72, 0x92, 0xa0, 0xa6, 0x38, 0x8c, 0x9a, 0xc2, + 0xd5, 0xc6, 0xaa, 0xe3, 0xda, 0xbe, 0x2a, 0x6a, 0x43, 0xf5, 0x9d, 0x58, + 0x1f, 0xda, 0x80, 0xba, 0xa8, 0xe6, 0x6c, 0x01, 0x5f, 0xd7, 0xe0, 0x1b, + 0xd4, 0xd3, 0x56, 0x99, 0xca, 0xed, 0x80, 0x7c, 0xd8, 0x7f, 0xfb, 0xfb, + 0xe8, 0x43, 0x3e, 0x9f, 0x63, 0x0d, 0xc2, 0x78, 0xb5, 0x0f, 0x6d, 0x1d, + 0x6d, 0xec, 0xe9, 0x04, 0x7c, 0xc4, 0x7e, 0x90, 0xf9, 0x62, 0x7a, 0x41, + 0x9e, 0xdc, 0x1c, 0xd8, 0xf4, 0x6f, 0x31, 0x27, 0x5e, 0xd3, 0xde, 0x88, + 0x39, 0xf0, 0x17, 0xd8, 0x97, 0x5a, 0x03, 0x5c, 0xba, 0xfd, 0xe7, 0xc4, + 0xd1, 0xb7, 0xe1, 0xd6, 0x1c, 0xda, 0xd5, 0xf7, 0x9a, 0xfa, 0xb2, 0x98, + 0xcf, 0xef, 0xe2, 0x3b, 0xf0, 0xfb, 0x16, 0x7e, 0x61, 0x77, 0xf6, 0x05, + 0xcc, 0xe9, 0xc3, 0xef, 0x77, 0x9a, 0xe6, 0x42, 0x0a, 0xfb, 0x2f, 0xd1, + 0x77, 0x31, 0xa4, 0xc1, 0x6f, 0x89, 0x5f, 0x6a, 0xe2, 0xe3, 0x07, 0xe8, + 0xfb, 0x6b, 0xf4, 0xf9, 0xfe, 0xdb, 0x4e, 0xd4, 0x27, 0xa5, 0x96, 0x70, + 0xef, 0x46, 0xd5, 0xde, 0x69, 0xca, 0xe6, 0x8f, 0x2c, 0xe9, 0xaa, 0x0e, + 0x7a, 0xae, 0x8e, 0xea, 0x08, 0x71, 0xbe, 0xbc, 0x10, 0xd4, 0xad, 0xc7, + 0x51, 0x73, 0x16, 0xab, 0xb4, 0x91, 0x1c, 0xfa, 0x6d, 0x9c, 0x69, 0x32, + 0x69, 0xdc, 0xaa, 0x63, 0x13, 0x89, 0xc9, 0x7a, 0x9b, 0x48, 0x37, 0x69, + 0x32, 0x4f, 0x22, 0x8e, 0xd9, 0x99, 0xe2, 0xc2, 0xec, 0x8c, 0x07, 0x9c, + 0x63, 0x75, 0xae, 0xe5, 0x3c, 0x93, 0xf7, 0x63, 0x4d, 0x74, 0x69, 0x13, + 0x60, 0x06, 0xf4, 0x9e, 0xab, 0x93, 0x7e, 0x40, 0xb3, 0xac, 0x68, 0xda, + 0xe8, 0x8f, 0xea, 0xc7, 0x1c, 0x6a, 0x5d, 0x99, 0x64, 0xed, 0x5c, 0x0c, + 0x69, 0xba, 0x75, 0x49, 0x24, 0x0a, 0xcd, 0xf8, 0x82, 0x8c, 0xf3, 0xb9, + 0xfa, 0xec, 0x8c, 0xfe, 0x42, 0x36, 0xc7, 0x3b, 0x11, 0xd7, 0x9a, 0x9d, + 0x69, 0x1d, 0x48, 0xc8, 0x8f, 0x91, 0xbb, 0x1d, 0x53, 0x34, 0x66, 0x67, + 0x8c, 0x17, 0x02, 0x5b, 0x0c, 0xe8, 0xe0, 0x3c, 0xc9, 0xb7, 0x43, 0x4e, + 0xd2, 0x62, 0x4d, 0x1d, 0x8c, 0x4f, 0xaa, 0x7a, 0xd1, 0x94, 0x2b, 0x15, + 0x45, 0x3b, 0xac, 0xdb, 0xc9, 0xc3, 0xec, 0x8c, 0xfc, 0xd1, 0x2d, 0x1e, + 0xd6, 0x91, 0x87, 0x78, 0x49, 0x27, 0xd0, 0x5b, 0xc0, 0x7f, 0x12, 0xf5, + 0x7b, 0x54, 0xab, 0xfb, 0xfe, 0x8a, 0x93, 0x43, 0x5c, 0xe0, 0x3e, 0xb6, + 0xa8, 0x3c, 0xd7, 0x73, 0x32, 0xbc, 0xef, 0x9b, 0xe3, 0xdf, 0x39, 0x78, + 0xf9, 0x01, 0xd4, 0x4d, 0xbc, 0x1b, 0xa4, 0x7f, 0xe1, 0xf7, 0x36, 0xff, + 0xe2, 0x7c, 0xf6, 0x93, 0xe7, 0x81, 0xf4, 0x55, 0xf0, 0xe7, 0xe5, 0xd1, + 0x87, 0x58, 0x51, 0x6c, 0x44, 0xb8, 0x78, 0xc7, 0xce, 0x39, 0x2a, 0xff, + 0x6e, 0xf2, 0xd1, 0x96, 0xf0, 0xdc, 0xa5, 0x8e, 0xc8, 0x27, 0xf9, 0xe9, + 0x84, 0x4d, 0x90, 0x17, 0xce, 0x8f, 0xee, 0x25, 0xd8, 0xfe, 0xb8, 0x36, + 0x12, 0xdd, 0xa9, 0x7d, 0x9c, 0x3d, 0x8f, 0x74, 0x76, 0x37, 0x7e, 0x88, + 0x83, 0xb4, 0x23, 0xbe, 0x22, 0x9e, 0x88, 0x8f, 0xfc, 0x44, 0xbc, 0x28, + 0x1b, 0x5d, 0x97, 0x9f, 0x60, 0x5d, 0xc0, 0x4f, 0x69, 0x21, 0x0d, 0x9d, + 0x90, 0xa7, 0x11, 0x6d, 0xa4, 0xba, 0xde, 0x1d, 0xc7, 0x0f, 0x5c, 0xc6, + 0xd5, 0xb1, 0x06, 0xef, 0xa1, 0x48, 0x97, 0x7f, 0x3b, 0xb2, 0xa4, 0x8d, + 0x34, 0xf8, 0x9d, 0xa9, 0xae, 0xb9, 0x8d, 0x88, 0xde, 0x5a, 0x9d, 0x46, + 0xbf, 0xbc, 0x2b, 0xff, 0x0c, 0xf6, 0xa9, 0x3b, 0xf8, 0xbb, 0x14, 0x55, + 0x47, 0xb1, 0x6f, 0xb9, 0xd5, 0x73, 0xa2, 0xbf, 0xd3, 0xd9, 0x1f, 0xe6, + 0x43, 0x51, 0x6d, 0x1c, 0xd5, 0x59, 0xea, 0x9e, 0x7d, 0xaf, 0xe7, 0x68, + 0xc8, 0x4f, 0x99, 0x33, 0x05, 0x3a, 0x08, 0xf1, 0xde, 0x91, 0xcf, 0x91, + 0x26, 0x3e, 0x47, 0xc1, 0xe7, 0x3e, 0xf0, 0x39, 0x76, 0x8b, 0xcf, 0x5b, + 0xb6, 0x97, 0x29, 0xc3, 0xf6, 0x46, 0xd6, 0xb5, 0xbd, 0x55, 0x3a, 0xab, + 0x73, 0x83, 0xfb, 0x9a, 0x91, 0x86, 0x2f, 0xc7, 0x9d, 0x8f, 0x53, 0x37, + 0xb7, 0xcb, 0x99, 0x85, 0xbb, 0xd5, 0xb7, 0x11, 0xaf, 0x2a, 0x77, 0x94, + 0x4b, 0xf5, 0x80, 0x9f, 0x1f, 0x2f, 0xb1, 0x3d, 0x12, 0xea, 0x8a, 0x3a, + 0xcb, 0x3a, 0x25, 0xb9, 0x1b, 0x2f, 0xbf, 0xf8, 0x9c, 0x76, 0xa5, 0x12, + 0x9d, 0x4f, 0x5a, 0x78, 0xc6, 0xae, 0xe5, 0x29, 0xfa, 0x6e, 0x32, 0x66, + 0x45, 0xf7, 0x67, 0x22, 0xfc, 0xfe, 0xc0, 0xef, 0x75, 0x6b, 0xbf, 0x13, + 0xf0, 0x7c, 0x8a, 0x78, 0xd7, 0x53, 0x3c, 0x9f, 0xc6, 0x9c, 0x66, 0x19, + 0x5c, 0xd8, 0xa4, 0x9e, 0xe4, 0x98, 0xe7, 0xd0, 0x2f, 0x4c, 0xd0, 0x0c, + 0xee, 0xdd, 0x6a, 0x4b, 0xbe, 0x5c, 0x74, 0x36, 0x06, 0xe7, 0x28, 0x64, + 0xba, 0x6c, 0xf1, 0xfe, 0x0a, 0x31, 0x8c, 0x67, 0x83, 0xb2, 0xb5, 0x16, + 0xf5, 0x5c, 0x39, 0xd0, 0x0e, 0x1d, 0xb3, 0xdd, 0xd6, 0xcb, 0xfb, 0x0a, + 0xca, 0xbc, 0xa0, 0xf6, 0x21, 0xd2, 0x71, 0xf4, 0x7d, 0xae, 0x55, 0x96, + 0xc3, 0xbb, 0xad, 0xc5, 0x8a, 0xef, 0xbf, 0x83, 0x3c, 0xfc, 0x34, 0x74, + 0x5f, 0xae, 0xff, 0xcc, 0x5f, 0x4e, 0xf1, 0x6f, 0xa5, 0x22, 0x9b, 0xd8, + 0xd1, 0xcb, 0x7b, 0x20, 0xf8, 0x96, 0x1c, 0xaf, 0x87, 0x65, 0xbf, 0x70, + 0x9c, 0x7d, 0xff, 0x0d, 0xbe, 0x7d, 0xff, 0xf4, 0xaa, 0x9d, 0x02, 0xfe, + 0x17, 0x33, 0xe1, 0x9b, 0xdd, 0x90, 0x58, 0x00, 0x00, 0x00 }; static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 }; static u32 bnx2_RXP_b06FwRodata[(0x28/4) + 1] = { @@ -1943,387 +1057,264 @@ static u32 bnx2_RXP_b06FwRodata[(0x28/4) + 1] = { static u32 bnx2_RXP_b06FwBss[(0x13a4/4) + 1] = { 0x0 }; static u32 bnx2_RXP_b06FwSbss[(0x1c/4) + 1] = { 0x0 }; -static u32 bnx2_rv2p_proc1[] = { - 0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004, - 0x00000010, 0x20bf002c, 0x00000010, 0x203f0143, 0x00000018, 0x8000fffd, - 0x00000010, 0xb1b8b017, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000, - 0x00000000, 0x2c380000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000, - 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x00000008, 0x02000002, - 0x00000010, 0x91de0000, 0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08, - 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000008, 0x2d800150, - 0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000010, 0x2c620002, - 0x00000018, 0x80000012, 0x0000000b, 0x2fdf0002, 0x0000000c, 0x1f800002, - 0x00000000, 0x2c070000, 0x00000018, 0x8000ffe6, 0x00000008, 0x02000002, - 0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08, 0x00000008, 0x2c8000b0, - 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, - 0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000018, 0x80000004, - 0x0000000c, 0x1f800002, 0x00000000, 0x00000000, 0x00000018, 0x8000ffd9, - 0x0000000c, 0x29800002, 0x0000000c, 0x1f800002, 0x00000000, 0x2adf0000, - 0x00000008, 0x2a000005, 0x00000018, 0x8000ffd4, 0x00000008, 0x02240030, - 0x00000018, 0x00040000, 0x00000018, 0x80000015, 0x00000018, 0x80000017, - 0x00000018, 0x8000001b, 0x00000018, 0x8000004c, 0x00000018, 0x8000008c, - 0x00000018, 0x8000000f, 0x00000018, 0x8000000e, 0x00000018, 0x8000000d, - 0x00000018, 0x8000000c, 0x00000018, 0x800000c2, 0x00000018, 0x8000000a, - 0x00000018, 0x80000009, 0x00000018, 0x80000008, 0x00000018, 0x800000fd, - 0x00000018, 0x80000006, 0x00000018, 0x80000005, 0x00000018, 0x800000ff, - 0x00000018, 0x80000104, 0x00000018, 0x80000002, 0x00000018, 0x80000098, - 0x00000018, 0x80000000, 0x0000000c, 0x1f800001, 0x00000000, 0x00000000, - 0x00000018, 0x8000ffba, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001, - 0x0000000c, 0x1f800001, 0x00000008, 0x2a000002, 0x00000018, 0x8000ffb5, - 0x00000010, 0xb1a0b012, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000, - 0x00000008, 0x2c800000, 0x00000008, 0x2d000000, 0x00000010, 0x91d40000, - 0x00000008, 0x2d80011c, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, - 0x0000000f, 0x47600008, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, - 0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, - 0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000018, 0x80000013, - 0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002, 0x00000008, 0x2c800000, - 0x00000008, 0x2d000000, 0x00000010, 0x91d40000, 0x00000008, 0x2d80011c, - 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, 0x00000000, 0x0f580000, - 0x00000010, 0x91de0000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, - 0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000000, 0x02620000, - 0x0000000b, 0x2fdf0002, 0x00000000, 0x309a0000, 0x00000000, 0x31040000, - 0x00000000, 0x0c961800, 0x00000009, 0x0c99ffff, 0x00000004, 0xcc993400, - 0x00000010, 0xb1963202, 0x00000008, 0x0f800000, 0x0000000c, 0x29800001, - 0x00000010, 0x00220002, 0x0000000c, 0x29520001, 0x0000000c, 0x29520000, - 0x00000008, 0x22000001, 0x0000000c, 0x1f800001, 0x00000000, 0x2adf0000, - 0x00000008, 0x2a000003, 0x00000018, 0x8000ff83, 0x00000010, 0xb1a0b01d, - 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0, - 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150, - 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000, - 0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000000, 0x00000000, - 0x00000010, 0x91de0000, 0x0000000f, 0x47600008, 0x00000000, 0x060e0000, - 0x00000010, 0x001f0000, 0x00000000, 0x0f580000, 0x00000010, 0x91de0000, - 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, 0x00000000, 0x0b670000, - 0x00000000, 0x0d620000, 0x00000000, 0x0ce71800, 0x00000009, 0x0c99ffff, - 0x00000004, 0xcc993400, 0x00000010, 0xb1963220, 0x00000008, 0x0f800000, - 0x00000018, 0x8000001e, 0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002, - 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, - 0x00000008, 0x2d80012c, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, - 0x00000000, 0x0f580000, 0x00000010, 0x91de0000, 0x00000000, 0x0a640000, - 0x00000000, 0x0ae50000, 0x00000000, 0x0b670000, 0x00000000, 0x0d620000, - 0x00000000, 0x02630000, 0x0000000f, 0x47620010, 0x00000000, 0x0ce71800, - 0x0000000b, 0x2fdf0002, 0x00000000, 0x311a0000, 0x00000000, 0x31840000, - 0x0000000b, 0xc20000ff, 0x00000002, 0x42040000, 0x00000001, 0x31620800, - 0x0000000f, 0x020e0010, 0x00000002, 0x31620800, 0x00000009, 0x0c99ffff, - 0x00000004, 0xcc993400, 0x00000010, 0xb1963202, 0x00000008, 0x0f800000, - 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x0000000c, 0x61420006, - 0x00000008, 0x22000008, 0x00000000, 0x2adf0000, 0x00000008, 0x2a000004, - 0x00000018, 0x8000ff42, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, - 0x00000010, 0x91a0b008, 0x00000010, 0x91d40000, 0x0000000c, 0x31620018, - 0x00000008, 0x2d800001, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, - 0x00000008, 0xac000001, 0x00000018, 0x8000000e, 0x00000000, 0x0380b000, - 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c004000, 0x00000010, 0x91d40000, - 0x00000008, 0x2d800101, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, - 0x0000000c, 0x31620018, 0x00000008, 0x2d800001, 0x00000000, 0x00000000, - 0x00000010, 0x91de0000, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c000e00, - 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000008, 0x2a000007, - 0x00000018, 0x8000ff27, 0x00000010, 0xb1a0b016, 0x0000000b, 0x2fdf0002, - 0x00000000, 0x03d80000, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0, - 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150, - 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000, - 0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000008, 0x07000001, - 0x00000010, 0xb5de1c00, 0x00000010, 0x2c620002, 0x00000018, 0x8000000a, - 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c070000, 0x0000000c, 0x1f800001, - 0x00000010, 0x91de0000, 0x00000018, 0x8000ff11, 0x00000008, 0x2c8000b0, - 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, - 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000010, 0x91de0000, - 0x00000000, 0x2adf0000, 0x00000008, 0x2a00000a, 0x00000018, 0x8000ff07, - 0x00000000, 0x82265600, 0x0000000f, 0x47220008, 0x00000009, 0x070e000f, - 0x00000008, 0x070e0008, 0x00000008, 0x02800001, 0x00000007, 0x02851c00, - 0x00000008, 0x82850001, 0x00000000, 0x02840a00, 0x00000007, 0x42851c00, - 0x00000003, 0xc3aa5200, 0x00000000, 0x03b10e00, 0x00000010, 0x001f0000, - 0x0000000f, 0x0f280007, 0x00000007, 0x4b071c00, 0x00000000, 0x00000000, - 0x0000000f, 0x0a960003, 0x00000000, 0x0a955c00, 0x00000000, 0x4a005a00, - 0x00000000, 0x0c960a00, 0x00000009, 0x0c99ffff, 0x00000008, 0x0d00ffff, - 0x00000010, 0xb1963202, 0x00000008, 0x0f800005, 0x00000010, 0x00220020, - 0x00000000, 0x02a70000, 0x00000010, 0xb1850002, 0x00000008, 0x82850200, - 0x00000000, 0x02000000, 0x00000000, 0x03a60000, 0x00000018, 0x8000004e, - 0x00000000, 0x072b0000, 0x00000001, 0x878c1c00, 0x00000000, 0x870e1e00, - 0x00000000, 0x860c1e00, 0x00000000, 0x03061e00, 0x00000010, 0xb18e0003, - 0x00000018, 0x80000047, 0x00000018, 0x8000fffa, 0x00000010, 0x918c0003, - 0x00000010, 0xb1870002, 0x00000018, 0x80000043, 0x00000010, 0x91d40000, - 0x0000000c, 0x29800001, 0x00000000, 0x2a860000, 0x00000000, 0x230c0000, - 0x00000000, 0x2b070000, 0x00000010, 0xb187000e, 0x00000008, 0x2a000008, - 0x00000018, 0x8000003b, 0x00000010, 0x91d40000, 0x00000000, 0x28d18c00, - 0x00000000, 0x2a860000, 0x00000000, 0x230c0000, 0x00000000, 0x2b070000, - 0x00000018, 0x8000fff8, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001, - 0x00000000, 0x2aab0000, 0x00000000, 0xa3265600, 0x00000000, 0x2b000000, - 0x0000000c, 0x1f800001, 0x00000008, 0x2a000008, 0x00000018, 0x8000fec8, - 0x00000010, 0x91d40000, 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, - 0x00000008, 0x2a000009, 0x00000018, 0x8000fec3, 0x00000010, 0x91d40000, - 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000000, 0x29420000, - 0x00000008, 0x2a000002, 0x00000018, 0x8000febd, 0x00000018, 0x8000febc, - 0x00000010, 0xb1bcb016, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000, - 0x00000000, 0x2c3c0000, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, - 0x00000010, 0x91d40000, 0x00000008, 0x2d800150, 0x00000000, 0x00000000, - 0x00000010, 0x205f0000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000, - 0x00000008, 0x2d800108, 0x00000008, 0x07000001, 0x00000010, 0xb5de1c00, - 0x00000010, 0x2c620002, 0x00000018, 0x8000000a, 0x0000000b, 0x2fdf0002, - 0x00000000, 0x2c070000, 0x0000000c, 0x1f800000, 0x00000010, 0x91de0000, - 0x00000018, 0x8000fea6, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, - 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x0000000c, 0x29800000, - 0x0000000c, 0x1f800000, 0x00000010, 0x91de0000, 0x00000000, 0x2adf0000, - 0x00000008, 0x2a000006, 0x00000018, 0x8000fe9c, 0x00000008, 0x03050004, - 0x00000006, 0x83040c00, 0x00000008, 0x02850200, 0x00000000, 0x86050c00, - 0x00000001, 0x860c0e00, 0x00000008, 0x02040004, 0x00000000, 0x02041800, - 0x00000000, 0x83871800, 0x00000018, 0x00020000 }; +static u8 bnx2_rv2p_proc1[] = { + 0x1f, 0x8b, 0x08, 0x08, 0x5e, 0xd0, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xc5, 0x56, 0xcf, 0x6b, + 0x13, 0x51, 0x10, 0x9e, 0xec, 0x6e, 0xb2, 0xdb, 0x74, 0xbb, 0x1b, 0x2b, + 0xda, 0xa0, 0xb1, 0x8d, 0x51, 0x6a, 0x7f, 0xa4, 0xb4, 0x11, 0x0f, 0x82, + 0x42, 0x25, 0x3d, 0x04, 0x54, 0x44, 0x7a, 0x28, 0x22, 0x82, 0x36, 0x8a, + 0xfe, 0x1b, 0xa1, 0x3f, 0xd2, 0x4b, 0x10, 0x7a, 0xb0, 0x58, 0xf1, 0x50, + 0x10, 0x2a, 0x68, 0x0f, 0xc9, 0xa1, 0x20, 0x52, 0x11, 0xda, 0x8b, 0x07, + 0x2f, 0x42, 0x0f, 0x7a, 0x69, 0xbd, 0xa8, 0xff, 0x82, 0x08, 0x4d, 0x7c, + 0x6f, 0x66, 0x9e, 0xee, 0x6e, 0xb2, 0x4d, 0x15, 0xc1, 0x85, 0xf6, 0xe3, + 0xbd, 0x9d, 0x79, 0x33, 0xf3, 0xcd, 0x37, 0xfb, 0x62, 0x01, 0x40, 0x04, + 0x60, 0xcd, 0x46, 0x2c, 0x8d, 0x26, 0x04, 0x1a, 0x30, 0x7e, 0x52, 0x62, + 0x16, 0xde, 0xa6, 0x25, 0x4e, 0x44, 0xc6, 0xd3, 0x49, 0x81, 0x7b, 0x0d, + 0x28, 0xc9, 0x75, 0x4f, 0xf5, 0x55, 0xad, 0x53, 0xa0, 0x06, 0xbb, 0xa3, + 0x80, 0xcf, 0x47, 0x9d, 0xf0, 0x7c, 0xd6, 0x42, 0x2c, 0x31, 0xc2, 0x48, + 0x02, 0x61, 0x7b, 0x51, 0xae, 0xad, 0x48, 0x69, 0xc4, 0x42, 0x3f, 0xd0, + 0x68, 0x7f, 0x67, 0xd1, 0x15, 0xff, 0x53, 0xf0, 0x39, 0x2f, 0xd7, 0x56, + 0x7c, 0x0e, 0xed, 0xaa, 0xec, 0x2f, 0xfe, 0xd0, 0xfe, 0xba, 0xf0, 0x03, + 0x7e, 0x94, 0x5f, 0x02, 0xcf, 0x29, 0x66, 0x65, 0x5e, 0xdd, 0x22, 0xa0, + 0xca, 0xc7, 0x46, 0x2c, 0xf5, 0x91, 0xb5, 0x89, 0xef, 0xbf, 0x8a, 0xbc, + 0x55, 0xdc, 0x76, 0xf1, 0x82, 0xf9, 0x06, 0xe3, 0x26, 0x91, 0x1f, 0x28, + 0xf9, 0xe3, 0x00, 0xc8, 0xfd, 0x4f, 0x8d, 0x5f, 0xfb, 0x83, 0xfe, 0xf7, + 0xbb, 0x43, 0xf2, 0xbc, 0x28, 0xc0, 0x90, 0xb4, 0xdb, 0xe6, 0x7c, 0xc6, + 0xe0, 0xb4, 0x96, 0xc4, 0xf7, 0x06, 0xfa, 0x1f, 0x11, 0xe7, 0x4a, 0xec, + 0x61, 0x3c, 0xce, 0x78, 0x95, 0xb1, 0xc2, 0xe8, 0x32, 0x3a, 0x8c, 0x5d, + 0x8c, 0x36, 0xe3, 0x26, 0x63, 0x9c, 0xb1, 0x83, 0xd1, 0x62, 0xdc, 0x63, + 0x8c, 0x31, 0x46, 0x19, 0x1b, 0x8c, 0x46, 0x84, 0x50, 0xe3, 0xf5, 0x63, + 0x46, 0xe0, 0xba, 0x23, 0x81, 0xba, 0x5f, 0xb3, 0x2e, 0x24, 0x6f, 0xfc, + 0x7e, 0x50, 0xd9, 0x31, 0xef, 0x58, 0xf7, 0x3a, 0xdb, 0x75, 0x57, 0x57, + 0x02, 0xfa, 0x49, 0xef, 0xab, 0x9b, 0x54, 0x8b, 0x3e, 0xb8, 0x58, 0xcf, + 0x9d, 0x82, 0x8b, 0x71, 0x9c, 0x18, 0xed, 0xab, 0xb4, 0x6e, 0xb8, 0x84, + 0xf7, 0xe2, 0x84, 0x5f, 0x18, 0xef, 0x77, 0x12, 0x4e, 0x77, 0xc9, 0x7c, + 0x0e, 0x8b, 0x80, 0xea, 0x1c, 0x95, 0x4f, 0xbb, 0x3c, 0xc2, 0xe2, 0xa9, + 0xbc, 0xda, 0xc5, 0x25, 0x2c, 0x6a, 0xfe, 0xfa, 0x9f, 0x8c, 0x11, 0x1a, + 0x39, 0x22, 0x75, 0xc9, 0x16, 0x3d, 0x83, 0x46, 0x63, 0xd9, 0x36, 0xe4, + 0xfa, 0xdc, 0xf2, 0x7b, 0xd4, 0xfb, 0xd9, 0xa5, 0x1a, 0xe7, 0xe7, 0x2a, + 0x9e, 0x69, 0x0e, 0x32, 0x40, 0xeb, 0x49, 0xe4, 0x1d, 0x04, 0x5a, 0xb8, + 0x86, 0x8c, 0xbf, 0x5f, 0xa4, 0x43, 0x9d, 0xfb, 0x31, 0xcb, 0xfd, 0x38, + 0x11, 0xd2, 0x8f, 0xb0, 0xb9, 0x68, 0x9e, 0xc7, 0xdb, 0xe9, 0x20, 0x6f, + 0x61, 0xf3, 0xa3, 0xf8, 0xa6, 0xdd, 0x3f, 0xe5, 0xf1, 0x01, 0xf3, 0x58, + 0x24, 0x1e, 0x93, 0xdf, 0x5a, 0xf2, 0x94, 0xf6, 0xf0, 0x24, 0xeb, 0xec, + 0x0d, 0xe9, 0x73, 0x58, 0x7d, 0xd9, 0xbf, 0xee, 0x73, 0x20, 0x3f, 0xb8, + 0x8b, 0xdf, 0x9b, 0x04, 0x14, 0x0b, 0x2a, 0x5f, 0x3f, 0xcf, 0xc7, 0xa8, + 0xdf, 0x30, 0x97, 0x93, 0xfb, 0x62, 0xfe, 0x36, 0x35, 0x5c, 0x1b, 0xf9, + 0x88, 0x04, 0xab, 0x98, 0x23, 0x7f, 0x47, 0xd3, 0x78, 0x7d, 0x50, 0x5d, + 0xa8, 0xbe, 0x4b, 0x8c, 0x41, 0x7e, 0x9a, 0xeb, 0xcc, 0x50, 0x3c, 0xd2, + 0x81, 0xc1, 0x3a, 0xc8, 0xf3, 0xf7, 0x28, 0xc8, 0x87, 0x55, 0x5d, 0x59, + 0xf4, 0xce, 0x75, 0x12, 0x8a, 0x39, 0xd2, 0x55, 0x73, 0x5f, 0x59, 0x6f, + 0x6b, 0xea, 0xbb, 0x84, 0xdb, 0xd5, 0x92, 0xee, 0xab, 0xf7, 0x12, 0x64, + 0xbd, 0x3c, 0x47, 0x5a, 0xe8, 0xa3, 0x5d, 0x1c, 0xdf, 0x79, 0x0e, 0x64, + 0x5b, 0x7d, 0x6f, 0x4c, 0xae, 0xeb, 0x0c, 0xeb, 0xfb, 0x68, 0x93, 0xbe, + 0xd5, 0x7d, 0xf5, 0xef, 0x74, 0xce, 0xf5, 0x9b, 0x68, 0x97, 0xda, 0x59, + 0xf7, 0xde, 0x4f, 0x71, 0xcf, 0xfd, 0x44, 0x6e, 0xa6, 0xca, 0xbb, 0xcf, + 0x7b, 0xaf, 0x1c, 0x0a, 0xe9, 0x83, 0xf7, 0x3e, 0x0a, 0xd6, 0xeb, 0xd7, + 0x23, 0xf5, 0x35, 0xce, 0xf5, 0x9b, 0x0d, 0xee, 0xc3, 0x54, 0xff, 0x0c, + 0xe9, 0x3f, 0x53, 0x90, 0xfa, 0x71, 0xc1, 0x31, 0xe9, 0x7c, 0x42, 0x71, + 0x8e, 0x66, 0x62, 0xde, 0xf3, 0x1a, 0xad, 0xe7, 0x67, 0xd0, 0x2f, 0x3e, + 0xa7, 0xf6, 0xf3, 0x48, 0xd8, 0xe4, 0x8b, 0x2d, 0xe2, 0xbd, 0xa6, 0xab, + 0xb9, 0x70, 0x91, 0xef, 0x01, 0x97, 0xec, 0xcc, 0x2b, 0x8a, 0x2f, 0xb9, + 0xaf, 0xc3, 0x12, 0xcd, 0xc5, 0xad, 0x47, 0x84, 0x37, 0xe1, 0x32, 0x9d, + 0xfb, 0xfb, 0xfb, 0x66, 0x21, 0x42, 0x97, 0x57, 0xc7, 0x51, 0xa1, 0x63, + 0x9c, 0x63, 0x25, 0x57, 0x78, 0xae, 0x11, 0x9f, 0xf3, 0xa4, 0x73, 0x8d, + 0xf3, 0xc3, 0xab, 0x45, 0x3e, 0xab, 0xba, 0xac, 0xf7, 0x9a, 0xd2, 0x1d, + 0x0c, 0x9b, 0x38, 0x3f, 0xa9, 0xca, 0x02, 0x2e, 0x7b, 0x1d, 0x46, 0xbb, + 0x4c, 0x18, 0xc3, 0xfc, 0x75, 0x78, 0x58, 0x93, 0x7e, 0x05, 0xbe, 0xdf, + 0x7e, 0xb0, 0x5e, 0x74, 0xa8, 0xf0, 0xef, 0x8b, 0x05, 0x7c, 0x3f, 0x01, + 0xcd, 0xf7, 0x1b, 0xc5, 0x29, 0x0f, 0x11, 0xda, 0xa7, 0xb8, 0xaf, 0xc3, + 0xd2, 0xce, 0x11, 0x7e, 0xdc, 0x3f, 0xec, 0xc3, 0x05, 0x8f, 0x3f, 0x42, + 0xe5, 0xc3, 0x40, 0x98, 0xbf, 0xb4, 0xff, 0xde, 0xe2, 0x3e, 0xa5, 0xf7, + 0x2f, 0xc9, 0x7e, 0xaa, 0xff, 0x19, 0xd7, 0x3f, 0xec, 0xd5, 0xbd, 0x8a, + 0xf7, 0xae, 0xbe, 0xff, 0x7d, 0xdc, 0xc1, 0x76, 0x5b, 0xfb, 0xd8, 0xd1, + 0xf1, 0xf9, 0x41, 0xef, 0xfd, 0xfd, 0xa6, 0x4e, 0x3c, 0x6d, 0xd4, 0xd5, + 0x5c, 0x6d, 0x84, 0xcc, 0xd5, 0xc5, 0xff, 0x3a, 0x57, 0x10, 0x98, 0xab, + 0xd5, 0xfa, 0xc1, 0xe6, 0x0a, 0xb8, 0x7e, 0x08, 0x99, 0xab, 0x18, 0xf3, + 0xf0, 0x94, 0xcf, 0x33, 0x20, 0xaa, 0xc7, 0xb0, 0x7d, 0xc6, 0x2c, 0xeb, + 0x92, 0xf4, 0x68, 0x47, 0xcb, 0xa8, 0x3f, 0xc7, 0x2e, 0x93, 0x9d, 0x41, + 0xfb, 0x49, 0x85, 0x0b, 0xb3, 0xf4, 0x7b, 0x4a, 0x83, 0x9f, 0x94, 0x15, + 0x12, 0x3d, 0x80, 0x0b, 0x00, 0x00, 0x00 }; -static u32 bnx2_rv2p_proc2[] = { - 0x00000000, 0x2a000000, 0x00000010, 0xb1d40000, 0x00000008, 0x02540003, - 0x00000018, 0x00040000, 0x00000018, 0x8000000a, 0x00000018, 0x8000000a, - 0x00000018, 0x8000000e, 0x00000018, 0x80000056, 0x00000018, 0x800001b9, - 0x00000018, 0x800001e1, 0x00000018, 0x8000019b, 0x00000018, 0x800001f9, - 0x00000018, 0x8000019f, 0x00000018, 0x800001a6, 0x00000018, 0x80000000, - 0x0000000c, 0x29800001, 0x00000000, 0x2a000000, 0x0000000c, 0x29800000, - 0x00000010, 0x20530000, 0x00000018, 0x8000ffee, 0x0000000c, 0x29800001, - 0x00000010, 0x91de0000, 0x00000010, 0x001f0000, 0x00000000, 0x2f80aa00, - 0x00000000, 0x2a000000, 0x00000000, 0x0d610000, 0x00000000, 0x03620000, - 0x00000000, 0x2c400000, 0x00000000, 0x02638c00, 0x00000000, 0x26460000, - 0x00000010, 0x00420002, 0x00000008, 0x02040012, 0x00000010, 0xb9060836, - 0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, - 0x00000000, 0x0b660000, 0x00000000, 0x0c000000, 0x00000000, 0x0b800000, - 0x00000010, 0x00420009, 0x00000008, 0x0cc60012, 0x00000008, 0x0f800003, - 0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000008, 0x27110012, - 0x00000000, 0x66900000, 0x00000008, 0xa31b0012, 0x00000018, 0x80000008, - 0x00000000, 0x0cc60000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000, - 0x00000010, 0x009f0000, 0x00000000, 0x27110000, 0x00000000, 0x66900000, - 0x00000000, 0x231b0000, 0x00000010, 0xb197320e, 0x00000000, 0x25960000, - 0x00000000, 0x021b0000, 0x00000010, 0x001f0000, 0x00000008, 0x0f800003, - 0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000000, 0x22c50800, - 0x00000010, 0x009f0000, 0x00000000, 0x27002200, 0x00000000, 0x26802000, - 0x00000000, 0x231b0000, 0x0000000c, 0x69520001, 0x00000018, 0x8000fff3, - 0x00000010, 0x01130002, 0x00000010, 0xb1980003, 0x00000010, 0x001f0000, - 0x00000008, 0x0f800004, 0x00000008, 0x22000003, 0x00000008, 0x2c80000c, - 0x00000008, 0x2d00000c, 0x00000010, 0x009f0000, 0x00000000, 0x25960000, - 0x0000000c, 0x29800000, 0x00000000, 0x32140000, 0x00000000, 0x32950000, - 0x00000000, 0x33160000, 0x00000000, 0x31e32e00, 0x00000008, 0x2d800010, - 0x00000010, 0x20530000, 0x00000018, 0x8000ffac, 0x00000000, 0x23000000, - 0x00000000, 0x25e60000, 0x00000008, 0x2200000b, 0x0000000c, 0x69520000, - 0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000018, 0x8000ffa5, - 0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, - 0x00000010, 0x001f0000, 0x00000000, 0x02700000, 0x00000000, 0x0d620000, - 0x00000000, 0xbb630800, 0x00000000, 0x2a000000, 0x00000009, 0x076000ff, - 0x0000000f, 0x2c0e0007, 0x00000008, 0x2c800000, 0x00000008, 0x2d000064, - 0x00000008, 0x2d80011c, 0x00000009, 0x06420002, 0x0000000c, 0x61420001, - 0x00000000, 0x0f400000, 0x00000000, 0x02d08c00, 0x00000000, 0x23000000, - 0x00000004, 0x826da000, 0x00000000, 0x8304a000, 0x00000000, 0x22c50c00, - 0x00000000, 0x03760000, 0x00000004, 0x83860a00, 0x00000000, 0x83870c00, - 0x00000010, 0x91de0000, 0x00000000, 0x037c0000, 0x00000000, 0x837b0c00, - 0x00000001, 0x83060e00, 0x00000000, 0x83870c00, 0x00000000, 0x82850e00, - 0x00000010, 0xb1860016, 0x0000000f, 0x47610018, 0x00000000, 0x068e0000, - 0x0000000f, 0x47670010, 0x0000000f, 0x47e20010, 0x00000000, 0x870e1e00, - 0x00000010, 0xb70e1a10, 0x00000010, 0x0ce7000e, 0x00000008, 0x22000009, - 0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400, - 0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004, - 0x00000018, 0x8000023f, 0x00000000, 0x37ed0000, 0x0000000c, 0x73e7001a, - 0x00000010, 0x20530000, 0x00000008, 0x22000008, 0x0000000c, 0x61420004, - 0x00000000, 0x02f60000, 0x00000004, 0x82840a00, 0x00000010, 0xb1840a2b, - 0x00000010, 0x2d67000a, 0x00000010, 0xb96d0804, 0x00000004, 0xb6ed0a00, - 0x00000000, 0x37ed0000, 0x00000018, 0x80000029, 0x0000000c, 0x61420000, - 0x00000000, 0x37040000, 0x00000000, 0x37850000, 0x0000000c, 0x33e7001a, - 0x00000018, 0x80000024, 0x00000010, 0xb96d0809, 0x00000004, 0xb6ed0a00, - 0x00000000, 0x036d0000, 0x00000004, 0xb76e0c00, 0x00000010, 0x91ee0c1f, - 0x0000000c, 0x73e7001a, 0x00000004, 0xb6ef0c00, 0x00000000, 0x37ed0000, - 0x00000018, 0x8000001b, 0x0000000c, 0x61420000, 0x00000010, 0xb7ee0a05, - 0x00000010, 0xb96f0815, 0x00000003, 0xb76e0800, 0x00000004, 0xb7ef0a00, - 0x00000018, 0x80000015, 0x00000010, 0x0ce7000c, 0x00000008, 0x22000009, - 0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400, - 0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004, - 0x00000018, 0x80000215, 0x00000010, 0x20530000, 0x00000008, 0x22000008, - 0x0000000c, 0x61420004, 0x00000000, 0x37040000, 0x00000000, 0x37850000, - 0x00000000, 0x036d0000, 0x00000003, 0xb8f10c00, 0x00000018, 0x80000004, - 0x00000000, 0x02840000, 0x00000002, 0x21421800, 0x0000000c, 0x61420000, - 0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff, - 0x00000000, 0x23000000, 0x00000010, 0xb1840a3d, 0x00000010, 0x01420002, - 0x00000004, 0xb8f10a00, 0x00000003, 0x83760a00, 0x00000010, 0xb8040c39, - 0x00000010, 0xb7e6080a, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, - 0x00000009, 0x0c68ffff, 0x00000009, 0x0b67ffff, 0x00000000, 0x0be60000, - 0x00000000, 0x0c840000, 0x00000010, 0xb197320c, 0x00000008, 0x0f800002, - 0x00000018, 0x8000000a, 0x00000000, 0x0a6a0000, 0x00000000, 0x0aeb0000, - 0x00000000, 0x0c000000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0be90000, - 0x00000000, 0x0c840000, 0x00000010, 0xb1973203, 0x00000008, 0x0f800002, - 0x00000018, 0x80000001, 0x00000010, 0x001f0000, 0x00000000, 0x0c860000, - 0x00000000, 0x06980000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000, - 0x00000010, 0x009f0000, 0x00000010, 0xb1973210, 0x00000000, 0x231b0000, - 0x00000000, 0x02043600, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, - 0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000, - 0x0000000c, 0x29000000, 0x00000018, 0x800001de, 0x00000000, 0x06980000, - 0x00000010, 0x20530000, 0x00000000, 0x22c58c00, 0x00000010, 0x001f0000, - 0x00000008, 0x0f800003, 0x00000018, 0x8000fff0, 0x00000000, 0x02043600, - 0x00000000, 0x231b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, - 0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000, - 0x0000000c, 0x29000000, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, - 0x00000000, 0x32140000, 0x00000000, 0x32950000, 0x00000005, 0x73e72c00, - 0x00000005, 0x74683000, 0x00000000, 0x33170000, 0x00000018, 0x80000138, - 0x00000010, 0x91c60004, 0x00000008, 0x07000004, 0x00000010, 0xb1c41c02, - 0x00000010, 0x91840a04, 0x00000018, 0x800001c3, 0x00000010, 0x20530000, - 0x00000000, 0x22c58c00, 0x00000010, 0xb1840a8e, 0x0000000c, 0x21420006, - 0x00000010, 0x0ce7001a, 0x0000000f, 0x43680010, 0x00000000, 0x03f30c00, - 0x00000010, 0x91870850, 0x0000000f, 0x46ec0010, 0x00000010, 0xb68d0c4e, - 0x00000000, 0x838d0c00, 0x00000000, 0xa3050800, 0x00000001, 0xa3460e00, - 0x00000000, 0x02048c00, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, - 0x00000010, 0x001f0000, 0x00000008, 0x22000008, 0x00000003, 0x8384a000, - 0x0000000f, 0x65870010, 0x00000009, 0x2607ffff, 0x00000000, 0x27750c00, - 0x00000000, 0x66f40000, 0x0000000c, 0x29000000, 0x00000018, 0x800001aa, - 0x00000000, 0x03068c00, 0x00000003, 0xf4680c00, 0x00000010, 0x20530000, - 0x00000000, 0x22c58c00, 0x00000018, 0x8000ffe5, 0x00000000, 0x39760000, - 0x00000000, 0x39840000, 0x0000000c, 0x33e70019, 0x00000010, 0x001f0000, - 0x00000000, 0x031e0000, 0x00000000, 0x0760fe00, 0x0000000f, 0x0f0e0007, - 0x00000000, 0x83850800, 0x00000000, 0x0a7d0000, 0x00000000, 0x0afe0000, - 0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000, 0x00000000, 0x0c000000, - 0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003, - 0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff, - 0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010, - 0x00000002, 0x33e70e00, 0x00000000, 0x28f30000, 0x00000010, 0x009f0000, - 0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, - 0x00000008, 0x22000006, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000, - 0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, - 0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000, - 0x0000000c, 0x29000000, 0x00000018, 0x8000017e, 0x00000003, 0xf4683600, - 0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400, - 0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004, - 0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000, - 0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000, - 0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000, - 0x00000000, 0x22c53600, 0x00000018, 0x8000ffac, 0x00000010, 0x001f0000, - 0x00000000, 0x031e0000, 0x00000000, 0x83850800, 0x00000009, 0x076000ff, - 0x0000000f, 0x0f0e0007, 0x00000000, 0x0c000000, 0x00000000, 0x0a7d0000, - 0x00000000, 0x0afe0000, 0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000, - 0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003, - 0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff, - 0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010, - 0x00000002, 0x33e70e00, 0x00000000, 0x39840000, 0x00000003, 0xb9720800, - 0x00000000, 0x28f30000, 0x0000000f, 0x65680010, 0x00000010, 0x009f0000, - 0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, - 0x00000008, 0x22000007, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000, - 0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, - 0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000, - 0x0000000c, 0x29000000, 0x00000018, 0x80000145, 0x00000003, 0xf4683600, - 0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400, - 0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004, - 0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000, - 0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000, - 0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000, - 0x00000000, 0x22c53600, 0x00000018, 0x8000ff73, 0x00000010, 0x0ce70005, - 0x00000008, 0x2c80000c, 0x00000008, 0x2d000070, 0x00000008, 0x2d800010, - 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000018, 0x8000011d, - 0x00000000, 0x2c1e0000, 0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010, - 0x00000008, 0x2d800048, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, - 0x00000018, 0x8000fe5d, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000, - 0x00000010, 0x001f0000, 0x00000000, 0x0f008000, 0x00000008, 0x0f800007, - 0x00000018, 0x80000006, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000, - 0x00000010, 0x001f0000, 0x0000000f, 0x0f470007, 0x00000008, 0x0f800008, - 0x00000018, 0x80000119, 0x00000010, 0x20530000, 0x00000018, 0x8000fe4f, - 0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, - 0x00000000, 0x2a000000, 0x00000009, 0x0261ffff, 0x0000000d, 0x70e10001, - 0x00000018, 0x80000101, 0x00000000, 0x2c400000, 0x00000008, 0x2c8000c4, - 0x00000008, 0x2d00001c, 0x00000008, 0x2d800001, 0x00000005, 0x70e10800, - 0x00000010, 0x91de0000, 0x00000018, 0x8000fe41, 0x0000000c, 0x29800001, - 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, 0x00000010, 0x001f0000, - 0x00000000, 0x02700000, 0x00000000, 0x0d620000, 0x00000000, 0xbb630800, - 0x00000000, 0x2a000000, 0x00000000, 0x0f400000, 0x00000000, 0x2c400000, - 0x0000000c, 0x73e7001b, 0x00000010, 0x0ce7000e, 0x00000000, 0x286d0000, - 0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff, 0x00000018, 0x80000069, - 0x00000008, 0x02000004, 0x00000010, 0x91c40803, 0x00000018, 0x800000f6, - 0x00000010, 0x20530000, 0x00000018, 0x800000e5, 0x00000008, 0x2c8000b8, - 0x00000008, 0x2d000010, 0x00000008, 0x2d800048, 0x00000018, 0x80000005, - 0x00000008, 0x2c8000c4, 0x00000008, 0x2d00001c, 0x00000008, 0x2d800001, - 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800048, - 0x00000008, 0x2d000068, 0x00000008, 0x2d800104, 0x00000000, 0x00000000, - 0x00000010, 0x91de0000, 0x00000000, 0x27f60000, 0x00000010, 0xb87a9e04, - 0x00000008, 0x2200000d, 0x00000018, 0x800000e2, 0x00000010, 0x20530000, - 0x00000018, 0x8000fe18, 0x0000000c, 0x29800001, 0x00000010, 0x91de0000, - 0x00000000, 0x2fd50000, 0x00000010, 0x001f0000, 0x00000000, 0x02700000, - 0x00000000, 0x0d620000, 0x00000000, 0xbb630800, 0x00000000, 0x2a000000, - 0x00000010, 0x0e670011, 0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010, - 0x00000009, 0x266dffff, 0x00000004, 0xb8f1a000, 0x00000000, 0x0f400000, - 0x0000000c, 0x73e7001c, 0x00000018, 0x80000040, 0x00000008, 0x02000004, - 0x00000010, 0x91c40802, 0x00000018, 0x800000cd, 0x00000000, 0x2c1e0000, - 0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010, 0x00000008, 0x2d800048, - 0x00000010, 0x20530000, 0x00000010, 0x91de0000, 0x00000018, 0x8000fdfe, - 0x0000000c, 0x29800001, 0x00000000, 0x03550000, 0x00000000, 0x06460000, - 0x00000000, 0x03d60000, 0x00000000, 0x2a000000, 0x0000000f, 0x0f480007, - 0x00000010, 0xb18c0027, 0x0000000f, 0x47420008, 0x00000009, 0x070e000f, - 0x00000008, 0x070e0008, 0x00000010, 0x001f0000, 0x00000008, 0x09000001, - 0x00000007, 0x09121c00, 0x00000003, 0xcbca9200, 0x00000000, 0x0b97a200, - 0x00000007, 0x4b171c00, 0x0000000f, 0x0a960003, 0x00000000, 0x0a959c00, - 0x00000000, 0x4a009a00, 0x00000008, 0x82120001, 0x00000001, 0x0c170800, - 0x00000000, 0x02180000, 0x00000000, 0x0c971800, 0x00000008, 0x0d00ffff, - 0x00000008, 0x0f800006, 0x0000000c, 0x29000000, 0x00000008, 0x22000001, - 0x00000000, 0x22c50c00, 0x00000010, 0x009f0000, 0x00000010, 0xb197320b, - 0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000, - 0x00000018, 0x800000a4, 0x00000000, 0x02180000, 0x00000010, 0x20530000, - 0x00000000, 0x22c53600, 0x00000010, 0x001f0000, 0x00000008, 0x0f800006, - 0x00000018, 0x8000fff5, 0x00000010, 0x91870002, 0x00000008, 0x2200000a, - 0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000, - 0x00000018, 0x80000098, 0x00000008, 0x0200000a, 0x00000010, 0x91c40804, - 0x00000010, 0x02c20003, 0x00000010, 0x001f0000, 0x00000008, 0x0f800008, - 0x00000010, 0x20530000, 0x00000018, 0x8000fdc9, 0x00000000, 0x06820000, - 0x00000010, 0x001f0000, 0x00000010, 0x0ce70028, 0x00000000, 0x03720000, - 0x00000000, 0xa8760c00, 0x00000000, 0x0cf60000, 0x00000010, 0xb8723224, - 0x00000000, 0x03440000, 0x00000008, 0x22000010, 0x00000000, 0x03ca0000, - 0x0000000f, 0x65680010, 0x00000000, 0x0bcf0000, 0x00000000, 0x27f20000, - 0x00000010, 0xb7ef3203, 0x0000000c, 0x21420004, 0x0000000c, 0x73e70019, - 0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x8000007e, - 0x00000004, 0xb9723200, 0x00000010, 0x20530000, 0x00000000, 0x22060000, - 0x0000000c, 0x61420004, 0x00000000, 0x25070000, 0x00000000, 0x27970000, - 0x00000000, 0x290e0000, 0x00000010, 0x0ce70010, 0x00000010, 0xb873320f, - 0x0000000f, 0x436c0010, 0x00000000, 0x03f30c00, 0x00000000, 0x03f30000, - 0x00000000, 0x83990e00, 0x00000001, 0x83860e00, 0x00000000, 0x83060e00, - 0x00000003, 0xf66c0c00, 0x00000000, 0x39f30e00, 0x00000000, 0x3af50e00, - 0x00000000, 0x7a740000, 0x0000000f, 0x43680010, 0x00000001, 0x83860e00, - 0x00000000, 0x83060e00, 0x00000003, 0xf4680c00, 0x00000000, 0x286d0000, - 0x00000000, 0x03690000, 0x00000010, 0xb1f60c54, 0x00000000, 0x0a6a0000, - 0x00000000, 0x0aeb0000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0c000000, - 0x00000000, 0x0be90000, 0x00000003, 0x8cf6a000, 0x0000000c, 0x09800002, - 0x00000010, 0x009f0000, 0x00000010, 0xb8173209, 0x00000000, 0x35140000, - 0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34970000, - 0x00000004, 0xb8f12e00, 0x00000010, 0x001f0000, 0x00000008, 0x0f800004, - 0x00000018, 0x8000fff7, 0x00000000, 0x03e90000, 0x00000010, 0xb8f6a01a, - 0x00000010, 0x20130019, 0x00000010, 0xb1f10e18, 0x00000000, 0x83973200, - 0x00000000, 0x38700e00, 0x00000000, 0xbb760e00, 0x00000000, 0x37d00000, - 0x0000000c, 0x73e7001a, 0x00000003, 0xb8f1a000, 0x00000000, 0x32140000, - 0x00000000, 0x32950000, 0x00000005, 0x73e72c00, 0x00000000, 0x33190000, - 0x00000005, 0x74680000, 0x00000010, 0x0ce7000d, 0x00000008, 0x22000009, - 0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x0000000c, 0x73e70019, - 0x0000000f, 0x65680010, 0x0000000c, 0x21420004, 0x00000018, 0x8000003c, - 0x00000010, 0x20530000, 0x0000000c, 0x61420004, 0x00000000, 0x290e0000, - 0x00000018, 0x80000002, 0x00000010, 0x91973206, 0x00000000, 0x35140000, - 0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34990000, - 0x00000004, 0xb8f13200, 0x00000000, 0x83690c00, 0x00000010, 0xb1860013, - 0x00000000, 0x28e90000, 0x00000008, 0x22000004, 0x00000000, 0x23ec0000, - 0x00000000, 0x03690000, 0x00000010, 0xb8660c07, 0x00000009, 0x036cffff, - 0x00000000, 0x326a0000, 0x00000000, 0x32eb0000, 0x00000005, 0x73e70c00, - 0x00000000, 0x33690000, 0x00000005, 0x74680000, 0x0000000c, 0x73e7001c, - 0x00000000, 0x03690000, 0x00000010, 0xb1f60c12, 0x00000010, 0xb1d00c11, - 0x0000000c, 0x21420005, 0x0000000c, 0x33e7001c, 0x00000018, 0x8000000e, - 0x00000010, 0x2e67000d, 0x00000000, 0x03690000, 0x00000010, 0xb1f60c0b, - 0x00000010, 0xb1d00c0a, 0x00000000, 0x03440000, 0x00000008, 0x2200000c, - 0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x80000015, - 0x0000000c, 0x33e7001c, 0x00000010, 0x20530000, 0x00000000, 0x22060000, - 0x00000000, 0x290e0000, 0x00000018, 0x000d0000, 0x00000000, 0x06820000, - 0x00000010, 0x2de7000d, 0x00000010, 0x0ce7000c, 0x00000000, 0x27f20000, - 0x00000010, 0xb96d9e0a, 0x00000000, 0xa86d9e00, 0x00000009, 0x0361ffff, - 0x00000010, 0xb7500c07, 0x00000008, 0x2200000f, 0x0000000f, 0x65680010, - 0x00000000, 0x29000000, 0x00000018, 0x80000004, 0x0000000c, 0x33e7001b, - 0x00000010, 0x20530000, 0x00000018, 0x000d0000, 0x00000000, 0x2b820000, - 0x00000010, 0x20d2002f, 0x00000010, 0x0052002e, 0x00000009, 0x054e0007, - 0x00000010, 0xb18a002c, 0x00000000, 0x050a8c00, 0x00000008, 0x850a0008, - 0x00000010, 0x918a0029, 0x00000003, 0xc5008800, 0x00000008, 0xa3460001, - 0x00000010, 0xb1c60007, 0x00000008, 0x22000001, 0x0000000c, 0x29800000, - 0x00000010, 0x20530000, 0x00000000, 0x274e8c00, 0x00000000, 0x66cd0000, - 0x00000000, 0x22c58c00, 0x00000008, 0x22000014, 0x00000003, 0x22c58e00, - 0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00, - 0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000, - 0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x0000000c, 0x69520000, - 0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000003, 0x22c58e00, - 0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00, - 0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000, - 0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x00000000, 0xa2c58c00, - 0x00000000, 0xa74e8c00, 0x00000000, 0xe6cd0000, 0x0000000f, 0x620a0010, - 0x00000008, 0x23460001, 0x0000000c, 0x29800000, 0x00000010, 0x20530000, - 0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000, - 0x00000018, 0x00570000 }; +static u8 bnx2_rv2p_proc2[] = { + 0x1f, 0x8b, 0x08, 0x08, 0x7e, 0xd1, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xcd, 0x58, 0x5b, 0x6c, + 0x54, 0x55, 0x14, 0x3d, 0xf3, 0xe8, 0xcc, 0x9d, 0xe9, 0xed, 0x9d, 0xf2, + 0xb2, 0x03, 0xad, 0x08, 0xe5, 0xd1, 0x56, 0x29, 0xe8, 0x54, 0xab, 0x18, + 0x15, 0x2c, 0x5a, 0x8c, 0x26, 0x68, 0xf0, 0xf9, 0x63, 0x14, 0x04, 0xda, + 0x9a, 0x56, 0x9b, 0x16, 0xfb, 0x81, 0xaf, 0x09, 0x14, 0x6a, 0x4c, 0x25, + 0xd6, 0x08, 0xc5, 0x47, 0xa0, 0x11, 0x1f, 0x84, 0xf0, 0xd3, 0x1f, 0x3b, + 0x8d, 0x7f, 0x0a, 0x24, 0x6a, 0x88, 0xc4, 0xa8, 0x9f, 0x24, 0x68, 0xa0, + 0x21, 0x0a, 0x58, 0x8b, 0x63, 0x4c, 0xb4, 0xf5, 0xec, 0xbd, 0xf6, 0xb9, + 0x73, 0xef, 0x6d, 0x8b, 0x1a, 0xf9, 0x70, 0x3e, 0xba, 0x7b, 0xce, 0xd9, + 0x67, 0x3f, 0xd6, 0xde, 0x67, 0x9f, 0x7d, 0xae, 0x52, 0xfc, 0xbb, 0xb6, + 0x94, 0xc9, 0x37, 0x83, 0x96, 0xfe, 0x1b, 0x51, 0x0f, 0x85, 0xd3, 0x3c, + 0x8e, 0x2a, 0xa2, 0x49, 0xa5, 0xb2, 0x5e, 0xea, 0x08, 0x7d, 0x44, 0xe8, + 0x70, 0x08, 0xf4, 0xb4, 0xd0, 0x77, 0x84, 0xfe, 0x2e, 0xf4, 0x80, 0xd0, + 0x0f, 0x85, 0xea, 0x5f, 0xd6, 0xd6, 0x7f, 0xf4, 0xb0, 0x46, 0x89, 0x7e, + 0x1b, 0xd3, 0x35, 0xb0, 0xe3, 0xc1, 0x05, 0xc4, 0x77, 0x61, 0xa2, 0xc0, + 0x87, 0xf9, 0x53, 0x7d, 0xa0, 0xd7, 0x60, 0xd7, 0xe1, 0xec, 0x0a, 0xb3, + 0x1f, 0x64, 0x43, 0x09, 0xe8, 0xc6, 0x08, 0xe8, 0xea, 0x65, 0x4c, 0x7a, + 0x9f, 0x0a, 0x63, 0xdc, 0xb8, 0x94, 0xf6, 0x87, 0x55, 0x83, 0x22, 0x3f, + 0x67, 0xaa, 0x68, 0x98, 0xc6, 0xf5, 0x56, 0x6c, 0x18, 0xeb, 0x8f, 0xa5, + 0x40, 0x37, 0x25, 0x41, 0xcf, 0x08, 0xdd, 0x52, 0x2c, 0x7a, 0x6c, 0x31, + 0xbf, 0x98, 0xf6, 0x25, 0x5c, 0x39, 0xc7, 0x6d, 0xe0, 0x96, 0x95, 0xfd, + 0x4a, 0xc1, 0xce, 0x03, 0xb2, 0x3e, 0xa3, 0x0a, 0xb3, 0xaf, 0x6f, 0xc1, + 0xb8, 0xfc, 0x20, 0xf9, 0xa7, 0xff, 0xcf, 0x62, 0x7e, 0xfa, 0xfd, 0xf8, + 0x15, 0xf6, 0x83, 0x96, 0x2f, 0xa2, 0x75, 0x27, 0xd3, 0x3f, 0x88, 0xf1, + 0xde, 0x25, 0x32, 0x1f, 0x36, 0xf8, 0x18, 0x79, 0x41, 0x5c, 0x99, 0x58, + 0xc7, 0x2a, 0x7d, 0xf2, 0x2b, 0x15, 0xe4, 0x2f, 0xc8, 0x2e, 0x35, 0xf2, + 0x81, 0xfb, 0xfa, 0x16, 0xb2, 0x73, 0x4c, 0xc7, 0x01, 0xb8, 0xcd, 0x0a, + 0x95, 0xb2, 0xdc, 0x7d, 0x83, 0x5e, 0x3d, 0x51, 0xad, 0x07, 0xfa, 0x54, + 0xa5, 0xc5, 0x20, 0x65, 0x97, 0x81, 0xaa, 0x5a, 0xbf, 0x1f, 0x7b, 0x97, + 0x18, 0x7b, 0x30, 0x9e, 0x9d, 0x01, 0xdd, 0x23, 0xf4, 0xaa, 0x3a, 0x26, + 0xcb, 0x7f, 0xb8, 0xc1, 0x62, 0x0c, 0xb2, 0xb5, 0xde, 0x7c, 0x38, 0x32, + 0x61, 0xf0, 0x52, 0x8b, 0x40, 0xce, 0x2e, 0x21, 0x3e, 0x1d, 0x9c, 0x4a, + 0xc8, 0x5d, 0xdf, 0x32, 0x55, 0x1e, 0x7d, 0x30, 0x45, 0x1e, 0x61, 0xff, + 0xb7, 0x2b, 0x7c, 0xf9, 0xa4, 0xda, 0x25, 0x4f, 0x36, 0x22, 0x8f, 0xac, + 0xa7, 0x3e, 0x91, 0x85, 0x6b, 0x13, 0xfa, 0xcf, 0x84, 0x7a, 0x32, 0x4e, + 0x01, 0x8a, 0x2b, 0x87, 0xfd, 0x53, 0xe2, 0xe7, 0x26, 0xed, 0x27, 0xd1, + 0x8a, 0x50, 0xb6, 0x36, 0xc1, 0x38, 0x35, 0xc4, 0xa0, 0xaf, 0x61, 0x03, + 0xb6, 0xaf, 0x46, 0x5c, 0x7b, 0x4f, 0x86, 0x8d, 0xfd, 0x51, 0xfa, 0x3b, + 0xd0, 0xb6, 0x9d, 0x47, 0x03, 0xd1, 0x1d, 0x4c, 0xed, 0x63, 0x95, 0x58, + 0xee, 0x8a, 0xf0, 0x7a, 0x72, 0x97, 0xcc, 0xf7, 0xec, 0xf0, 0xdb, 0xfd, + 0x02, 0xf2, 0xdb, 0x7e, 0x7e, 0x47, 0x88, 0xa8, 0x13, 0x73, 0xf9, 0x98, + 0x3a, 0x3b, 0xb7, 0x13, 0xff, 0x55, 0x6a, 0xd7, 0x20, 0x29, 0x4e, 0xab, + 0x0d, 0x6b, 0xb1, 0x6f, 0x77, 0x2c, 0xc5, 0xb8, 0x36, 0xad, 0x05, 0xfd, + 0x1e, 0xf3, 0xf3, 0x9d, 0x1e, 0xe2, 0x2f, 0x9d, 0xe7, 0x0c, 0x71, 0x5e, + 0xa9, 0x11, 0xce, 0xc7, 0x04, 0x65, 0x06, 0xff, 0xda, 0xaa, 0xc1, 0xdf, + 0xbc, 0x99, 0x15, 0xbf, 0xd9, 0x9a, 0xe7, 0x3c, 0x18, 0xe8, 0x18, 0x26, + 0x3f, 0xe7, 0xaa, 0x91, 0x4e, 0xa2, 0x51, 0xd5, 0xb0, 0x90, 0xf0, 0x5e, + 0x15, 0x36, 0x71, 0x3a, 0x7f, 0x33, 0xcd, 0xcf, 0xd3, 0xeb, 0x26, 0x1e, + 0x24, 0xd7, 0x92, 0x78, 0x45, 0x5d, 0x7c, 0xf2, 0x61, 0xf8, 0xdb, 0xcd, + 0x76, 0x5f, 0x97, 0xec, 0xe6, 0xfc, 0x4a, 0xaa, 0x26, 0x8e, 0x7f, 0xd4, + 0x6a, 0x1b, 0xc6, 0xfa, 0xf9, 0x8f, 0x8d, 0x5c, 0xd2, 0x53, 0x23, 0x75, + 0x44, 0xb9, 0x72, 0xa2, 0x37, 0x83, 0xee, 0x34, 0x7a, 0xeb, 0x88, 0x6f, + 0xb1, 0x42, 0xfe, 0x26, 0x26, 0xc9, 0x69, 0x03, 0xce, 0xf6, 0x33, 0xec, + 0xf7, 0x35, 0xf6, 0x85, 0x3e, 0x63, 0x2f, 0xe6, 0x2f, 0xfa, 0xf4, 0x95, + 0x7b, 0xf4, 0x11, 0x7f, 0x51, 0xf2, 0x02, 0xef, 0x9b, 0x63, 0x3d, 0x3b, + 0xcc, 0xb8, 0x58, 0xcf, 0x0c, 0x41, 0xfe, 0xc5, 0x21, 0xe2, 0x9f, 0x23, + 0x7a, 0xed, 0xff, 0x88, 0xe7, 0x9c, 0x30, 0xe4, 0x4c, 0x8f, 0x5f, 0xc1, + 0x6f, 0xe3, 0x17, 0xcb, 0xb5, 0x47, 0x73, 0x69, 0xe6, 0x33, 0xf1, 0xe8, + 0x0e, 0x73, 0x02, 0xa6, 0x1b, 0x16, 0xfa, 0x71, 0x33, 0xf6, 0x9c, 0xdf, + 0xcc, 0x79, 0x3e, 0xd1, 0x26, 0x75, 0x40, 0x71, 0x9d, 0xb9, 0x5d, 0xe2, + 0xa1, 0xf3, 0x3a, 0x04, 0xff, 0x46, 0x73, 0x2c, 0x3f, 0xd9, 0xc5, 0x79, + 0xb9, 0xd2, 0x8e, 0xe6, 0x38, 0x5e, 0xd6, 0xd9, 0x21, 0x6c, 0x2b, 0xd4, + 0x4f, 0xc8, 0x6b, 0xb6, 0x41, 0x9b, 0xa4, 0x8e, 0x9e, 0x15, 0xda, 0x6d, + 0x33, 0x3e, 0xba, 0x8e, 0x59, 0x2c, 0x3f, 0x9b, 0x32, 0xf7, 0x0c, 0xd6, + 0x9f, 0x16, 0x39, 0x3f, 0x0a, 0x55, 0x22, 0xa7, 0x55, 0xf6, 0x9f, 0xf3, + 0xc9, 0x89, 0x04, 0xe4, 0x84, 0x94, 0xc1, 0xcd, 0x9c, 0xef, 0x5d, 0x52, + 0xbf, 0xf7, 0xc5, 0xa6, 0xab, 0xb7, 0x7c, 0x0e, 0xdc, 0xba, 0x5a, 0x8e, + 0x3a, 0x53, 0x1f, 0x0d, 0xb3, 0xbf, 0x03, 0xdd, 0x3b, 0x80, 0x53, 0x8f, + 0xe0, 0x14, 0x07, 0x4e, 0xf3, 0x0a, 0xf5, 0x59, 0x14, 0xd4, 0x90, 0xfe, + 0x53, 0x21, 0xe3, 0xc7, 0xbe, 0x98, 0xaf, 0xfe, 0xf6, 0x9a, 0xfa, 0x5b, + 0xa8, 0xd3, 0xc4, 0xff, 0xb3, 0xa9, 0x6f, 0x5a, 0x9f, 0xd1, 0xff, 0x6f, + 0xf5, 0x72, 0x9c, 0x92, 0xdd, 0x7d, 0x26, 0xce, 0x98, 0x2e, 0xd4, 0xd9, + 0x22, 0x22, 0xcb, 0x46, 0x3a, 0x99, 0x5e, 0xdf, 0xbc, 0x15, 0xf3, 0x65, + 0x7c, 0x4e, 0x6e, 0x09, 0x01, 0xaf, 0xa8, 0x3a, 0xde, 0x87, 0xba, 0xae, + 0xe2, 0x2c, 0xaf, 0xe2, 0x28, 0xc7, 0x3f, 0xaa, 0xe5, 0x12, 0xdf, 0x67, + 0xa1, 0x42, 0x3e, 0x7a, 0xfd, 0xd9, 0xad, 0xf3, 0x84, 0xec, 0x88, 0xe9, + 0xbc, 0xa5, 0xb1, 0x3e, 0x47, 0xb6, 0xe4, 0xf9, 0x1a, 0xe6, 0xb3, 0xc7, + 0x22, 0x34, 0xff, 0x80, 0xd5, 0xd3, 0x87, 0xf9, 0x9f, 0x1a, 0x69, 0xbc, + 0xce, 0x7e, 0x0d, 0xe7, 0xcc, 0x7e, 0x0d, 0xf5, 0xcb, 0x2a, 0x3a, 0x88, + 0xba, 0xd6, 0x78, 0x10, 0xf2, 0x71, 0x4f, 0x7b, 0xfd, 0xf2, 0xe2, 0x47, + 0xe7, 0xe1, 0xb2, 0x38, 0xd9, 0xcf, 0x09, 0x4e, 0x97, 0x7c, 0xf1, 0x39, + 0x6c, 0xe2, 0xd3, 0x1b, 0x93, 0xf3, 0xd2, 0x7c, 0x29, 0xe8, 0x17, 0xf1, + 0x9d, 0x71, 0xef, 0x9d, 0xae, 0x95, 0xa0, 0xdd, 0x2b, 0xe5, 0x9c, 0xd6, + 0xf9, 0xf3, 0x6b, 0x3e, 0xea, 0xf2, 0xb8, 0x7b, 0x4f, 0x20, 0xbf, 0xac, + 0x9d, 0xf0, 0x4b, 0xbd, 0x28, 0x79, 0x3c, 0x2e, 0xf4, 0x65, 0xc9, 0xdf, + 0x6d, 0xd2, 0xb7, 0x98, 0xfe, 0xe2, 0x0f, 0xcc, 0x3b, 0xfd, 0x6e, 0x5f, + 0x60, 0xea, 0x36, 0x8d, 0x43, 0xca, 0x89, 0x13, 0x83, 0x36, 0xeb, 0x33, + 0x24, 0x4a, 0xcf, 0x1a, 0xe0, 0x35, 0x52, 0x07, 0xbe, 0xdd, 0x91, 0xb0, + 0x8c, 0x21, 0x6f, 0xac, 0xda, 0x77, 0x0f, 0xd7, 0x4f, 0xc6, 0x93, 0xe4, + 0xc6, 0xdc, 0xfa, 0x24, 0x79, 0xaf, 0x26, 0x84, 0x96, 0x2f, 0xbe, 0x2c, + 0xbe, 0x85, 0xfe, 0x64, 0xa9, 0x17, 0xdf, 0x97, 0x34, 0xbe, 0xbc, 0xaf, + 0xbe, 0xf9, 0x12, 0xa6, 0x4b, 0x6f, 0x05, 0xed, 0xbb, 0x95, 0xe7, 0x17, + 0xa3, 0xee, 0x11, 0x7e, 0x9c, 0x5f, 0xf5, 0x6f, 0x0c, 0x9a, 0x7e, 0x42, + 0xf0, 0x08, 0xf4, 0x41, 0x65, 0x77, 0x80, 0xbe, 0x29, 0x74, 0xce, 0x2a, + 0xd0, 0xbd, 0xab, 0xfc, 0x71, 0x88, 0xa5, 0x7c, 0x71, 0xac, 0x47, 0x1c, + 0x8f, 0x4c, 0x04, 0xeb, 0x81, 0xc4, 0x4b, 0xc7, 0x27, 0x70, 0xbf, 0x1b, + 0xfd, 0xe2, 0xce, 0xdf, 0xc5, 0xed, 0x4a, 0xc7, 0xab, 0x7b, 0x25, 0xee, + 0x93, 0x0e, 0xe9, 0x4b, 0xc7, 0xdc, 0xfb, 0xe2, 0x9f, 0xc4, 0x31, 0x7e, + 0x85, 0xe3, 0x78, 0xf7, 0xff, 0x2c, 0x8e, 0x9d, 0x12, 0xc7, 0x22, 0xb9, + 0x57, 0x4d, 0xbf, 0xd9, 0x2e, 0x7d, 0x18, 0xf5, 0x8d, 0x7e, 0xbd, 0x4f, + 0x70, 0x1f, 0x78, 0xb5, 0x5b, 0x8f, 0xe7, 0x33, 0x7f, 0x4e, 0xf6, 0x95, + 0xca, 0xbe, 0x7b, 0x26, 0xed, 0x3b, 0xc5, 0xf5, 0xee, 0xf1, 0xf1, 0xc9, + 0xef, 0x15, 0x9f, 0x9d, 0x59, 0x95, 0x02, 0xee, 0xa8, 0xe3, 0xb1, 0x29, + 0xde, 0x37, 0x86, 0x1f, 0xf9, 0xb5, 0x36, 0x85, 0xba, 0x05, 0xfe, 0xb9, + 0x9e, 0x7a, 0x4a, 0xe3, 0xfb, 0xc7, 0xa7, 0xef, 0x57, 0x8d, 0x3c, 0xc4, + 0x6d, 0x43, 0xb8, 0x84, 0xf9, 0x4e, 0xb7, 0xf3, 0x7d, 0xe7, 0xfa, 0xb7, + 0x9a, 0xfd, 0x3a, 0x2a, 0xfe, 0x55, 0x88, 0x7f, 0x7a, 0xb9, 0x96, 0xeb, + 0xbe, 0x75, 0xba, 0xdd, 0xeb, 0xdf, 0x9d, 0x97, 0xd1, 0xf7, 0x4f, 0xfb, + 0x63, 0xd1, 0x9b, 0x32, 0xfa, 0x49, 0x5e, 0xb9, 0xf4, 0x7d, 0xd4, 0x4f, + 0x62, 0x7e, 0x72, 0x9f, 0x41, 0xfa, 0x5b, 0x34, 0x5e, 0x72, 0xdf, 0x70, + 0x3e, 0x47, 0xac, 0xa3, 0x6c, 0x57, 0x5e, 0xf9, 0x71, 0x39, 0x23, 0x7c, + 0x53, 0xc5, 0x8d, 0xd6, 0x8b, 0x64, 0x7d, 0x2a, 0xbf, 0xc5, 0x4e, 0x37, + 0x1f, 0x64, 0x1f, 0xf3, 0x35, 0x0b, 0x5f, 0x34, 0x34, 0x39, 0xfe, 0x18, + 0xe5, 0xab, 0x38, 0xaf, 0xf7, 0x6f, 0xcb, 0x11, 0x9f, 0x76, 0x9e, 0xf3, + 0xf0, 0xfb, 0x80, 0x7d, 0xe9, 0x2b, 0x80, 0x23, 0xf1, 0xcd, 0x50, 0x4d, + 0xce, 0x74, 0x78, 0xe1, 0xdd, 0x30, 0x9a, 0x33, 0x78, 0xdb, 0xec, 0xe7, + 0x48, 0x27, 0xe9, 0x5f, 0x1d, 0xc0, 0x31, 0x2c, 0x38, 0x9e, 0x50, 0x7f, + 0x9f, 0xf7, 0xc6, 0x0f, 0x6f, 0x5e, 0x8c, 0xff, 0x19, 0xcc, 0xe3, 0x87, + 0xe5, 0x5d, 0xdd, 0x18, 0x03, 0xfd, 0x2e, 0x62, 0xec, 0x46, 0x5e, 0xdf, + 0xc3, 0xe7, 0xb5, 0x4a, 0xf5, 0xf2, 0xbb, 0xc3, 0x52, 0x0d, 0x6b, 0xc9, + 0xee, 0x94, 0xae, 0x7f, 0xc8, 0x77, 0x27, 0xee, 0xbd, 0xb7, 0x75, 0x0d, + 0x4c, 0xc4, 0x69, 0x58, 0x31, 0x33, 0xc1, 0x82, 0xde, 0xf8, 0xe2, 0x4b, + 0x5e, 0x7e, 0xaf, 0xbf, 0x18, 0xf3, 0x65, 0xf7, 0x91, 0x9c, 0x88, 0xda, + 0x8b, 0xba, 0xfb, 0xee, 0x1e, 0xd0, 0xb7, 0xd5, 0xbd, 0xd8, 0x3f, 0x73, + 0x3b, 0xd7, 0x51, 0xab, 0x4c, 0xf2, 0x2b, 0x0d, 0x5c, 0xd3, 0xa8, 0xc3, + 0x13, 0x13, 0xaa, 0x04, 0xf7, 0x9a, 0x79, 0x07, 0xab, 0x1a, 0xd1, 0x8b, + 0xfa, 0x68, 0x17, 0xde, 0xc1, 0x44, 0x8b, 0x83, 0x7d, 0x9f, 0x55, 0xe8, + 0xaf, 0x08, 0x8f, 0xf7, 0x5d, 0x1c, 0xd3, 0xe1, 0x60, 0x5d, 0xf2, 0xfa, + 0x15, 0x93, 0x73, 0xfd, 0xab, 0xfb, 0x6e, 0xee, 0xe1, 0x7e, 0x2a, 0x19, + 0xac, 0xcb, 0x01, 0xf9, 0xfb, 0x24, 0x7e, 0x49, 0x89, 0x5f, 0x54, 0xc7, + 0x0f, 0xef, 0xed, 0x4f, 0x7d, 0xef, 0x7a, 0xaa, 0x1b, 0xde, 0xbc, 0xfb, + 0xfc, 0x4f, 0x63, 0xd7, 0xf6, 0x98, 0xb7, 0x0e, 0x57, 0xbb, 0xe7, 0xae, + 0x43, 0xde, 0x8b, 0x5d, 0x87, 0x30, 0xce, 0x73, 0xbf, 0xbc, 0x38, 0xd3, + 0x21, 0x79, 0x74, 0x57, 0x44, 0xf2, 0x41, 0xec, 0xfb, 0x22, 0x62, 0xee, + 0x1b, 0x8c, 0xbf, 0x92, 0xfb, 0xee, 0x97, 0x2a, 0xf4, 0xd9, 0x17, 0x87, + 0xcc, 0xfb, 0xc4, 0xbc, 0x57, 0xb0, 0xbe, 0x3e, 0xae, 0x04, 0x67, 0xbe, + 0xff, 0xb5, 0x3f, 0x9c, 0xaf, 0x99, 0x8e, 0x61, 0x1f, 0x5e, 0x2a, 0x16, + 0x78, 0xbf, 0xc4, 0xe5, 0xfb, 0x45, 0xbf, 0xe0, 0xe1, 0xf0, 0xf9, 0x29, + 0xd5, 0xf6, 0x13, 0x4d, 0x65, 0x3a, 0x73, 0xb0, 0xa7, 0xd5, 0xed, 0x23, + 0xc1, 0x27, 0xd4, 0x79, 0x4b, 0xde, 0xc1, 0xf2, 0x5e, 0xd6, 0xef, 0x61, + 0xf4, 0x73, 0xad, 0x79, 0x8c, 0xc7, 0xd0, 0xb7, 0x39, 0xbf, 0xca, 0xbd, + 0xb5, 0x75, 0x9b, 0xe9, 0x4b, 0xa7, 0xde, 0x67, 0xee, 0xb9, 0xb6, 0x6a, + 0xd0, 0x16, 0xee, 0x5b, 0x1f, 0xb2, 0xf3, 0x92, 0x1f, 0x85, 0x77, 0x89, + 0xff, 0x3d, 0x62, 0xfa, 0x85, 0x73, 0xc5, 0xb8, 0x67, 0xf3, 0xbd, 0x34, + 0xa1, 0xdf, 0x23, 0x09, 0x6f, 0x9e, 0x25, 0x32, 0x65, 0x82, 0xfb, 0xec, + 0x9b, 0x40, 0xf7, 0xdc, 0x84, 0xbe, 0xbc, 0xb5, 0x4b, 0x70, 0xb8, 0x91, + 0x71, 0x5b, 0x3e, 0x9a, 0x0b, 0x7e, 0x67, 0x21, 0x5c, 0x7f, 0x73, 0xfb, + 0xd1, 0x73, 0x6c, 0xd7, 0xbc, 0x81, 0x3c, 0xf3, 0xcd, 0x55, 0xb3, 0xf8, + 0xfc, 0xa6, 0x9d, 0x51, 0xd8, 0x99, 0xe9, 0x17, 0xbf, 0xda, 0x6f, 0x01, + 0xed, 0x92, 0x3a, 0x73, 0xd2, 0x7d, 0x97, 0xc3, 0x4e, 0x53, 0x4f, 0x26, + 0xbf, 0x13, 0x30, 0x9e, 0x5b, 0xc7, 0x63, 0xd5, 0xbc, 0x95, 0xe4, 0x97, + 0x4c, 0x7a, 0xcf, 0x16, 0xe2, 0x6e, 0xf2, 0xc1, 0xe4, 0x8f, 0xf7, 0x1d, + 0x7b, 0x9b, 0xa7, 0x5e, 0xfa, 0xe3, 0xef, 0x70, 0xbe, 0x84, 0x65, 0x3d, + 0x96, 0xe9, 0xef, 0xbb, 0x3c, 0x3e, 0x6f, 0x01, 0x9f, 0x8c, 0xd8, 0x6d, + 0xb7, 0xf0, 0x3b, 0x74, 0x96, 0xda, 0x25, 0xf1, 0x39, 0x57, 0x2d, 0x75, + 0x50, 0xec, 0xfb, 0x49, 0xfa, 0x1f, 0xc4, 0x31, 0x6e, 0x6f, 0xc9, 0x49, + 0xdc, 0x24, 0x8f, 0x9e, 0x16, 0xbf, 0x7f, 0x84, 0xdf, 0xb6, 0xf1, 0xbb, + 0xc5, 0xf5, 0xdb, 0xd4, 0x59, 0xaf, 0x9c, 0x99, 0x3a, 0x1f, 0xb8, 0x5e, + 0xdb, 0x27, 0xf9, 0xdd, 0x53, 0x24, 0xe7, 0xa1, 0x42, 0xbe, 0x3b, 0x38, + 0xe2, 0x4f, 0x89, 0x6a, 0x5a, 0xee, 0xdd, 0x57, 0x2c, 0xfb, 0x92, 0x7a, + 0x1f, 0xe6, 0x71, 0xfe, 0xec, 0x29, 0xf0, 0x34, 0xdf, 0x11, 0x8c, 0xdc, + 0xe0, 0x39, 0xf2, 0xe2, 0xc7, 0x37, 0x13, 0xff, 0x50, 0x07, 0x74, 0x9c, + 0x6a, 0xcd, 0xf7, 0x07, 0xcc, 0xe3, 0xfc, 0x26, 0xf7, 0xb7, 0xa1, 0xaf, + 0xdc, 0xdf, 0x76, 0x48, 0xfa, 0x08, 0xc1, 0xe5, 0x81, 0x21, 0xb2, 0x43, + 0xc7, 0xae, 0xd2, 0x7f, 0xfe, 0x61, 0x47, 0x54, 0xec, 0x28, 0xf7, 0xd8, + 0x11, 0xd0, 0x7b, 0x1d, 0xcd, 0xaf, 0x50, 0x5f, 0x73, 0x1e, 0x2e, 0x57, + 0xeb, 0x29, 0x47, 0xf4, 0xbd, 0xb0, 0xae, 0x88, 0xc6, 0xcb, 0xd4, 0xab, + 0xf0, 0xb7, 0x37, 0x59, 0x84, 0x3a, 0x96, 0xdc, 0x49, 0xf3, 0x35, 0xea, + 0xd5, 0x3e, 0x0e, 0xc4, 0x2b, 0xea, 0x18, 0xea, 0x73, 0xe3, 0x41, 0xb6, + 0x47, 0x1d, 0x1f, 0x34, 0xf5, 0x7a, 0xca, 0xef, 0x98, 0xbd, 0xeb, 0xa4, + 0x5e, 0x9c, 0xc0, 0x77, 0x51, 0xfd, 0x5e, 0x23, 0xfe, 0xd9, 0xe6, 0x3d, + 0xb8, 0xfb, 0x98, 0xa1, 0x8b, 0x7c, 0xe3, 0xfd, 0x27, 0x96, 0x0a, 0xad, + 0xf2, 0x8d, 0x07, 0xd6, 0x55, 0x09, 0xad, 0x36, 0xe3, 0xe9, 0xbe, 0x2b, + 0x5e, 0x29, 0xf9, 0x62, 0xf7, 0x7b, 0xe2, 0xcf, 0x47, 0xe2, 0xcf, 0x59, + 0xe0, 0x9f, 0xdc, 0x28, 0x78, 0x2c, 0x0a, 0xea, 0x17, 0xbb, 0xdc, 0x73, + 0x63, 0xd6, 0x11, 0x8f, 0x47, 0xd5, 0x5f, 0x3f, 0x97, 0x8f, 0x31, 0xd8, + 0x17, 0x00, 0x00, 0x00 }; static const int bnx2_TPAT_b06FwReleaseMajor = 0x1; static const int bnx2_TPAT_b06FwReleaseMinor = 0x0; @@ -2339,201 +1330,199 @@ static const u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0; static const int bnx2_TPAT_b06FwBssLen = 0x250; static const u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60; static const int bnx2_TPAT_b06FwSbssLen = 0x34; -static u32 bnx2_TPAT_b06FwText[(0x122c/4) + 1] = { - 0x0a000218, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20322e35, - 0x2e313100, 0x02050b01, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, - 0x24421a60, 0x3c030800, 0x24631cf0, 0xac400000, 0x0043202b, 0x1480fffd, - 0x24420004, 0x3c1d0800, 0x37bd2ffc, 0x03a0f021, 0x3c100800, 0x26100860, - 0x3c1c0800, 0x279c1a60, 0x0e000546, 0x00000000, 0x0000000d, 0x8f820010, - 0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140, - 0x8f820024, 0x30420001, 0x10400007, 0x3069ffff, 0x24020002, 0x2523fffe, - 0xa7420146, 0xa7430148, 0x0a000242, 0x3c020800, 0xa7400146, 0x3c020800, - 0x8c43083c, 0x1460000e, 0x24020f00, 0x8f820024, 0x30430020, 0x0003182b, - 0x00031823, 0x30650009, 0x30420c00, 0x24030400, 0x14430002, 0x34a40001, - 0x34a40005, 0xa744014a, 0x0a000264, 0x3c020800, 0x8f830014, 0x14620008, - 0x00000000, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023, 0x3042000d, - 0x0a000262, 0x34420005, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023, - 0x30420009, 0x34420001, 0xa742014a, 0x3c020800, 0x8c430820, 0x8f840024, - 0x3c020048, 0x00621825, 0x30840006, 0x24020002, 0x1082000d, 0x2c820003, - 0x50400005, 0x24020004, 0x10800012, 0x3c020001, 0x0a000284, 0x00000000, - 0x10820007, 0x24020006, 0x1482000f, 0x3c020111, 0x0a00027c, 0x00621025, - 0x0a00027b, 0x3c020101, 0x3c020011, 0x00621025, 0x24030001, 0xaf421000, - 0xaf830020, 0x0a000284, 0x00000000, 0x00621025, 0xaf421000, 0xaf800020, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f830020, 0x1060003f, - 0x3c048000, 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039, - 0x00000000, 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000, - 0x97421014, 0x14400031, 0x00000000, 0x97421008, 0x8f840010, 0x24420006, - 0x00024082, 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001, - 0x10400004, 0x00000000, 0x0000000d, 0x0a0002c3, 0x00081080, 0x5460000f, - 0x30a5ffff, 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b, - 0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fb, - 0x8ce20000, 0x0a0002c2, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b, - 0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000205, - 0x8ce20000, 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000, - 0x8c620830, 0x24420001, 0xac620830, 0x8f840018, 0x01202821, 0x24820008, - 0x30421fff, 0x24434000, 0x0343d821, 0x30a30007, 0xaf84000c, 0xaf820018, - 0xaf420084, 0x10600002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000, - 0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, - 0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000, - 0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x8f830024, 0x27bdffe0, - 0xafbf0018, 0xafb10014, 0x30620200, 0x14400004, 0xafb00010, 0x0000000d, - 0x00000000, 0x24000242, 0x00031a82, 0x30630003, 0x000310c0, 0x00431021, - 0x00021080, 0x00431021, 0x00021080, 0x3c030800, 0x24631aa0, 0x00438821, - 0x8e240000, 0x10800004, 0x00000000, 0x0000000d, 0x00000000, 0x2400024d, - 0x8f850010, 0x24020001, 0xae220000, 0x8ca70008, 0xa2200007, 0x8f620004, - 0x26300014, 0x02002021, 0x00021402, 0xa2220004, 0x304600ff, 0x24c60005, - 0x0e000673, 0x00063082, 0x8f620004, 0xa6220008, 0x8f430108, 0x3c021000, - 0x00621824, 0x10600008, 0x00000000, 0x97420104, 0x92230007, 0x2442ffec, - 0x3045ffff, 0x34630002, 0x0a000321, 0xa2230007, 0x97420104, 0x2442fff0, - 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x54400005, 0x92230007, - 0x92220007, 0x34420001, 0xa2220007, 0x92230007, 0x24020001, 0x10620009, - 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003, 0x1062000a, - 0x00000000, 0x0a000342, 0x00000000, 0x8f820010, 0x8c43000c, 0x3c04ffff, - 0x00641824, 0x00651825, 0x0a000342, 0xac43000c, 0x8f820010, 0x8c430010, - 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004, 0x3042ffff, - 0x24420002, 0x00021083, 0xa2220005, 0x304500ff, 0x8f820010, 0x3c04ffff, - 0x00052880, 0x00a22821, 0x8ca70000, 0x96220008, 0x97430104, 0x00e42024, - 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x92240005, 0x00041080, - 0x02021021, 0x90430000, 0x3c05fff6, 0x34a5ffff, 0x3063000f, 0x00832021, - 0xa2240006, 0x308200ff, 0x24420003, 0x00021080, 0x02021021, 0x8c460000, - 0x308300ff, 0x8f820010, 0x3c04ff3f, 0x00031880, 0x00c53824, 0x00621821, - 0xae26000c, 0xac67000c, 0x8e22000c, 0x92230006, 0x3484ffff, 0x00441024, - 0x24630003, 0x00031880, 0x02031821, 0x00e42024, 0xae22000c, 0xac640000, - 0x92220006, 0x24420004, 0x00021080, 0x02021021, 0x94470002, 0xac470000, - 0x92230006, 0x8f820010, 0x00031880, 0x00621821, 0x24020010, 0xac670010, - 0x24030002, 0xa7420140, 0xa7400142, 0xa7400144, 0xa7430146, 0x97420104, - 0x24030001, 0x2442fffe, 0xa7420148, 0xa743014a, 0x8f820024, 0x24030002, - 0x30440006, 0x1083000d, 0x2c820003, 0x10400005, 0x24020004, 0x10800011, - 0x3c020009, 0x0a0003a5, 0x00000000, 0x10820007, 0x24020006, 0x1482000d, - 0x3c020119, 0x0a00039f, 0x24030001, 0x0a00039e, 0x3c020109, 0x3c020019, - 0x24030001, 0xaf421000, 0xaf830020, 0x0a0003a5, 0x00000000, 0xaf421000, - 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x92220004, - 0x24030008, 0x8f840020, 0x24420002, 0x30420007, 0x00621823, 0x30630007, - 0x10800006, 0xae230010, 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd, - 0x00000000, 0x8f820018, 0xaf82000c, 0x24420010, 0x30421fff, 0xaf820018, - 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007, - 0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821, - 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030, - 0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021, - 0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008, - 0x27bd0020, 0x8f830024, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0x30620200, - 0x14400004, 0xafb00010, 0x0000000d, 0x00000000, 0x240002e4, 0x00031a82, - 0x30630003, 0x000310c0, 0x00431021, 0x00021080, 0x00431021, 0x00021080, - 0x3c030800, 0x24631aa0, 0x00438021, 0x8e040000, 0x14800004, 0x00000000, - 0x0000000d, 0x00000000, 0x240002e9, 0x8f620004, 0x04410008, 0x26050014, - 0x92020006, 0x8e03000c, 0x24420003, 0x00021080, 0x00a21021, 0xac430000, - 0xae000000, 0x92020005, 0x24420001, 0x00021080, 0x00a21021, 0x8c430000, - 0x3c040001, 0x00641821, 0xac430000, 0x92060004, 0x27710008, 0x02202021, - 0x24c60005, 0x0e000673, 0x00063082, 0x92040006, 0x3c057fff, 0x8f620004, - 0x00042080, 0x00912021, 0x8c830004, 0x34a5ffff, 0x00451024, 0x00621821, - 0xac830004, 0x92050005, 0x3c07ffff, 0x92040004, 0x00052880, 0x00b12821, - 0x8ca30000, 0x97420104, 0x96060008, 0x00671824, 0x00441021, 0x00461023, - 0x3042ffff, 0x00621825, 0xaca30000, 0x92030007, 0x24020001, 0x1062000a, - 0x28620002, 0x1440001d, 0x2402000a, 0x24020002, 0x10620019, 0x24020003, - 0x1062000e, 0x2402000a, 0x0a000447, 0x00000000, 0x92020004, 0x97430104, - 0x8e24000c, 0x00621821, 0x2463fff2, 0x3063ffff, 0x00872024, 0x00832025, - 0xae24000c, 0x0a000447, 0x2402000a, 0x92020004, 0x97430104, 0x8e240010, - 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025, 0xae240010, - 0x2402000a, 0xa7420140, 0x96030012, 0x8f840024, 0xa7430142, 0x92020004, - 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001, 0xa7430148, - 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005, 0x24020004, - 0x10800011, 0x3c020041, 0x0a00046c, 0x00000000, 0x10820007, 0x24020006, - 0x1482000d, 0x3c020151, 0x0a000466, 0x24030001, 0x0a000465, 0x3c020141, - 0x3c020051, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00046c, 0x00000000, - 0xaf421000, 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x8f820020, 0x8f840018, 0x10400006, 0x92030004, 0x3c058000, 0x8f421000, - 0x00451024, 0x1040fffd, 0x00000000, 0x2463000a, 0x30620007, 0x10400002, - 0x24620007, 0x304303f8, 0x00831021, 0x30421fff, 0xaf84000c, 0xaf820018, - 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007, - 0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821, - 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030, - 0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021, - 0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008, - 0x27bd0020, 0x8f620000, 0x97430104, 0x3c048000, 0x3045ffff, 0x3066ffff, - 0x8f420178, 0x00441024, 0x1440fffd, 0x2402000a, 0x30a30007, 0xa7420140, - 0x24020008, 0x00431023, 0x30420007, 0x24a3fffe, 0xa7420142, 0xa7430144, - 0xa7400146, 0xa7460148, 0x8f420108, 0x8f830024, 0x30420020, 0x0002102b, - 0x00021023, 0x30420009, 0x34420001, 0x30630006, 0xa742014a, 0x24020002, - 0x1062000d, 0x2c620003, 0x10400005, 0x24020004, 0x10600011, 0x3c020041, - 0x0a0004d6, 0x00000000, 0x10620007, 0x24020006, 0x1462000d, 0x3c020151, - 0x0a0004d0, 0x24030001, 0x0a0004cf, 0x3c020141, 0x3c020051, 0x24030001, - 0xaf421000, 0xaf830020, 0x0a0004d6, 0x00000000, 0xaf421000, 0xaf800020, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f820020, 0x24a30008, - 0x8f850018, 0x10400006, 0x30c6ffff, 0x3c048000, 0x8f421000, 0x00441024, - 0x1040fffd, 0x00000000, 0x3063ffff, 0x30620007, 0x10400002, 0x24620007, - 0x3043fff8, 0x00a31021, 0x30421fff, 0x24434000, 0x0343d821, 0x00c02021, - 0x30830007, 0xaf85000c, 0xaf820018, 0xaf420084, 0x10600002, 0x24820007, - 0x3044fff8, 0x8f820030, 0x8f850000, 0x00441821, 0xaf82001c, 0x0065102b, - 0xaf830030, 0x14400002, 0x00651023, 0xaf820030, 0x8f840030, 0x34028000, - 0x3c030800, 0x8c650834, 0x00821021, 0x03421821, 0xaf830010, 0xaf440080, - 0x10a00006, 0x2402000e, 0x9383002f, 0x14620004, 0x3c021000, 0x2402043f, - 0xa7420148, 0x3c021000, 0x03e00008, 0xaf420178, 0x8f820024, 0x30424000, - 0x10400005, 0x24020800, 0x0000000d, 0x00000000, 0x2400040e, 0x24020800, - 0xaf420178, 0x97440104, 0x3c030008, 0xaf430140, 0x8f820024, 0x30420001, - 0x10400006, 0x3085ffff, 0x24020002, 0x24a3fffe, 0xa7420146, 0x0a000526, - 0xa7430148, 0xa7400146, 0x8f840018, 0x2402000d, 0xa742014a, 0x24830008, - 0x30631fff, 0x24624000, 0x0342d821, 0x30a20007, 0xaf84000c, 0xaf830018, - 0xaf430084, 0x10400002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000, - 0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, - 0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000, - 0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x27bdffe8, 0x3c046008, - 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x375b4000, - 0x00431024, 0x3442380c, 0xac825000, 0x8f430008, 0x3c100800, 0x37428000, - 0x34630001, 0xaf430008, 0xaf820010, 0x3c02601c, 0xaf800018, 0xaf400080, - 0xaf400084, 0x8c450008, 0x3c036000, 0x8c620808, 0x3c040800, 0x3c030080, - 0xac830820, 0x3042fff0, 0x38420010, 0x2c420001, 0xaf850000, 0xaf820004, - 0x0e000658, 0x00000000, 0x8f420000, 0x30420001, 0x1040fffb, 0x00000000, - 0x8f430108, 0x8f440100, 0x30622000, 0xaf830024, 0xaf840014, 0x10400004, - 0x8e02082c, 0x24420001, 0x0a0005c6, 0xae02082c, 0x30620200, 0x14400003, - 0x24020f00, 0x14820027, 0x24020d00, 0x97420104, 0x1040001c, 0x30624000, - 0x14400005, 0x00000000, 0x0e00022f, 0x00000000, 0x0a0005bb, 0x00000000, - 0x8f620008, 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007, - 0x28620031, 0x1440002f, 0x24020040, 0x10620007, 0x00000000, 0x0a0005bb, - 0x00000000, 0x0e0002e8, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0003db, - 0x00000000, 0x0a0005bb, 0x00000000, 0x30620040, 0x1440002b, 0x00000000, - 0x0000000d, 0x00000000, 0x240004b2, 0x0a0005c6, 0x00000000, 0x1482000f, - 0x30620006, 0x97420104, 0x10400005, 0x30620040, 0x0e000510, 0x00000000, - 0x0a0005bb, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d, 0x00000000, - 0x240004c4, 0x0a0005c6, 0x00000000, 0x1040000e, 0x30621000, 0x10400005, - 0x00000000, 0x0e000688, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0004a1, - 0x00000000, 0x8f82002c, 0x24420001, 0xaf82002c, 0x0a0005c6, 0x00000000, - 0x30620040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000, 0x240004db, - 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a000566, 0x00000000, - 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000, 0x00621824, - 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c, 0x34420001, - 0xaf420008, 0x37428000, 0xaf800018, 0xaf820010, 0xaf400080, 0xaf400084, - 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0, - 0x38420010, 0x2c420001, 0xaf860000, 0xaf820004, 0x03e00008, 0x00000000, - 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8, 0x8f820018, - 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf82000c, 0xaf830018, - 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, - 0x3044fff8, 0x8f820030, 0x8f830000, 0x00442021, 0xaf82001c, 0x0083102b, - 0xaf840030, 0x14400002, 0x00831023, 0xaf820030, 0x8f820030, 0x34038000, - 0x00431821, 0x03432021, 0xaf840010, 0x03e00008, 0xaf420080, 0x8f830024, - 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005, 0x24020004, - 0x10600012, 0x3c020001, 0x0a00062a, 0x00000000, 0x10620007, 0x24020006, - 0x1462000f, 0x3c020111, 0x0a000622, 0x00821025, 0x0a000621, 0x3c020101, - 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00062a, - 0x00000000, 0x00821025, 0xaf421000, 0xaf800020, 0x00000000, 0x00000000, - 0x00000000, 0x03e00008, 0x00000000, 0x8f820020, 0x10400005, 0x3c038000, - 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008, 0x00000000, - 0x8f820024, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010, 0x0e00022f, - 0x00000000, 0x0a000656, 0x8fbf0010, 0x8f620008, 0x8f630000, 0x24020030, - 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d, 0x8fbf0010, - 0x24020040, 0x10620007, 0x00000000, 0x0a000656, 0x00000000, 0x0e0002e8, - 0x00000000, 0x0a000656, 0x8fbf0010, 0x0e0003db, 0x00000000, 0x8fbf0010, - 0x03e00008, 0x27bd0018, 0x8f840028, 0x1080000f, 0x3c026000, 0x8c430c3c, - 0x30630fff, 0xaf830008, 0x14600011, 0x3082000f, 0x10400005, 0x308200f0, - 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d, 0x00000000, - 0x2400051a, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000, 0x2400051f, - 0x03e00008, 0x00000000, 0xaf830028, 0x03e00008, 0x00000000, 0x10c00007, - 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb, - 0x24840004, 0x03e00008, 0x00000000, 0x0a000684, 0x00a01021, 0xac860000, - 0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff, - 0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x00000000}; +static u8 bnx2_TPAT_b06FwText[] = { + 0x1f, 0x8b, 0x08, 0x08, 0x47, 0xd2, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xc5, 0x57, 0x4d, 0x68, + 0x1c, 0xe7, 0x19, 0x7e, 0xe7, 0x77, 0x47, 0x62, 0x25, 0x8d, 0x93, 0x3d, + 0xac, 0x5d, 0xa5, 0x99, 0x91, 0x46, 0x3f, 0x54, 0x26, 0x9e, 0x84, 0xa5, + 0x56, 0x61, 0x20, 0xe3, 0x99, 0x95, 0x2c, 0x0c, 0x05, 0x07, 0x42, 0x08, + 0xe4, 0xb2, 0x1d, 0x49, 0x36, 0x85, 0x1e, 0x5a, 0x9a, 0x43, 0xa0, 0x05, + 0x0f, 0x33, 0xeb, 0x34, 0x87, 0xc5, 0xdb, 0xaa, 0xc5, 0xbe, 0x94, 0xd6, + 0x95, 0xea, 0xe8, 0xb2, 0x68, 0xe2, 0x53, 0x0f, 0xc5, 0xd8, 0xb4, 0x54, + 0xd0, 0x53, 0x7b, 0x0a, 0x85, 0x5c, 0x4c, 0x69, 0x20, 0x85, 0x12, 0x44, + 0x0f, 0x21, 0xd4, 0xad, 0xa7, 0xcf, 0xfb, 0xcd, 0x8c, 0xbc, 0xbb, 0x95, + 0x5b, 0x1f, 0x02, 0x15, 0xac, 0x66, 0xe6, 0xfb, 0xde, 0xf7, 0xfb, 0x79, + 0x9f, 0xe7, 0x79, 0xbf, 0xf7, 0x6b, 0xca, 0x34, 0x49, 0xe5, 0xdf, 0x14, + 0x7e, 0x6f, 0x7f, 0xe3, 0xdb, 0x6f, 0x7f, 0xf5, 0xa5, 0x57, 0x2c, 0xa2, + 0x57, 0x5e, 0x92, 0x64, 0x5d, 0xa6, 0x2f, 0xe0, 0x4f, 0x21, 0x32, 0xab, + 0xf1, 0xf9, 0x47, 0x86, 0xec, 0x75, 0xce, 0x04, 0x0e, 0x19, 0x8a, 0x77, + 0x34, 0xbb, 0xe9, 0x10, 0xf9, 0x83, 0x15, 0x2b, 0xa4, 0x7f, 0xe5, 0x71, + 0x43, 0x25, 0x6e, 0x7f, 0xc1, 0xfb, 0xe7, 0xb9, 0x7b, 0xe7, 0xed, 0xa3, + 0xdb, 0x0a, 0x19, 0xa6, 0xd7, 0x31, 0xcc, 0x45, 0x32, 0x66, 0xe1, 0xf3, + 0xd3, 0xa5, 0x75, 0x8d, 0xa6, 0xab, 0xb1, 0x4c, 0x4a, 0xfa, 0x06, 0xad, + 0xf5, 0x30, 0x8e, 0xf3, 0x8e, 0x14, 0x66, 0xaa, 0x14, 0xde, 0x32, 0x48, + 0xf6, 0x7c, 0x29, 0xc8, 0x1c, 0xf4, 0x49, 0x14, 0xb8, 0x35, 0xf2, 0xcd, + 0x3c, 0xff, 0xa6, 0x2b, 0x93, 0xec, 0x3c, 0xce, 0xe7, 0x17, 0xd6, 0xa5, + 0x60, 0x7f, 0x43, 0x0a, 0xf7, 0x03, 0xde, 0x37, 0xd6, 0xb1, 0x2e, 0xf9, + 0xfb, 0xfc, 0xf4, 0x8c, 0xb0, 0x37, 0x4d, 0x9d, 0x06, 0xcd, 0xc8, 0x0e, + 0xfb, 0x5a, 0x14, 0xba, 0x2b, 0x4d, 0x85, 0xe6, 0xf1, 0x9b, 0xa0, 0x6d, + 0x97, 0xea, 0x81, 0x4b, 0xaa, 0xe2, 0xc8, 0x14, 0x36, 0x24, 0xfa, 0x65, + 0x4b, 0xc3, 0xef, 0x92, 0xd4, 0xde, 0xdf, 0x2a, 0xc7, 0x69, 0x50, 0x8a, + 0xb5, 0x44, 0x0d, 0x5e, 0x5b, 0xe1, 0x1f, 0xb8, 0x2b, 0xa6, 0x4c, 0xf3, + 0xf8, 0x4d, 0xe1, 0x3d, 0x82, 0x9d, 0x46, 0x41, 0x6b, 0xbc, 0x6f, 0x02, + 0xef, 0x58, 0x27, 0xc6, 0x0a, 0xc4, 0x3a, 0x2c, 0xac, 0xc3, 0xa1, 0x6e, + 0x7f, 0x03, 0xfb, 0x58, 0x68, 0x46, 0xa4, 0x53, 0x57, 0xac, 0x7d, 0x8a, + 0x12, 0x53, 0xa1, 0xe4, 0xac, 0x46, 0xfe, 0x65, 0x15, 0xdf, 0xcf, 0x51, + 0x6c, 0x4a, 0xb0, 0xe9, 0x96, 0xf8, 0xd5, 0xd0, 0xaf, 0xa3, 0x7d, 0x86, + 0x92, 0xc6, 0x29, 0x49, 0xf6, 0xbe, 0x8f, 0xf6, 0x05, 0x33, 0xa2, 0xef, + 0xe1, 0x29, 0xe1, 0xfb, 0x14, 0x8f, 0x87, 0x6f, 0x89, 0x14, 0x87, 0xcc, + 0x20, 0xb3, 0x28, 0xcd, 0x2a, 0x5f, 0x6e, 0x2f, 0xda, 0xe2, 0x6c, 0x1c, + 0x3b, 0xd8, 0xf5, 0x5f, 0xa5, 0x8e, 0x49, 0xb1, 0xea, 0xc1, 0xa6, 0xef, + 0x98, 0x6d, 0xe0, 0xe4, 0x0b, 0x3c, 0xbf, 0xc6, 0xed, 0xfc, 0x87, 0x76, + 0x8b, 0x14, 0xcf, 0x31, 0x43, 0x6a, 0x51, 0xd1, 0xd7, 0x30, 0x83, 0x5b, + 0x2f, 0x93, 0x2f, 0xe2, 0x61, 0xe0, 0xdd, 0xc4, 0x9e, 0x74, 0x60, 0x9b, + 0xf8, 0x32, 0xc5, 0x4d, 0x83, 0xec, 0xd5, 0x2d, 0xf4, 0x7c, 0xdc, 0x53, + 0x10, 0x67, 0xc6, 0x49, 0x2d, 0xfd, 0x18, 0xd7, 0xdf, 0x62, 0x5d, 0xb1, + 0x69, 0xd0, 0x0c, 0x75, 0x5e, 0xcf, 0xf3, 0x3b, 0x6e, 0x9e, 0xeb, 0x9e, + 0xb3, 0xfc, 0x3e, 0xad, 0x34, 0x35, 0x5a, 0x34, 0xf1, 0x44, 0xdc, 0x1c, + 0xc4, 0x46, 0x2d, 0xe7, 0x9f, 0x2a, 0xd7, 0xfa, 0x48, 0x42, 0xe8, 0xe9, + 0xcf, 0xbd, 0xdf, 0xf0, 0xde, 0x97, 0xd7, 0x85, 0x7d, 0x9e, 0xef, 0xae, + 0x3e, 0xcd, 0x5e, 0x93, 0x0b, 0xfb, 0x3c, 0x5f, 0x6b, 0xf1, 0x7c, 0x36, + 0xf6, 0xc6, 0x9c, 0x24, 0x5a, 0x1b, 0xb8, 0x46, 0xd4, 0xc3, 0xba, 0x1c, + 0x3c, 0x07, 0x4d, 0xac, 0xdd, 0x5e, 0xb6, 0x24, 0x83, 0x12, 0x27, 0x7f, + 0x11, 0x3c, 0xf0, 0x43, 0xc7, 0xfe, 0x53, 0xa8, 0xd4, 0x68, 0xcf, 0xad, + 0x53, 0x37, 0x6b, 0x52, 0x92, 0x75, 0x29, 0xc8, 0x64, 0x8c, 0x5f, 0xa3, + 0x5d, 0xe7, 0xf3, 0x7c, 0xcd, 0x75, 0x81, 0x33, 0xb1, 0x5f, 0x73, 0x8d, + 0x66, 0xd1, 0xbf, 0x62, 0x6e, 0x91, 0x8b, 0x98, 0xcb, 0x88, 0xc9, 0xbc, + 0x78, 0x4f, 0x32, 0x17, 0xfd, 0x14, 0xcb, 0x2d, 0xdb, 0x4c, 0xc8, 0x6e, + 0x06, 0x0a, 0x99, 0xb2, 0x67, 0xc2, 0x26, 0xa6, 0x76, 0x66, 0xd0, 0x43, + 0xe5, 0x1d, 0xc1, 0xe3, 0xb4, 0xff, 0x30, 0xbf, 0xb7, 0xd4, 0xa4, 0xfb, + 0x59, 0x83, 0xee, 0x66, 0x24, 0x47, 0x1c, 0xab, 0x86, 0x49, 0x1f, 0x64, + 0xd5, 0x3e, 0xc0, 0x65, 0x27, 0x39, 0xa3, 0x40, 0x67, 0x9b, 0xee, 0x03, + 0xb0, 0xc4, 0x06, 0x0e, 0x31, 0xf6, 0x5c, 0x3d, 0x79, 0x4f, 0xb7, 0xcf, + 0x6c, 0x3a, 0xf6, 0x7b, 0x21, 0xb3, 0xf3, 0x86, 0x8a, 0xd6, 0xe1, 0x38, + 0x7c, 0x1d, 0xfe, 0x26, 0x5d, 0x87, 0x5e, 0x64, 0xc4, 0x63, 0xee, 0xc0, + 0xa0, 0xfd, 0x5e, 0x8d, 0xac, 0x5d, 0x95, 0xa2, 0x7e, 0x83, 0xdc, 0x45, + 0xdb, 0x22, 0x59, 0x6e, 0xc8, 0x88, 0xdf, 0xdc, 0x6e, 0x4e, 0xeb, 0xae, + 0x46, 0x87, 0xce, 0x77, 0x75, 0x9a, 0x4e, 0x5c, 0x9d, 0xd8, 0xc6, 0xa0, + 0xb9, 0xf7, 0x0d, 0x29, 0xec, 0xf3, 0xfa, 0x39, 0xce, 0x46, 0x19, 0x67, + 0x55, 0x0a, 0x6e, 0xd5, 0x68, 0x7e, 0xe7, 0x6f, 0x79, 0xe0, 0x20, 0xc6, + 0xe0, 0xf1, 0x66, 0xcb, 0x56, 0x68, 0x12, 0x6d, 0xbb, 0xdc, 0x77, 0x54, + 0xb6, 0xf3, 0x18, 0x79, 0x1e, 0xb8, 0xcf, 0x53, 0xc0, 0xfc, 0x7e, 0x9d, + 0x7d, 0x6a, 0x34, 0xb7, 0xc3, 0xba, 0xc0, 0x73, 0x97, 0xbf, 0x79, 0x6d, + 0x13, 0x14, 0x61, 0x37, 0xd1, 0x72, 0x03, 0xfb, 0x97, 0x85, 0x06, 0x22, + 0xec, 0x56, 0x76, 0x26, 0xf1, 0x14, 0x71, 0x50, 0x0a, 0x3e, 0x73, 0x5e, + 0xa8, 0x53, 0x08, 0x5c, 0x55, 0xac, 0x67, 0x8b, 0x16, 0x9a, 0xdb, 0xa2, + 0x0f, 0x6d, 0x03, 0xee, 0x33, 0xc7, 0xfa, 0xf0, 0x3d, 0xa8, 0xd6, 0x20, + 0x03, 0xf3, 0x14, 0xb3, 0x68, 0x62, 0xaf, 0x6b, 0x2e, 0xdb, 0xb3, 0x6d, + 0xbc, 0xac, 0x91, 0xbd, 0xbc, 0x8b, 0xd1, 0xf7, 0x7b, 0xd8, 0xef, 0x4d, + 0xce, 0x35, 0x8e, 0xf5, 0x17, 0x62, 0xfb, 0x79, 0xec, 0x79, 0x61, 0x35, + 0xe5, 0xbe, 0x81, 0x46, 0xce, 0x4e, 0x6c, 0xaa, 0x88, 0xbd, 0x8c, 0xc0, + 0x87, 0x3f, 0xfc, 0x2c, 0xd7, 0x3c, 0x70, 0xb8, 0x35, 0x03, 0x6c, 0x6c, + 0x2b, 0x85, 0x9e, 0x1d, 0x8c, 0x9b, 0xb8, 0x0a, 0xfc, 0x0a, 0x8c, 0xd8, + 0x6e, 0xbd, 0x97, 0x53, 0x2a, 0xe6, 0xba, 0xc6, 0x73, 0x21, 0xe7, 0x38, + 0xab, 0xbf, 0x03, 0x27, 0x22, 0xaa, 0xd3, 0xe2, 0x41, 0x9d, 0xae, 0x0e, + 0xea, 0x34, 0x77, 0x43, 0x47, 0x1c, 0xf2, 0xbc, 0xdb, 0x62, 0x0d, 0x02, + 0x6b, 0x87, 0xed, 0xec, 0xa6, 0x22, 0xf3, 0x3a, 0xd0, 0x7f, 0x40, 0xb4, + 0x35, 0xd0, 0x11, 0x37, 0x75, 0x68, 0x6c, 0x99, 0x2e, 0xfe, 0x84, 0xe8, + 0xe2, 0x80, 0x7d, 0x79, 0xfc, 0xc2, 0x27, 0xc2, 0x9e, 0x65, 0x60, 0x7e, + 0x75, 0x20, 0x23, 0x1f, 0x20, 0x5f, 0xee, 0x07, 0xc8, 0x83, 0x6d, 0xfc, + 0xd6, 0x91, 0x1b, 0x19, 0x1b, 0xce, 0x13, 0x8f, 0x81, 0xcf, 0x06, 0xfa, + 0x2e, 0xa1, 0x8d, 0xf3, 0x16, 0xdb, 0xea, 0xd4, 0x76, 0xa7, 0x28, 0xad, + 0x72, 0x91, 0xc9, 0xb9, 0xe8, 0x14, 0xf8, 0x34, 0x81, 0xfc, 0x72, 0x47, + 0x19, 0xcd, 0x45, 0xc8, 0x59, 0x8d, 0xd3, 0xc8, 0x3d, 0x3f, 0x47, 0x3b, + 0x8f, 0xf7, 0x33, 0x3c, 0x27, 0xf0, 0x7d, 0x1a, 0xb6, 0xc3, 0x79, 0xa8, + 0xf2, 0x7b, 0x5a, 0x0e, 0x02, 0xef, 0x76, 0x0c, 0xd8, 0x5b, 0xd0, 0x0b, + 0xc7, 0xbb, 0x86, 0x7c, 0xc1, 0x31, 0xaf, 0x21, 0xa6, 0x3a, 0xe6, 0x36, + 0x69, 0xfe, 0x80, 0x62, 0xa5, 0xcc, 0x4f, 0xe1, 0x71, 0x7e, 0x6a, 0x0a, + 0x1e, 0x24, 0x99, 0x09, 0x1f, 0xd6, 0x6d, 0xa5, 0x53, 0xc6, 0x8e, 0xfc, + 0x00, 0x1a, 0x0e, 0x94, 0x3c, 0xdf, 0xc4, 0x19, 0x11, 0x01, 0x77, 0x1f, + 0xda, 0x8d, 0xa0, 0xdd, 0x70, 0x48, 0xbb, 0xe1, 0xff, 0xd4, 0x2e, 0x74, + 0x09, 0x8d, 0xdc, 0x05, 0xa7, 0x3e, 0xe8, 0x9f, 0xa4, 0x63, 0xd6, 0x30, + 0x6b, 0xd9, 0xa2, 0x7b, 0x4b, 0xcf, 0xa2, 0xe5, 0xbf, 0x3e, 0xab, 0x96, + 0x63, 0xd6, 0xb2, 0xca, 0x5a, 0x6e, 0x0c, 0x6b, 0xf9, 0x53, 0xf8, 0x17, + 0x9a, 0xbc, 0xa0, 0x36, 0x48, 0x5b, 0x04, 0x0e, 0x3b, 0x75, 0x52, 0x6e, + 0x3c, 0xe1, 0x1b, 0x73, 0x38, 0x1c, 0xe0, 0xdf, 0x81, 0x86, 0x3e, 0x69, + 0xb4, 0x1d, 0x39, 0x4f, 0xf5, 0xec, 0xe6, 0x96, 0xb0, 0x51, 0x49, 0x47, + 0xdc, 0xbf, 0xb3, 0x64, 0x5b, 0x96, 0x3c, 0xac, 0x79, 0xa8, 0x7e, 0x27, + 0xbf, 0xa6, 0x79, 0x3c, 0x4f, 0x6c, 0x81, 0xeb, 0xd6, 0x8f, 0x80, 0x51, + 0xda, 0x63, 0x9e, 0x3b, 0xe6, 0x9a, 0xe0, 0x17, 0xbe, 0xa1, 0x05, 0x0d, + 0x7c, 0xad, 0xc1, 0x4e, 0xdd, 0x29, 0xf4, 0x73, 0x17, 0xe3, 0xee, 0xf5, + 0x98, 0x5f, 0x06, 0xe9, 0x37, 0x9d, 0xe6, 0x55, 0x91, 0x73, 0xe7, 0xcd, + 0x75, 0x62, 0xed, 0xf1, 0x79, 0x87, 0xfe, 0x41, 0x8d, 0x14, 0xa1, 0xf7, + 0xc9, 0x52, 0xef, 0x2f, 0x20, 0x46, 0x93, 0xf8, 0x66, 0xcd, 0x9f, 0x2e, + 0x35, 0x3f, 0x8d, 0x27, 0xb7, 0x5d, 0x54, 0x0b, 0xee, 0x80, 0x87, 0x3b, + 0x8c, 0x6b, 0x1d, 0xf9, 0x8d, 0xe7, 0xff, 0x7b, 0xbe, 0xe9, 0x30, 0xb6, + 0x8e, 0xf5, 0x03, 0x5a, 0x80, 0xee, 0xd0, 0x7e, 0xc0, 0xb6, 0xec, 0x53, + 0xd9, 0x9a, 0xa5, 0xed, 0xa7, 0x63, 0xb6, 0x68, 0x3f, 0x60, 0x3b, 0xd6, + 0xc5, 0x73, 0xa4, 0xdc, 0xe4, 0xf3, 0x38, 0x60, 0x5d, 0xc0, 0xaf, 0x8d, + 0x36, 0xae, 0x19, 0xd8, 0x9f, 0xcf, 0x66, 0x5e, 0x27, 0xd7, 0x13, 0x7c, + 0x7e, 0x8f, 0x9d, 0xd3, 0xc7, 0xda, 0xb8, 0x00, 0xbe, 0x7f, 0x4b, 0xfd, + 0x4f, 0x6d, 0xbc, 0x06, 0x2d, 0x5c, 0x51, 0x0b, 0x6d, 0x6c, 0xe3, 0x79, + 0x01, 0xdf, 0xaf, 0x8d, 0x69, 0xa3, 0xf2, 0x7b, 0xfa, 0xf9, 0x9c, 0xf4, + 0x9b, 0xe2, 0x6c, 0xe5, 0xf9, 0x94, 0x1d, 0x8a, 0xb5, 0x52, 0x07, 0x6b, + 0xc7, 0x3a, 0x98, 0x44, 0xae, 0x18, 0xe1, 0xb8, 0x12, 0xba, 0xb6, 0x99, + 0x12, 0x6b, 0x62, 0xf8, 0xfc, 0xfa, 0x7f, 0xe9, 0x82, 0xc0, 0x23, 0x31, + 0x37, 0x6a, 0x0c, 0x3e, 0x0f, 0xf2, 0xfc, 0x8a, 0x8b, 0xfe, 0xaa, 0xd6, + 0x10, 0xd8, 0xf3, 0x59, 0xcb, 0x78, 0xa0, 0xbe, 0x73, 0xe6, 0xa1, 0x05, + 0xce, 0x01, 0x8f, 0xf3, 0x3d, 0x27, 0x40, 0x5b, 0x1b, 0xf1, 0x67, 0x4c, + 0x36, 0xa4, 0xf5, 0x7d, 0x83, 0xfd, 0xa0, 0xb3, 0x93, 0x6a, 0x2c, 0x1d, + 0x9a, 0x7a, 0x82, 0x13, 0xf3, 0x28, 0x1a, 0xc2, 0xa9, 0x23, 0x70, 0xfa, + 0xf0, 0x18, 0xa7, 0xa8, 0xc4, 0x29, 0x12, 0x38, 0xfd, 0xb1, 0xc4, 0xe9, + 0x0f, 0x4f, 0xc1, 0xe9, 0xc3, 0x67, 0xc0, 0xc9, 0xa0, 0x3d, 0xa7, 0x89, + 0x73, 0x56, 0x17, 0x35, 0xe9, 0xa1, 0x7b, 0x52, 0x4d, 0x75, 0x52, 0xdc, + 0x6d, 0x73, 0x8f, 0x86, 0xeb, 0x0e, 0xdb, 0x7a, 0x80, 0xf5, 0xa5, 0xc0, + 0xee, 0xfa, 0x58, 0xed, 0x91, 0xc0, 0xbe, 0x5d, 0xe2, 0x74, 0x1d, 0x38, + 0xb5, 0x4b, 0x9c, 0xb6, 0x87, 0x70, 0xda, 0x1e, 0xc1, 0x89, 0xf3, 0x49, + 0xcb, 0xd8, 0xee, 0x55, 0x18, 0x55, 0xf8, 0xe8, 0x74, 0xdb, 0x9c, 0xc6, + 0xfe, 0xcf, 0x51, 0xfa, 0x63, 0x95, 0xeb, 0x5a, 0x60, 0xf7, 0xaa, 0x2a, + 0x8b, 0xf3, 0x80, 0xdf, 0x9f, 0xd4, 0x27, 0x98, 0xcb, 0x0f, 0x5c, 0x8e, + 0x23, 0xea, 0x57, 0xa7, 0xca, 0x43, 0xcf, 0xab, 0xa8, 0xad, 0xf0, 0xcd, + 0x36, 0xaa, 0xd4, 0x86, 0xde, 0x15, 0xd4, 0xe5, 0xe1, 0x71, 0x5d, 0x5e, + 0xc4, 0xe0, 0x7a, 0x59, 0x97, 0xef, 0x39, 0x5c, 0x97, 0x2f, 0x6a, 0x34, + 0xb9, 0x51, 0x62, 0xc9, 0x9c, 0x9e, 0x42, 0xdf, 0x25, 0x81, 0x79, 0x8a, + 0xfc, 0xbd, 0x89, 0xfd, 0x47, 0x82, 0x9b, 0xa8, 0xb1, 0x4a, 0xde, 0xa2, + 0x86, 0xa5, 0x30, 0x2b, 0x62, 0xf5, 0xc5, 0xd6, 0x5d, 0x9f, 0x20, 0x4f, + 0x1b, 0x1d, 0x15, 0x75, 0xfd, 0xfd, 0x8c, 0xf3, 0x33, 0x5d, 0x4e, 0x7a, + 0x14, 0x9f, 0xf1, 0xae, 0xe5, 0xc0, 0xdc, 0x7f, 0xeb, 0x3c, 0x9f, 0x33, + 0xf5, 0xd5, 0xa0, 0x85, 0xf6, 0x81, 0x41, 0xa8, 0x7d, 0x70, 0x4f, 0xa1, + 0x38, 0x38, 0x2f, 0xa1, 0xc6, 0xc1, 0x37, 0x7c, 0x92, 0x6c, 0xb6, 0x23, + 0x7b, 0x4d, 0x70, 0x21, 0x26, 0x1f, 0xeb, 0xf4, 0x33, 0x71, 0x57, 0xe9, + 0x28, 0x9e, 0x81, 0xda, 0x92, 0x0c, 0x9c, 0xf3, 0x88, 0x89, 0x65, 0xa4, + 0x03, 0xd4, 0x41, 0x38, 0xfb, 0x83, 0x55, 0xc4, 0xe5, 0x2c, 0x70, 0xcb, + 0x54, 0xf8, 0xbe, 0xa9, 0x17, 0xf7, 0x1c, 0x54, 0x35, 0x22, 0x5e, 0x8f, + 0x4a, 0x7e, 0x88, 0x3a, 0x4b, 0x6a, 0xf7, 0xc9, 0x8a, 0x5c, 0xf0, 0x1c, + 0xe7, 0x48, 0x37, 0xe3, 0xda, 0xf9, 0xac, 0x21, 0xdf, 0xe0, 0x5c, 0x7e, + 0x88, 0x18, 0xe2, 0xfd, 0x80, 0xcf, 0x16, 0x85, 0xeb, 0x6f, 0xdc, 0x67, + 0x96, 0x90, 0x6b, 0x68, 0x0a, 0x79, 0x0f, 0x79, 0x77, 0x96, 0x71, 0xf2, + 0x23, 0xc6, 0x4b, 0x9c, 0x1b, 0xe7, 0xe4, 0x62, 0x9e, 0x5f, 0x6b, 0x05, + 0x7f, 0x71, 0x87, 0x41, 0xfc, 0x36, 0xfb, 0x2e, 0xe7, 0xdb, 0x2f, 0x2b, + 0x74, 0x44, 0x82, 0x8f, 0xe6, 0xcb, 0xc8, 0xc3, 0xe7, 0xe0, 0xe3, 0x0b, + 0x2d, 0x16, 0xf5, 0x56, 0xe5, 0xf3, 0xc9, 0xd8, 0x18, 0x1f, 0x29, 0xa3, + 0xdf, 0x3e, 0xf8, 0xbc, 0x52, 0xce, 0x57, 0xf1, 0xe3, 0x57, 0xe0, 0xc7, + 0x61, 0xd9, 0xcf, 0x77, 0x16, 0x1d, 0x36, 0xbc, 0x3e, 0xe6, 0x11, 0xdb, + 0x9b, 0xda, 0xe8, 0x18, 0x5f, 0x1a, 0xf3, 0xff, 0xfd, 0x90, 0xff, 0x34, + 0xef, 0xc9, 0x8c, 0x0a, 0x0e, 0xe2, 0xef, 0x3d, 0x7d, 0xd4, 0xf7, 0x17, + 0x6a, 0xf1, 0x7d, 0xb6, 0xe0, 0x9e, 0x83, 0x67, 0x76, 0x38, 0xb4, 0x36, + 0x75, 0x6c, 0xec, 0x87, 0x18, 0x7b, 0x15, 0x79, 0x84, 0x7c, 0x05, 0x77, + 0xa6, 0x90, 0xf0, 0x9e, 0x5d, 0xa9, 0xe2, 0x03, 0x4e, 0xd0, 0xe5, 0xb4, + 0xe4, 0x82, 0x5c, 0x70, 0x81, 0xeb, 0xb4, 0xd5, 0x4d, 0x70, 0x21, 0x05, + 0x17, 0xe0, 0xd7, 0xd1, 0xbc, 0x59, 0xe0, 0xcc, 0x39, 0x07, 0xdf, 0x19, + 0xf3, 0x82, 0x79, 0xc0, 0x9c, 0x78, 0xc2, 0x85, 0x2b, 0x3d, 0xc3, 0xd8, + 0xfd, 0x2f, 0x3c, 0x78, 0x57, 0xf0, 0x80, 0xf9, 0x58, 0xe4, 0x85, 0x2e, + 0x70, 0x48, 0xca, 0xbc, 0x50, 0xe8, 0x9c, 0xeb, 0x1b, 0xd6, 0x78, 0xa1, + 0x8d, 0x2d, 0x68, 0xa3, 0xad, 0x70, 0xbd, 0xc3, 0xba, 0x60, 0x3f, 0xd6, + 0xc6, 0x49, 0x7e, 0x85, 0x46, 0xd2, 0xbe, 0x6d, 0x55, 0xf9, 0x21, 0x85, + 0x2e, 0xba, 0xa5, 0x46, 0xd2, 0x52, 0x23, 0xb0, 0x89, 0x95, 0x16, 0xe7, + 0x7a, 0xdb, 0x0a, 0x91, 0x17, 0xba, 0x62, 0xcc, 0x98, 0x8a, 0x3b, 0x09, + 0xeb, 0x96, 0xf3, 0xe9, 0x50, 0x1e, 0x2d, 0xef, 0xa5, 0x1d, 0x71, 0x2f, + 0xfd, 0x8a, 0x3e, 0x9a, 0x47, 0x67, 0x90, 0x43, 0xf8, 0x5e, 0x3a, 0xa7, + 0xf3, 0xbd, 0x14, 0xba, 0xd3, 0x87, 0xef, 0xa5, 0xc9, 0xc8, 0xbd, 0xb4, + 0xf2, 0xe5, 0xf6, 0x93, 0xf2, 0x69, 0x15, 0x13, 0xce, 0xa9, 0x02, 0xf3, + 0x13, 0x6a, 0xbf, 0xca, 0x86, 0xf3, 0x0d, 0x6b, 0xb9, 0xcc, 0x51, 0xa8, + 0xb5, 0xee, 0x67, 0x15, 0xe7, 0xdf, 0xc0, 0x3c, 0xf8, 0xee, 0x9f, 0xc4, + 0x79, 0xa3, 0xe4, 0xfc, 0x54, 0xe1, 0xd3, 0x1f, 0xe6, 0xfd, 0x1b, 0xfa, + 0x28, 0xef, 0xab, 0x71, 0x2a, 0xde, 0x17, 0x63, 0x3e, 0x54, 0x9a, 0x38, + 0xdb, 0x96, 0x91, 0x6b, 0x66, 0xf8, 0xbe, 0x85, 0x5c, 0xe0, 0xd5, 0x71, + 0xef, 0x98, 0xe1, 0xb1, 0xd3, 0x0c, 0xe7, 0x4d, 0x03, 0xbc, 0x17, 0x9c, + 0x3d, 0x12, 0xf7, 0x01, 0xac, 0x7b, 0x86, 0xab, 0xab, 0x51, 0x2e, 0xbe, + 0x88, 0x0b, 0x45, 0xb5, 0x97, 0xaa, 0xcd, 0x19, 0x6a, 0x5b, 0x2e, 0xb1, + 0x2e, 0x62, 0xfd, 0xa0, 0xb8, 0x8f, 0xd3, 0x2e, 0x6a, 0xb1, 0x43, 0xd4, + 0x39, 0x77, 0x70, 0x9f, 0x4b, 0x06, 0x8f, 0xf2, 0x07, 0x0d, 0x95, 0xba, + 0xc7, 0x3e, 0x5d, 0xac, 0xd7, 0x36, 0x6f, 0xe3, 0xed, 0xdd, 0x41, 0x15, + 0x53, 0xee, 0xe7, 0xb6, 0x7f, 0xe0, 0xbc, 0x45, 0x1d, 0x37, 0x32, 0x67, + 0xf5, 0xce, 0x7f, 0xff, 0x06, 0x63, 0xe1, 0x4b, 0x7b, 0x30, 0x12, 0x00, + 0x00, 0x00 }; static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 }; static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 }; @@ -2554,939 +1543,422 @@ static const u32 bnx2_TXP_b06FwBssAddr = 0x080057a0; static const int bnx2_TXP_b06FwBssLen = 0x1c4; static const u32 bnx2_TXP_b06FwSbssAddr = 0x08005760; static const int bnx2_TXP_b06FwSbssLen = 0x38; -static u32 bnx2_TXP_b06FwText[(0x5748/4) + 1] = { - 0x0a000d2c, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x322e352e, - 0x38000000, 0x02050800, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, - 0x24425760, 0x3c030800, 0x24635964, 0xac400000, 0x0043202b, 0x1480fffd, - 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261034b0, - 0x3c1c0800, 0x279c5760, 0x0e000f5b, 0x00000000, 0x0000000d, 0x8f840014, - 0x27bdffe8, 0xafb10014, 0xafb00010, 0x8f460104, 0x8f830008, 0x8c8500ac, - 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12, 0x8c8200ac, - 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0x00008021, 0xa7420e16, - 0x8f430e18, 0x00006021, 0x00c53023, 0xaf430e1c, 0x10c001a2, 0x2d820001, - 0x3c0e1000, 0x2419fff8, 0x24110010, 0x240f0f00, 0x3c188100, 0x93620008, - 0x10400009, 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000, - 0x97620010, 0x3042ffff, 0x0a000d6d, 0xaf420e00, 0xaf460e00, 0x8f420000, - 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff, - 0x30820001, 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a000f34, - 0x00000000, 0x0000000d, 0x3083a040, 0x24020040, 0x1462004f, 0x3082a000, - 0x308a0036, 0x8f88000c, 0x30890008, 0x24020800, 0xaf420178, 0x01001821, - 0x9742008a, 0x00431023, 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa, - 0x00a06021, 0x8f820018, 0x00cc3023, 0x24070001, 0x8f830008, 0x304b00ff, - 0x24420001, 0xaf820018, 0x25024000, 0x106f0005, 0x03422021, 0x93820012, - 0x30420007, 0x00021240, 0x34470001, 0x000b1400, 0x3c030100, 0x00431025, - 0xac820000, 0x8f830018, 0x00ea3825, 0x1120000f, 0xac830004, 0x97430e0a, - 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825, 0xaf430160, 0x25830006, - 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158, 0xaf84000c, 0x0a000db7, - 0x00000000, 0x8f83000c, 0x25820002, 0xa7420158, 0x24630008, 0x30631fff, - 0xaf83000c, 0x54c0000f, 0x8f420e14, 0x8f820008, 0x504f0002, 0x24100001, - 0x34e70040, 0x97420e10, 0x97430e12, 0x8f850014, 0x00021400, 0x00621825, - 0xaca300a8, 0x8f840014, 0x8f420e18, 0xac8200ac, 0x8f420e14, 0x8f430e1c, - 0xaf420144, 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a000efb, 0xaf4e0178, - 0x10400165, 0x00000000, 0x93620008, 0x50400008, 0xafa60008, 0x97620010, - 0x00a2102b, 0x10400003, 0x30820040, 0x1040015c, 0x00000000, 0xafa60008, - 0xa7840010, 0xaf850004, 0x93620008, 0x1440005f, 0x27ac0008, 0xaf60000c, - 0x97820010, 0x30424000, 0x10400002, 0x2403000e, 0x24030016, 0xa363000a, - 0x24034007, 0xaf630014, 0x93820012, 0x8f630014, 0x30420007, 0x00021240, - 0x00621825, 0xaf630014, 0x97820010, 0x8f630014, 0x30420010, 0x00621825, - 0xaf630014, 0x97820010, 0x30420008, 0x5040000e, 0x00002821, 0x8f620014, - 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e, 0x00781825, 0xaf630004, - 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004, 0x0a000e06, 0xa363000a, - 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a, 0x30421f00, 0x00021182, - 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c, 0xa7620010, 0x93630009, - 0x24020008, 0x24630002, 0x30630007, 0x00431023, 0x30420007, 0xa362000b, - 0x93640009, 0x97620010, 0x8f890004, 0x97830010, 0x00441021, 0x00a21021, - 0x30630040, 0x10600007, 0x3045ffff, 0x00a9102b, 0x14400005, 0x0125102b, - 0x3c068000, 0x0a000e3a, 0x00005821, 0x0125102b, 0x544000c7, 0x00006021, - 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c, 0xaf420e18, - 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08, - 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001, 0xaf830004, - 0x97620010, 0x0a000e4c, 0x304dffff, 0x8f890004, 0x97820010, 0x30420040, - 0x10400004, 0x01206821, 0x3c068000, 0x0a000e4c, 0x00005821, 0x97630010, - 0x8f820004, 0x10430003, 0x00003021, 0x0a000eee, 0x00006021, 0x240b0001, - 0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040, - 0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025, - 0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003e, - 0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000, - 0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7, - 0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000, - 0x03422821, 0x00605021, 0x24630001, 0x314200ff, 0x00021400, 0xaf830018, - 0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00, - 0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008, - 0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c, - 0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0xa7420146, - 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a, 0xaf460160, - 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00511021, 0x30421fff, 0xaf82000c, - 0x0a000ed9, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c, 0x2463000a, - 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff, 0xafa30000, - 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, 0x1440fff7, - 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080, 0x24424000, - 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009, 0x310200ff, - 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025, 0xaca40000, - 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002, 0x8f450e1c, - 0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0x308400ff, - 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c, 0x25420007, 0x00591024, - 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154, 0xaf4e0178, 0x00621821, - 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005, 0x00000000, 0x8f620014, - 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c, 0x004d1021, 0xaf62000c, - 0x93630008, 0x14600008, 0x00000000, 0x11600006, 0x00000000, 0x8f630014, - 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014, 0xa36b0008, 0x01206021, - 0x1580000c, 0x8fa60008, 0x97420e14, 0x97430e16, 0x8f850014, 0x00021400, - 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c, 0xac8200ac, 0x0a000efd, - 0x2d820001, 0x14c0fe65, 0x2d820001, 0x00501025, 0x10400058, 0x24020f00, - 0x8f830008, 0x14620023, 0x3c048000, 0x11800009, 0x3c038000, 0x97420e08, - 0x30420040, 0x14400005, 0x00000000, 0x0000000d, 0x00000000, 0x2400032c, - 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97420e10, - 0x3c030500, 0x00431025, 0xaf42014c, 0x97430e14, 0xa7430144, 0x97420e16, - 0xa7420146, 0x8f430e1c, 0x24022000, 0xaf430148, 0x3c031000, 0xa3400152, - 0xa740015a, 0xaf400160, 0xa7400158, 0xaf420154, 0xaf430178, 0x8f830008, - 0x3c048000, 0x8f420178, 0x00441024, 0x1440fffd, 0x24020f00, 0x10620016, - 0x00000000, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c, - 0x3c031000, 0xaf420148, 0x0a000f51, 0x24020240, 0x97420e14, 0x97430e16, - 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c, - 0x00006021, 0xaca200ac, 0x0a000efd, 0x2d820001, 0xaf40014c, 0x11800007, - 0x00000000, 0x97420e10, 0xa7420144, 0x97430e12, 0xa7430146, 0x0a000f4e, - 0x8f420e18, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c, - 0xaf420148, 0x24020040, 0x3c031000, 0xa3400152, 0xa740015a, 0xaf400160, - 0xa7400158, 0xaf420154, 0xaf430178, 0x8fb10014, 0x8fb00010, 0x03e00008, - 0x27bd0018, 0x27bdffd0, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, - 0x03421821, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, - 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014, 0xaf440e00, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd, - 0x3c046004, 0xaf420e00, 0x8c835000, 0x24160800, 0x24150d00, 0x3c140800, - 0x24130f00, 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c, - 0x24020009, 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e001559, - 0x00000000, 0x0e000ff0, 0x00000000, 0x3c020800, 0x245057c0, 0x8f420000, - 0x30420001, 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020, - 0xaf560178, 0x93430108, 0xa3830012, 0x93820012, 0x30420001, 0x10400008, - 0x00000000, 0x93820012, 0x30420006, 0x00021100, 0x0e000d43, 0x0050d821, - 0x0a000fac, 0x00000000, 0x14950005, 0x00000000, 0x0e000d43, 0x269b5840, - 0x0a000fac, 0x00000000, 0x14930005, 0x00000000, 0x0e000d43, 0x265b5860, - 0x0a000fac, 0x00000000, 0x0e0010ea, 0x00000000, 0xaf510138, 0x0a000f89, - 0x00000000, 0x27bdfff8, 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c, - 0x9743008a, 0x3063ffff, 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, - 0x30421fff, 0x0044102b, 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082, - 0x00021080, 0x24424000, 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff, - 0x8f82000c, 0x24840007, 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c, - 0x03e00008, 0x00000000, 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, - 0x3c020008, 0x03421821, 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd, - 0x3c046004, 0xaf420e00, 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c, - 0x24030009, 0xac825000, 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e001559, - 0x00000000, 0x0e000ff0, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, - 0x27bdffe8, 0x3c02000a, 0x03421821, 0x3c040800, 0x24845880, 0x24050019, - 0xafbf0010, 0xaf830024, 0x0e001565, 0x00003021, 0x3c050800, 0x3c020800, - 0x24425330, 0xaca258e8, 0x24a558e8, 0x3c020800, 0x244254f8, 0x3c030800, - 0x2463550c, 0x3c040800, 0xaca20004, 0x3c020800, 0x24425338, 0xaca30008, - 0xac825900, 0x24845900, 0x3c020800, 0x244253c4, 0x3c070800, 0x24e75404, - 0x3c060800, 0x24c65520, 0x3c050800, 0x24a55438, 0x3c030800, 0xac820004, - 0x3c020800, 0x24425528, 0xac870008, 0xac86000c, 0xac850010, 0xac625920, - 0x24635920, 0x8fbf0010, 0x3c020800, 0x24425540, 0xac620004, 0x3c020800, - 0xac670008, 0xac66000c, 0xac650010, 0xac400048, 0x03e00008, 0x27bd0018, - 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc, 0xad020004, 0x8f4309e0, - 0xad030008, 0x934409d9, 0x24020001, 0x30840003, 0x1082001f, 0x30a900ff, - 0x28820002, 0x10400005, 0x24020002, 0x10800009, 0x3c0a0800, 0x0a001078, - 0x93420934, 0x1082000b, 0x24020003, 0x10820026, 0x3c0a0800, 0x0a001078, - 0x93420934, 0x974209e4, 0x00021400, 0x34420800, 0xad02000c, 0x0a001077, - 0x25080010, 0x974209e4, 0x00021400, 0x34428100, 0xad02000c, 0x974309e8, - 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010, 0x0a001077, 0x25080014, - 0x974409e4, 0x3c050800, 0x24a25880, 0x9443001c, 0x94460014, 0x94470010, - 0x00a05021, 0x24020800, 0xad000010, 0xad020014, 0x00042400, 0x00661821, - 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c, 0x0a001077, 0x25080018, - 0x974209e4, 0x3c050800, 0x00021400, 0x34428100, 0xad02000c, 0x974409e8, - 0x24a25880, 0x9443001c, 0x94460014, 0x94470010, 0x00a05021, 0x24020800, - 0xad000014, 0xad020018, 0x00042400, 0x00661821, 0x00671823, 0x2463ffee, - 0x00832025, 0xad040010, 0x2508001c, 0x93420934, 0x93450921, 0x3c074000, - 0x25445880, 0x94830018, 0x94860014, 0x00021082, 0x00021600, 0x00052c00, - 0x00a72825, 0x00451025, 0x00661821, 0x00431025, 0xad020000, 0x9783002c, - 0x974209ea, 0x00621821, 0x00031c00, 0xad030004, 0x9782002c, 0x24420001, - 0x30427fff, 0xa782002c, 0x93430920, 0x3c020006, 0x00031e00, 0x00621825, - 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930, 0xad030010, 0x8f440938, - 0x25080014, 0xad040000, 0x8f820020, 0x11200004, 0xad020004, 0x8f420940, - 0x0a0010a1, 0x2442ffff, 0x8f420940, 0xad020008, 0x8f440948, 0x8f420940, - 0x93430936, 0x00823023, 0x00663006, 0x3402ffff, 0x0046102b, 0x54400001, - 0x3406ffff, 0x93420937, 0x25445880, 0x90830024, 0xad000010, 0x00021700, - 0x34630010, 0x00031c00, 0x00431025, 0x00461025, 0xad02000c, 0x8c830008, - 0x14600031, 0x25080014, 0x3c020800, 0x8c430048, 0x1060002d, 0x00000000, - 0x9342010b, 0xad020000, 0x8f830000, 0x8c6200b0, 0xad020004, 0x8f830000, - 0x8c6200b4, 0xad020008, 0x8f830000, 0x8c6200c0, 0xad02000c, 0x8f830000, - 0x8c6200c4, 0xad020010, 0x8f830000, 0x8c6200c8, 0xad020014, 0x8f830000, - 0x8c6200cc, 0xad020018, 0x8f830000, 0x8c6200e0, 0xad02001c, 0x8f830000, - 0x8c6200e8, 0xad020020, 0x8f830000, 0x8c6200f0, 0x3c04600e, 0xad020024, - 0x8c8200d0, 0xad020028, 0x8c8300d4, 0xad03002c, 0x8f820028, 0x3c046012, - 0xad020030, 0x8c8200a8, 0xad020034, 0x8c8300ac, 0x3c026000, 0xad030038, - 0x8c434448, 0xad03003c, 0x03e00008, 0x01001021, 0x27bdffa8, 0x3c020008, - 0x03423021, 0xafbf0054, 0xafbe0050, 0xafb7004c, 0xafb60048, 0xafb50044, - 0xafb40040, 0xafb3003c, 0xafb20038, 0xafb10034, 0xafb00030, 0xaf860000, - 0x24020040, 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954, - 0x8f45095c, 0xaf820034, 0xaf830020, 0xaf84001c, 0xaf850030, 0x90c20000, - 0x24030020, 0x304400ff, 0x10830005, 0x24020030, 0x10820022, 0x3c030800, - 0x0a001139, 0x8c62002c, 0x24020088, 0xaf420818, 0x3c020800, 0x244258e8, - 0xafa20020, 0x93430109, 0x3c020800, 0x10600009, 0x24575900, 0x3c026000, - 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, - 0x24000376, 0x9342010a, 0x30420080, 0x14400021, 0x24020800, 0x3c026000, - 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, - 0x2400037d, 0x0a001141, 0x24020800, 0x93430109, 0x3063007f, 0x00031140, - 0x000318c0, 0x00431021, 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800, - 0x24425940, 0x3c030800, 0x24775950, 0x0a001140, 0xafa20020, 0x24420001, - 0xac62002c, 0x0000000d, 0x00000000, 0x24000395, 0x0a0014c1, 0x8fbf0054, - 0x24020800, 0xaf420178, 0x8f450104, 0x8f420988, 0x00a21023, 0x58400005, - 0x8f4309a0, 0x0000000d, 0x00000000, 0x240003b1, 0x8f4309a0, 0x3c100800, - 0xae0358b0, 0x8f4209a4, 0x8f830020, 0x260458b0, 0x2491ffd0, 0xae220034, - 0x00a21023, 0xae230028, 0xac82ffd0, 0x8fa30020, 0x8c620000, 0x0040f809, - 0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024, - 0x8e220020, 0x32530040, 0x2403ffbf, 0x00431024, 0x0a001493, 0xae220020, - 0x32420020, 0x10400002, 0x3c020800, 0x24575920, 0x32420001, 0x14400007, - 0x00000000, 0x8f820008, 0xaf420080, 0x8ec358b0, 0xaf430e10, 0x8e220034, - 0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff, - 0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100, - 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003ed, - 0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32530040, 0x00003821, - 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, - 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100, - 0xaf420148, 0x24020047, 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, - 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, - 0x9342010a, 0x3c030047, 0xafa50014, 0x00021600, 0x00431025, 0x00471025, - 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, - 0x3c070100, 0x3c050800, 0x24a25880, 0x0a001250, 0x8c430020, 0x32820002, - 0x10400050, 0x00000000, 0x0e0015b9, 0x32530040, 0x3c039000, 0x34630001, - 0x8f820008, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, - 0x1440fffd, 0x00000000, 0x8f830000, 0x90620005, 0x34420008, 0xa0620005, - 0x8f840000, 0x8c820074, 0x3c038000, 0x00431025, 0xac820074, 0x90830000, - 0x24020020, 0x10620004, 0x00000000, 0x0000000d, 0x00000000, 0x2400040b, - 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x9084007b, - 0x9342010a, 0x14820028, 0x3c030800, 0x00003821, 0x24052000, 0x3c090800, - 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0, - 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100, 0xaf420148, 0x24020046, - 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154, - 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030046, - 0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b, - 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070100, 0x3c030800, - 0x24625880, 0x0a001250, 0x8c430020, 0x93420108, 0x30420010, 0x50400056, - 0x9343093f, 0x8f860000, 0x90c2007f, 0x8cc30178, 0x304800ff, 0x15030004, - 0x00000000, 0x0000000d, 0x00000000, 0x24000425, 0x90c2007e, 0x90c40080, - 0x00081c00, 0x00021600, 0x00431025, 0x00042200, 0x90c3007a, 0x90c5000a, - 0x00441025, 0x11050028, 0x00623825, 0xa0c8000a, 0x00004021, 0x24056000, - 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, - 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0xaf420148, 0x24020052, - 0xaf47014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7480158, 0xaf450154, - 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030052, - 0xafa50014, 0x00021600, 0x00431025, 0x00481025, 0xafa20010, 0x9343010b, - 0xafa30018, 0x8f440100, 0x0e00159b, 0x8f450104, 0x0a00124a, 0x00000000, - 0x3c026000, 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, - 0x00000000, 0x2400043e, 0x16800009, 0x3c050800, 0x3c040800, 0x24825880, - 0x8c430020, 0x32530040, 0x2404ffbf, 0x00641824, 0x0a001493, 0xac430020, - 0x8ca25880, 0x10400005, 0x3c030800, 0x8c620034, 0xaca05880, 0x24420001, - 0xac620034, 0x9343093f, 0x24020012, 0x5462000e, 0x97420908, 0x32820038, - 0x14400009, 0x3c030800, 0x8f830000, 0x8c62004c, 0xac62005c, 0x3c020800, - 0x24445880, 0x8c820020, 0x0a001285, 0x32530040, 0xac605880, 0x97420908, - 0x5440001c, 0x97420908, 0x3c039000, 0x34630001, 0x8f820008, 0x32530040, - 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd, - 0x3c028000, 0x8f840000, 0x8f850008, 0x8c830050, 0x34420001, 0x00a22825, - 0xaf830020, 0xac830070, 0xac83005c, 0xaf450020, 0x3c050800, 0x24a45880, - 0x8c820020, 0x2403ffbf, 0x00431024, 0x0a001493, 0xac820020, 0x000211c0, - 0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c, - 0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa782002c, 0x3c020800, 0x24445880, - 0xac83002c, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830018, - 0x934209d8, 0x32850038, 0xafa50028, 0x00621821, 0xa483001a, 0x934209d8, - 0x93430934, 0x3c1e0800, 0x00809821, 0x00431021, 0x24420010, 0xa4820016, - 0x24020006, 0xae620020, 0x8fa20028, 0x10400003, 0x0000a821, 0x0a0012f0, - 0x24120008, 0x8f420958, 0x8f830020, 0x8f840030, 0x00431023, 0x00832023, - 0x04800003, 0xae620004, 0x04410003, 0x0082102b, 0x0a0012bc, 0xae600004, - 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809, 0x00000000, 0x00409021, - 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008, 0x1060002b, 0x3c02c000, - 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, - 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008, 0xaf830004, 0x8f840004, - 0x0044102b, 0x1040000b, 0x24150001, 0x24020100, 0x3c016000, 0xac22081c, - 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d, 0x00000000, 0x240004cd, - 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000, 0x02429025, 0x32420002, - 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec258b0, 0x8f830000, 0xac6200a8, - 0x8f840000, 0x8e620034, 0xac8200ac, 0x32420004, 0x50400013, 0x8f470940, - 0x3c020800, 0x3283007d, 0x10600110, 0x24575920, 0x32820001, 0x50400006, - 0x36520002, 0x8f830034, 0x8f420940, 0x10620109, 0x00000000, 0x36520002, - 0x24020008, 0xa6600010, 0xa6620012, 0xae600008, 0xa2600024, 0x8f470940, - 0x3c030800, 0x24685880, 0x8d02002c, 0x8d050008, 0x95040010, 0x9506000a, - 0x95030026, 0x00451021, 0x00862021, 0x00641821, 0xaf870034, 0xad02002c, - 0x32820030, 0x10400008, 0xa5030014, 0x91020024, 0x32910040, 0x34420004, - 0xa1020024, 0xaf400048, 0x0a001345, 0x3c040800, 0x93420923, 0x30420002, - 0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023, - 0x0442000a, 0x3c039000, 0x95020014, 0x8c630084, 0x00821021, 0x00621823, - 0x1c600004, 0x3c039000, 0x91020024, 0x34420001, 0xa1020024, 0x34630001, - 0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, - 0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a, - 0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014, - 0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, - 0x3c040800, 0x24865880, 0x94c20010, 0x94c3001a, 0x8cc40008, 0x00432821, - 0x14800006, 0xa4c5001c, 0x3c020800, 0x8c430048, 0x10600002, 0x24a20040, - 0xa4c2001c, 0x27d05880, 0x9604001c, 0x96020012, 0x00822021, 0x24840002, - 0x0e000faf, 0x3084ffff, 0x8f850018, 0x00a01821, 0xa2030025, 0x8ee60008, - 0x00402021, 0x24a50001, 0xaf850018, 0x00c0f809, 0x00000000, 0x00402021, - 0x0e001026, 0x02202821, 0x8ee3000c, 0x0060f809, 0x00402021, 0x9604001c, - 0x96020012, 0x00822021, 0x24840002, 0x0e000fc5, 0x3084ffff, 0x8fc25880, - 0x8e030008, 0x00431023, 0x14400012, 0xafc25880, 0x54600006, 0x8e020020, - 0x3243004a, 0x24020002, 0x14620005, 0x00000000, 0x8e020020, 0x34420040, - 0x0a001382, 0xae020020, 0x52a00006, 0x36520002, 0x8e020030, 0xaf420e10, - 0x8e030034, 0xaf430e18, 0x36520002, 0x52a00008, 0x96670014, 0x8f830000, - 0x8f420e10, 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670014, - 0x92680024, 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821, - 0x00621023, 0xaf830020, 0x18400008, 0x00000000, 0x8f820000, 0xaf83001c, - 0xac430054, 0x54e00005, 0xaf400040, 0x0a0013a0, 0x8f42095c, 0x54e00001, - 0xaf400044, 0x8f42095c, 0x31030008, 0xaf820030, 0x1060001a, 0x00000000, - 0x8f840000, 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007, - 0x24020007, 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122, - 0x8f850000, 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001, - 0x30630007, 0xac440000, 0x0a0013bd, 0xa0a30120, 0x90820122, 0x34420001, - 0xa0820122, 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000, - 0x8c43000c, 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008, - 0x34420001, 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024, - 0x1440fffd, 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018, - 0x00000000, 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068, - 0x90e40081, 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b, - 0x54400001, 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001, - 0x00c02021, 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c, - 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f820020, - 0x3c050800, 0x24b05880, 0xae020028, 0x8ee30010, 0x0060f809, 0x00000000, - 0x8f820028, 0x24420001, 0xaf820028, 0x12a00005, 0xaf40004c, 0x8f420e10, - 0xae020030, 0x8f430e18, 0xae030034, 0x1220fea7, 0x24020006, 0x8f870024, - 0x9786002c, 0x8f830000, 0x8f820034, 0x8f840020, 0x8f85001c, 0x32530040, - 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, 0xac650054, 0x1040007a, - 0x32820020, 0x10400027, 0x32910010, 0x00003821, 0x24052000, 0x3c090800, - 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0, - 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030400, 0xaf420148, 0x24020041, - 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154, - 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030041, - 0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b, - 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070400, 0x12200028, - 0x00003821, 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, - 0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, - 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0xa3420152, 0x8d230030, - 0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001, - 0xad230030, 0x9342010a, 0x3c03004e, 0xafa50014, 0x00021600, 0x00431025, - 0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104, - 0x0e00159b, 0x3c070300, 0x0a00148b, 0x8fa20024, 0x32820008, 0x10400026, - 0x24052000, 0x00003821, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, - 0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, - 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0xa3420152, 0x8d230030, - 0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001, - 0xad230030, 0x9342010a, 0x3c03004b, 0xafa50014, 0x00021600, 0x00431025, - 0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104, - 0x0e00159b, 0x3c070200, 0x8fa20024, 0x14400004, 0x8fa30020, 0x32420010, - 0x10400004, 0x00000000, 0x8c620004, 0x0040f809, 0x00000000, 0x12600006, - 0x8fa40020, 0x8c820008, 0x0040f809, 0x00000000, 0x0a0014c1, 0x8fbf0054, - 0x3c030800, 0x8c6258a0, 0x30420040, 0x14400023, 0x8fbf0054, 0x00002821, - 0x24040040, 0x8f870020, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, - 0x8ec258b0, 0x26c358b0, 0x2463ffd0, 0xaf420144, 0x8c620034, 0xaf420148, - 0x24020049, 0xaf47014c, 0xa3420152, 0x3c021000, 0xa7450158, 0xaf440154, - 0xaf420178, 0x8c660034, 0x9342010a, 0x3c030049, 0xafa40014, 0x00021600, - 0x00431025, 0x00451025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, - 0x0e00159b, 0x8f450104, 0x8fbf0054, 0x8fbe0050, 0x8fb7004c, 0x8fb60048, - 0x8fb50044, 0x8fb40040, 0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, - 0x03e00008, 0x27bd0058, 0x03e00008, 0x00001021, 0x3c020800, 0x24435880, - 0x8c650004, 0x8c445880, 0x0085182b, 0x10600002, 0x00403021, 0x00802821, - 0x9744093c, 0x00a4102b, 0x54400001, 0x00a02021, 0x93420923, 0x0004182b, - 0x00021042, 0x30420001, 0x00431024, 0x1040000d, 0x24c25880, 0x8f850000, - 0x8f830020, 0x8ca20084, 0x00431023, 0x04420007, 0x24c25880, 0x8ca20084, - 0x00641821, 0x00431023, 0x28420001, 0x00822023, 0x24c25880, 0xac440008, - 0xa4400026, 0x03e00008, 0x00001021, 0x8f850004, 0x97840010, 0x3c030800, - 0x24635880, 0x24020008, 0xa4620012, 0x8f820004, 0xa4600010, 0x000420c2, - 0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008, - 0xa0640024, 0x3c020800, 0x24425880, 0x90450025, 0x9443001c, 0x3c021100, - 0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008, - 0x03e00008, 0xac850000, 0x27bdffd8, 0x3c020800, 0x24425880, 0xafbf0020, - 0x90480025, 0x8c440008, 0x8c460020, 0x8f870020, 0x3c030800, 0x3c058000, - 0x8f420178, 0x00451024, 0x1440fffd, 0x8c6258b0, 0x246358b0, 0x2469ffd0, - 0xaf420144, 0x8d220034, 0x30c32000, 0xaf420148, 0x3c021000, 0xaf47014c, - 0xa3480152, 0xa7440158, 0xaf460154, 0xaf420178, 0x10600004, 0x3c030800, - 0x8c620030, 0x24420001, 0xac620030, 0x9342010a, 0x00081c00, 0x3084ffff, - 0xafa60014, 0x00021600, 0x00431025, 0x00441025, 0xafa20010, 0x9343010b, - 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x8d260034, 0x8fbf0020, - 0x03e00008, 0x27bd0028, 0x0000000d, 0x00000000, 0x2400019d, 0x03e00008, - 0x00000000, 0x0000000d, 0x00000000, 0x240001a9, 0x03e00008, 0x00000000, - 0x03e00008, 0x00000000, 0x3c020800, 0x24425880, 0xac400008, 0xa4400026, - 0x03e00008, 0x24020001, 0x3c020800, 0x24425880, 0x24030008, 0xac400008, - 0xa4400010, 0xa4430012, 0xa0400024, 0x03e00008, 0x24020004, 0x03e00008, - 0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, - 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00156c, - 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021, - 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068, - 0x3c050800, 0x24a52098, 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04, - 0x00a61021, 0xac440004, 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00, - 0x00431025, 0xac820008, 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14, - 0xac440010, 0x8f430e18, 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff, - 0x25290001, 0xac470018, 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000, - 0x24630001, 0xace3006c, 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068, - 0x00042600, 0x00681824, 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010, - 0x8fad0014, 0x8fae0018, 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080080, - 0x000a4940, 0x01281021, 0x01091821, 0xac440000, 0x00601021, 0xac650004, - 0xac460008, 0xac67000c, 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018, - 0x8c654448, 0x3c040800, 0x8c820064, 0x254a0001, 0x314a00ff, 0x01094021, - 0xad6a0060, 0x24420001, 0xac820064, 0x03e00008, 0xad05001c, 0x3c030800, - 0x3c090800, 0x8d250070, 0x246330b0, 0x8f460100, 0x00053900, 0x00e31021, - 0xac460000, 0x8f440104, 0x00671021, 0xac440004, 0x8f460108, 0x8f840014, - 0x24a50001, 0xac460008, 0x8c880074, 0x3c060800, 0x8cc20074, 0x30a5003f, - 0x00671821, 0xad250070, 0x24420001, 0xacc20074, 0x03e00008, 0xac68000c, - 0x00000000 }; +static u8 bnx2_TXP_b06FwText[] = { + 0x1f, 0x8b, 0x08, 0x08, 0x21, 0xd3, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xed, 0x5c, 0x6d, 0x6c, + 0x1b, 0xf7, 0x79, 0x7f, 0xee, 0x85, 0xd2, 0x51, 0x96, 0xe9, 0x93, 0xc2, + 0x78, 0x6c, 0xc0, 0xa6, 0x77, 0xd6, 0x51, 0x66, 0x20, 0xb5, 0xa0, 0x05, + 0x36, 0x55, 0x87, 0x43, 0x73, 0x3e, 0x52, 0x2f, 0x4e, 0x5c, 0x57, 0x71, + 0x94, 0x86, 0x6e, 0x0d, 0x8c, 0xa0, 0xec, 0xd8, 0xeb, 0x5a, 0x2c, 0x1f, + 0x8c, 0xd5, 0x68, 0xd1, 0x99, 0xa1, 0x68, 0xc7, 0xc9, 0x68, 0x51, 0xa9, + 0xe5, 0xa8, 0x43, 0x57, 0x80, 0x95, 0x64, 0xcb, 0x29, 0x4e, 0x3a, 0x65, + 0xcb, 0x16, 0x0c, 0x58, 0x16, 0xcd, 0x2f, 0x5d, 0x3f, 0x74, 0x80, 0x3f, + 0xec, 0x43, 0x3a, 0xec, 0x83, 0x91, 0x14, 0xad, 0x11, 0x6c, 0x59, 0xb0, + 0x2f, 0x33, 0xd6, 0x26, 0xb7, 0xdf, 0x73, 0x77, 0x94, 0x95, 0xc4, 0x4e, + 0xab, 0x7d, 0xbe, 0x07, 0x20, 0xee, 0x7f, 0xff, 0xd7, 0xe7, 0xfd, 0xe5, + 0x7f, 0x90, 0x06, 0xb7, 0x53, 0x17, 0x85, 0xb0, 0x1d, 0x3f, 0xed, 0x99, + 0x93, 0x27, 0x3e, 0xf7, 0xf9, 0xcf, 0x0d, 0xa1, 0x39, 0x4c, 0x4a, 0x4c, + 0xe4, 0xc1, 0x5b, 0x12, 0x51, 0xf9, 0x1d, 0x8a, 0x20, 0x82, 0x08, 0x22, + 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, + 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, + 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, + 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, + 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, + 0xf8, 0x9d, 0x20, 0x11, 0xa9, 0xfc, 0xdc, 0x1e, 0xfe, 0x48, 0x11, 0xcd, + 0xf2, 0x53, 0xb6, 0x41, 0x8a, 0x64, 0x1e, 0x39, 0x34, 0x65, 0x10, 0x59, + 0xce, 0x80, 0x56, 0xa0, 0xf7, 0xbd, 0x6a, 0x52, 0x26, 0xee, 0xff, 0xb4, + 0xf9, 0xdb, 0x53, 0xaf, 0x7f, 0x41, 0x7f, 0xaf, 0x25, 0x91, 0xa2, 0x9a, + 0x6b, 0x79, 0xb5, 0x9f, 0x94, 0x34, 0xd6, 0xfc, 0xd5, 0xee, 0xaf, 0xef, + 0xa0, 0x44, 0x7b, 0xaf, 0x24, 0xd5, 0x9b, 0xb7, 0xbc, 0xd7, 0x77, 0x27, + 0xe9, 0x15, 0x57, 0xa5, 0x35, 0x57, 0x16, 0x46, 0x9b, 0x0a, 0x4d, 0x37, + 0x1d, 0x3a, 0xdd, 0xa8, 0x52, 0xc1, 0xbd, 0x4c, 0xb5, 0x39, 0x35, 0x61, + 0x2f, 0xff, 0x84, 0xa6, 0xe7, 0x7a, 0x13, 0x85, 0x65, 0x87, 0x6a, 0x8d, + 0x54, 0xc2, 0x76, 0xd5, 0x44, 0x61, 0x3e, 0x89, 0xf7, 0xde, 0x84, 0x3d, + 0xaf, 0x57, 0x89, 0x76, 0x62, 0x4e, 0x2a, 0x51, 0x68, 0xea, 0x65, 0xa2, + 0xbe, 0xdc, 0x75, 0x4a, 0x27, 0x0a, 0xee, 0x82, 0xb0, 0xae, 0x0a, 0x54, + 0xfb, 0x2c, 0xa9, 0x09, 0xf3, 0xb6, 0xf7, 0x29, 0x43, 0xa5, 0x1e, 0x83, + 0x76, 0xec, 0x30, 0xe8, 0xd9, 0x94, 0xa9, 0x50, 0xe5, 0x7c, 0x9c, 0x2c, + 0x9f, 0x26, 0x95, 0x2a, 0xf3, 0x03, 0xea, 0x15, 0x8a, 0x91, 0x95, 0x6c, + 0xbf, 0x7b, 0x9e, 0x9d, 0xfb, 0x16, 0xff, 0x9d, 0x16, 0xce, 0xa2, 0xc4, + 0xa8, 0x4b, 0x64, 0x03, 0x2f, 0x3b, 0xf7, 0xbe, 0x17, 0xac, 0x51, 0x70, + 0xae, 0x9c, 0x18, 0x69, 0x7a, 0x5e, 0x31, 0x87, 0x33, 0x72, 0xed, 0xb5, + 0x31, 0x6a, 0x25, 0xad, 0xd6, 0x74, 0x2e, 0xbf, 0x23, 0xf8, 0x1b, 0x2f, + 0xa6, 0x91, 0xdf, 0x2d, 0x12, 0x8d, 0xaf, 0x50, 0x25, 0x49, 0xad, 0x5a, + 0xee, 0x61, 0x7a, 0x21, 0xd7, 0x4d, 0x67, 0xb1, 0xdf, 0xf3, 0x39, 0xf0, + 0xd1, 0x38, 0x29, 0xd8, 0xae, 0x9e, 0x22, 0xe1, 0x05, 0xb2, 0xe7, 0xfb, + 0xd4, 0x02, 0xe1, 0x6c, 0xc3, 0xfb, 0x8c, 0x9d, 0xc3, 0x79, 0x83, 0xff, + 0xeb, 0x59, 0x49, 0xbd, 0xdc, 0xa2, 0x14, 0xd5, 0x9a, 0x7d, 0xb9, 0x9f, + 0x93, 0x40, 0x9d, 0x06, 0xf3, 0xc7, 0xa3, 0xc7, 0x70, 0xae, 0x6d, 0xa0, + 0xdf, 0x25, 0x4b, 0xcc, 0xc4, 0xe8, 0x4f, 0x55, 0x5d, 0xb3, 0xa5, 0x5e, + 0xaa, 0x9d, 0xef, 0x04, 0x9e, 0x56, 0xaf, 0x88, 0xb9, 0x63, 0x79, 0x4a, + 0x6e, 0x23, 0x12, 0x24, 0x33, 0x83, 0x7d, 0x89, 0x6a, 0x4e, 0x0a, 0x6b, + 0x33, 0xc3, 0xef, 0xd0, 0x0e, 0xd2, 0x7a, 0x64, 0x9a, 0x76, 0xba, 0xc0, + 0xc7, 0x6e, 0xc8, 0x20, 0x33, 0xfc, 0x2e, 0x84, 0x22, 0x1a, 0x99, 0xd4, + 0x49, 0x2a, 0x0b, 0x05, 0xb7, 0x83, 0xa6, 0x33, 0x0a, 0xd5, 0x81, 0x47, + 0x3d, 0xf7, 0x35, 0xc1, 0x5e, 0x2e, 0x09, 0x85, 0x65, 0xcc, 0x73, 0x5f, + 0x0b, 0xff, 0x76, 0xad, 0x1b, 0xfb, 0x88, 0x54, 0xcb, 0x94, 0x30, 0xa6, + 0xd0, 0x14, 0xe6, 0x4d, 0x81, 0xa6, 0x69, 0x77, 0x07, 0xad, 0x4f, 0x26, + 0x13, 0xcc, 0xab, 0x1a, 0xc6, 0xbf, 0x32, 0x21, 0x90, 0x6a, 0x58, 0xf4, + 0xeb, 0x3c, 0x64, 0x38, 0xdf, 0xcb, 0x32, 0xa3, 0xd3, 0x4d, 0x4a, 0x8a, + 0x94, 0x49, 0x55, 0xe8, 0x32, 0x2d, 0x3a, 0x2c, 0x7f, 0xc8, 0x13, 0xf2, + 0xae, 0x39, 0xbc, 0x0e, 0x72, 0x6b, 0x16, 0xc1, 0x8f, 0x71, 0xe0, 0x70, + 0x50, 0x78, 0x6c, 0x71, 0x52, 0x18, 0x73, 0x7f, 0x93, 0xa0, 0xae, 0x93, + 0xc2, 0x01, 0xf7, 0xa8, 0x10, 0xf2, 0x1e, 0xb2, 0x53, 0xc8, 0x9a, 0x50, + 0xe8, 0x92, 0x1b, 0xc8, 0x6e, 0x01, 0xfa, 0x69, 0xa9, 0x16, 0xe4, 0x70, + 0x78, 0x63, 0x0e, 0x8f, 0xd5, 0x97, 0x65, 0x3a, 0xed, 0xf2, 0xfc, 0x3f, + 0x82, 0x7c, 0x14, 0x72, 0x76, 0x77, 0x53, 0x19, 0xfd, 0xb5, 0x79, 0xb2, + 0xec, 0x9c, 0x88, 0x35, 0x09, 0x92, 0x8c, 0x9d, 0xf8, 0x75, 0xd1, 0xd4, + 0x62, 0xa7, 0x25, 0x19, 0x49, 0x9a, 0x72, 0x99, 0x87, 0x78, 0x36, 0xdb, + 0x7c, 0x64, 0x5c, 0xb9, 0x9f, 0xd7, 0x71, 0xbf, 0x8a, 0xfe, 0xcd, 0x7d, + 0xac, 0x17, 0x09, 0xe0, 0xa3, 0x67, 0x59, 0x9f, 0x2b, 0xcd, 0x8c, 0x7a, + 0x80, 0x9f, 0x2e, 0xf3, 0xb6, 0xcd, 0x53, 0x19, 0x73, 0x45, 0xaa, 0x2c, + 0xe2, 0x9c, 0xf3, 0xbf, 0xf5, 0x62, 0x79, 0xbc, 0x1b, 0x1d, 0xa0, 0x8b, + 0xcf, 0x95, 0x81, 0x93, 0x48, 0xe5, 0x45, 0xde, 0x8b, 0xc7, 0x09, 0xb2, + 0xaf, 0xf5, 0x88, 0x94, 0x85, 0x7c, 0x75, 0x9c, 0x13, 0xc7, 0x9c, 0x6e, + 0xf0, 0x0f, 0xb4, 0x2e, 0xa3, 0x0d, 0xda, 0x45, 0x43, 0xc4, 0xfa, 0x4e, + 0x9a, 0xca, 0xb1, 0xbe, 0x30, 0x9e, 0xdb, 0xb0, 0x77, 0x9c, 0x8e, 0x9c, + 0x67, 0x7e, 0xc8, 0xf4, 0x3c, 0x70, 0x9c, 0x9e, 0xd7, 0xd5, 0x22, 0xe9, + 0xe0, 0x8d, 0x85, 0x79, 0x9d, 0x54, 0x56, 0x3d, 0x6f, 0x24, 0x37, 0xa0, + 0xbe, 0xec, 0xeb, 0xf9, 0x80, 0x9a, 0x11, 0xa8, 0xda, 0x61, 0xfe, 0x21, + 0x70, 0xd0, 0x4b, 0x44, 0xfc, 0xfe, 0xcf, 0x64, 0x4d, 0xb2, 0xfd, 0x24, + 0xf9, 0x2c, 0xd8, 0xd3, 0x4e, 0xe0, 0xcf, 0x36, 0x97, 0x86, 0x5c, 0x52, + 0xbe, 0x1d, 0x8c, 0xdc, 0xd5, 0x0e, 0xf4, 0xf1, 0x16, 0x6c, 0xa6, 0xb6, + 0x2c, 0xb3, 0xfd, 0xe5, 0xa0, 0x6e, 0xb4, 0xcd, 0x80, 0x6e, 0xf9, 0xb2, + 0xd9, 0x8f, 0xfd, 0x3d, 0xef, 0xcb, 0xb9, 0x00, 0xa7, 0xda, 0xbc, 0x85, + 0xb5, 0x32, 0xf8, 0xae, 0x1f, 0xd7, 0xfc, 0xf3, 0xf7, 0x87, 0xe7, 0xab, + 0x34, 0x05, 0xbc, 0x6b, 0x4d, 0x89, 0x0a, 0x2a, 0xef, 0xf1, 0x2e, 0xf7, + 0x97, 0x83, 0xbd, 0xa0, 0xb7, 0xe7, 0xfa, 0xd4, 0x7d, 0xb0, 0x25, 0xb6, + 0xb1, 0xda, 0x0a, 0xf3, 0x18, 0xfb, 0xe4, 0x99, 0xc7, 0xaa, 0x8f, 0xa3, + 0x3d, 0xcf, 0x7a, 0x44, 0x69, 0x89, 0x58, 0xcf, 0x2f, 0xb3, 0x2e, 0x41, + 0x3f, 0x03, 0xbd, 0xaa, 0x38, 0x2c, 0xff, 0x2f, 0x85, 0xf6, 0x29, 0x52, + 0x7f, 0x86, 0xf5, 0xfd, 0x05, 0x2a, 0xc0, 0xc6, 0xa7, 0x70, 0xd2, 0x22, + 0x68, 0x5a, 0x68, 0xf6, 0x81, 0x57, 0x6d, 0xbb, 0x83, 0x7c, 0x07, 0xff, + 0xc7, 0x0b, 0xe6, 0x77, 0x03, 0x27, 0xb6, 0x99, 0x9a, 0x2a, 0x52, 0x15, + 0x3f, 0xe8, 0x8d, 0xa1, 0x67, 0x6d, 0x49, 0x9f, 0x28, 0x03, 0x37, 0xe8, + 0x3d, 0xd9, 0x7b, 0x58, 0x9f, 0x31, 0xc7, 0xa5, 0xa1, 0xb6, 0x9d, 0x2d, + 0x38, 0x2c, 0xa7, 0x2e, 0x9c, 0xdb, 0xc6, 0x49, 0x46, 0x1f, 0xef, 0xa3, + 0x40, 0xe7, 0xdb, 0x3a, 0xc3, 0xfa, 0xa7, 0x5b, 0xeb, 0xd4, 0x41, 0xd9, + 0x0c, 0x7c, 0xd9, 0xbc, 0x08, 0xf9, 0xa5, 0xe1, 0x53, 0x64, 0x7a, 0xba, + 0x99, 0xa4, 0x63, 0x4d, 0xc6, 0xaf, 0x08, 0xbb, 0x83, 0x6f, 0x9b, 0x1f, + 0x85, 0x9d, 0x8d, 0x0b, 0x23, 0xb0, 0x89, 0x47, 0x17, 0x19, 0x27, 0x8f, + 0xd8, 0x2e, 0x8b, 0xcb, 0x65, 0x61, 0xd4, 0x2d, 0x09, 0xe3, 0xcb, 0x6c, + 0x27, 0x6c, 0x23, 0xba, 0xfa, 0x38, 0x31, 0x0d, 0x98, 0xe3, 0xfe, 0x22, + 0xc1, 0xb6, 0x5a, 0x3b, 0x17, 0x07, 0x1e, 0xdb, 0x80, 0x4f, 0x37, 0x6c, + 0x0f, 0xfa, 0x65, 0xe8, 0x13, 0xac, 0x33, 0xc5, 0x8c, 0xa1, 0xfd, 0x25, + 0x7d, 0x9c, 0x0f, 0x23, 0x1b, 0x7c, 0x18, 0x00, 0x4f, 0x3e, 0xcc, 0x87, + 0xfa, 0xc7, 0xf9, 0x60, 0x55, 0xc1, 0x87, 0x3a, 0xfc, 0x50, 0xdd, 0x65, + 0x9a, 0x3d, 0x12, 0xf7, 0x10, 0xb4, 0x93, 0xf6, 0x8a, 0x26, 0xeb, 0x28, + 0xdb, 0x49, 0x46, 0x9b, 0xc6, 0x0e, 0x4b, 0x4e, 0xb7, 0x6f, 0x1b, 0xa3, + 0x3e, 0x2f, 0x7e, 0x17, 0xbd, 0x4c, 0xdf, 0x1d, 0x9a, 0xc7, 0x17, 0xd9, + 0xdf, 0x40, 0xcf, 0x33, 0x86, 0x7a, 0x88, 0xee, 0xd0, 0xbd, 0xef, 0x0e, + 0xdd, 0x38, 0xa7, 0xed, 0x83, 0x98, 0xe6, 0xb6, 0x3f, 0x66, 0x5d, 0x79, + 0xc3, 0x93, 0x0c, 0x03, 0x32, 0x60, 0x7d, 0x61, 0x1c, 0x74, 0xf5, 0xcb, + 0xa0, 0xa7, 0x02, 0xbf, 0xc0, 0xb6, 0x54, 0xf6, 0xe7, 0x75, 0x50, 0xb9, + 0x27, 0x98, 0x3f, 0xd5, 0xf4, 0xfe, 0x4b, 0x34, 0x3f, 0xf0, 0xec, 0xbc, + 0x11, 0xda, 0xb8, 0x42, 0x7f, 0xb2, 0xa8, 0x97, 0x35, 0xa1, 0x9b, 0xaa, + 0xf7, 0xc3, 0xaf, 0x34, 0xd9, 0x3e, 0x76, 0xde, 0xc3, 0x97, 0xa5, 0x43, + 0x5f, 0xf6, 0x3e, 0x78, 0xcf, 0xb1, 0xe7, 0xe8, 0x07, 0xeb, 0x49, 0x7e, + 0x66, 0xd4, 0x09, 0x2a, 0x71, 0xbc, 0xd9, 0x21, 0xfa, 0xfe, 0xbb, 0x8f, + 0x63, 0x41, 0x55, 0x36, 0xe3, 0x54, 0xed, 0xa1, 0xaa, 0x64, 0xb2, 0x1d, + 0xb1, 0x6d, 0xb4, 0xf1, 0xde, 0x1e, 0xc6, 0xdd, 0x41, 0x89, 0x0c, 0x1e, + 0x47, 0x8c, 0x68, 0x32, 0x0d, 0xef, 0x87, 0xf2, 0x60, 0x7f, 0x4a, 0xb1, + 0x40, 0xdf, 0xf6, 0xc3, 0x5f, 0x32, 0x3f, 0x37, 0xeb, 0x0a, 0xfb, 0x51, + 0xd2, 0x44, 0x83, 0xfd, 0x28, 0xa9, 0x92, 0x79, 0x50, 0xb0, 0x16, 0xbf, + 0x26, 0x58, 0xe0, 0x9b, 0x05, 0xbe, 0x59, 0xe0, 0x9b, 0x0d, 0xbe, 0x15, + 0x5c, 0xc6, 0x85, 0xf1, 0x08, 0xf6, 0x2f, 0x06, 0xfb, 0x03, 0xc7, 0x9d, + 0x54, 0xf1, 0xed, 0x9b, 0x69, 0x85, 0x3f, 0xf6, 0x7d, 0xc1, 0xa8, 0x10, + 0xf8, 0x02, 0xde, 0x6f, 0x1c, 0xeb, 0x1f, 0x47, 0x8c, 0xb3, 0x44, 0xd1, + 0xb8, 0xc3, 0x8f, 0xfa, 0x26, 0x7e, 0x4c, 0x3b, 0xcc, 0x1f, 0x9e, 0xcf, + 0x76, 0xec, 0x40, 0xe6, 0x6d, 0x9e, 0xec, 0x07, 0x0e, 0x9d, 0x4c, 0x77, + 0x48, 0x07, 0xef, 0xdf, 0x1b, 0xee, 0x7f, 0x00, 0x7b, 0xb2, 0xdd, 0xde, + 0xed, 0x5c, 0x3e, 0x93, 0xe3, 0xe8, 0x27, 0xd1, 0x83, 0x3c, 0x02, 0x7e, + 0x66, 0x0d, 0x76, 0x76, 0x53, 0x4a, 0xd1, 0xeb, 0xbb, 0x6f, 0x20, 0xb7, + 0xa0, 0xea, 0x03, 0xa6, 0xa7, 0xc9, 0xe6, 0xfb, 0x5e, 0x3d, 0x0f, 0xdf, + 0x69, 0xea, 0x29, 0x5b, 0x1a, 0xa4, 0x37, 0xdc, 0x2c, 0xfd, 0x9d, 0x6b, + 0xd0, 0xdf, 0xba, 0x1a, 0xbd, 0xea, 0xa6, 0xe9, 0x6f, 0xdc, 0x14, 0xfd, + 0xb5, 0xdb, 0xce, 0x43, 0x92, 0xac, 0x47, 0x89, 0xa2, 0x7b, 0xb7, 0x5c, + 0x08, 0x3a, 0x8e, 0xbd, 0xec, 0xbc, 0x5c, 0x96, 0x4d, 0x3f, 0x3f, 0x98, + 0x98, 0x6e, 0x90, 0xb2, 0xd3, 0xa0, 0xed, 0xf7, 0x23, 0xef, 0x49, 0x9a, + 0xb4, 0xe3, 0x3e, 0x3c, 0x7b, 0x4d, 0xb2, 0x7a, 0xcc, 0x53, 0x9e, 0x68, + 0xb0, 0x1e, 0x75, 0x0f, 0x4f, 0xe5, 0xe3, 0x8c, 0xfb, 0xc4, 0x34, 0xfc, + 0x91, 0x8d, 0xb3, 0xaa, 0xd0, 0xc5, 0xaa, 0x7b, 0xe8, 0xfe, 0x20, 0x17, + 0x7a, 0x2f, 0xcc, 0x89, 0x38, 0xaf, 0x5a, 0x7f, 0x6a, 0xc2, 0x60, 0x3f, + 0x2b, 0x6c, 0xf2, 0xb3, 0x24, 0x14, 0x41, 0x53, 0x1d, 0xb8, 0x16, 0x41, + 0xe7, 0x57, 0x5d, 0x45, 0x28, 0x9c, 0xef, 0xa5, 0xe9, 0x45, 0x8e, 0x55, + 0x3c, 0x4f, 0x09, 0x73, 0x19, 0x7e, 0xef, 0xc0, 0x3b, 0x21, 0x7e, 0x14, + 0xb6, 0x53, 0x42, 0x7f, 0x73, 0x82, 0x9c, 0x30, 0x17, 0x89, 0xd1, 0x05, + 0x5f, 0x77, 0xb8, 0xdf, 0x2a, 0xfd, 0xb0, 0xff, 0x4e, 0xff, 0xf9, 0x8d, + 0xfe, 0x72, 0xe9, 0xeb, 0x1b, 0xfd, 0xef, 0xa8, 0x01, 0x4e, 0xc3, 0xc2, + 0xe3, 0xee, 0xf3, 0x61, 0xdf, 0x6d, 0xf0, 0xd3, 0xf3, 0xea, 0x88, 0x27, + 0x35, 0xe3, 0x36, 0x72, 0x1f, 0xf6, 0x29, 0x5b, 0xf1, 0x21, 0x1f, 0xf2, + 0x1f, 0xaa, 0x2d, 0xb1, 0x9c, 0x14, 0x0a, 0xf6, 0xe4, 0xf1, 0x4e, 0xf8, + 0x92, 0xdb, 0x68, 0x73, 0xec, 0x6a, 0xfb, 0x31, 0x9e, 0xc3, 0xeb, 0x6f, + 0xdd, 0x43, 0x96, 0x2a, 0x64, 0xb9, 0x35, 0x79, 0xd5, 0x1a, 0xa7, 0x42, + 0x9f, 0xd0, 0x3d, 0x6c, 0x43, 0x2e, 0x12, 0xe4, 0x52, 0x83, 0x5c, 0x0a, + 0xf7, 0x94, 0x0b, 0xce, 0xd8, 0xd0, 0x29, 0xc6, 0xa3, 0x2b, 0x3c, 0x9b, + 0x14, 0xd9, 0xac, 0x96, 0xea, 0xc6, 0xa7, 0x28, 0x66, 0x30, 0x1e, 0x06, + 0xf0, 0x38, 0x8a, 0xb5, 0x1c, 0xc3, 0x48, 0x89, 0x99, 0x2c, 0xcf, 0xdc, + 0x13, 0xb6, 0x71, 0xab, 0xb4, 0xe0, 0xdc, 0x2a, 0x5d, 0x34, 0xf8, 0xfd, + 0xf6, 0x64, 0x90, 0x37, 0x77, 0x3f, 0x89, 0xbc, 0x19, 0xeb, 0xd9, 0x1f, + 0x72, 0xff, 0x30, 0xe6, 0x71, 0x7c, 0xa0, 0x43, 0x35, 0xfc, 0xea, 0xfe, + 0xdc, 0x6b, 0x4f, 0xf0, 0xdc, 0x4e, 0x53, 0x9e, 0xfc, 0x35, 0x9e, 0x1d, + 0xa6, 0xf6, 0xe4, 0x4f, 0x0d, 0xde, 0x77, 0x78, 0xf2, 0xa2, 0xbf, 0x07, + 0x62, 0xa6, 0xbf, 0x36, 0xfb, 0x24, 0xaf, 0x7d, 0x0e, 0x3e, 0xf6, 0x0c, + 0xe2, 0xcb, 0x69, 0x47, 0x3b, 0x54, 0xc1, 0x6f, 0x8a, 0x71, 0x6a, 0xf2, + 0xb8, 0x85, 0x71, 0x19, 0xb1, 0x90, 0xdb, 0x0a, 0x1d, 0xc3, 0xbc, 0xa7, + 0x31, 0xef, 0xa8, 0x33, 0x8e, 0xbc, 0xbd, 0x4d, 0xd7, 0xbf, 0xc5, 0x0b, + 0xf3, 0xec, 0xcf, 0x91, 0xed, 0xaf, 0xfc, 0x7b, 0xdc, 0x86, 0x5f, 0x16, + 0x57, 0x6e, 0xc6, 0x0b, 0xa0, 0x5b, 0x5a, 0xf9, 0x45, 0xbc, 0x08, 0x3d, + 0x13, 0x0d, 0x09, 0x7e, 0xf9, 0x33, 0x54, 0x53, 0x3d, 0x7a, 0x19, 0xf1, + 0xab, 0x96, 0x85, 0xbf, 0x82, 0x34, 0x45, 0x03, 0x7e, 0x4c, 0x25, 0xa5, + 0xcb, 0x3c, 0xa9, 0x52, 0x57, 0x3e, 0x6e, 0x23, 0xde, 0xd4, 0x54, 0x09, + 0xfd, 0xfd, 0x78, 0x6e, 0xee, 0xff, 0x65, 0x1c, 0x7e, 0x0b, 0x3e, 0x82, + 0x14, 0x3b, 0xdf, 0x8d, 0xfd, 0xbf, 0x8d, 0x7e, 0x4c, 0xc8, 0x6c, 0xf4, + 0x3f, 0x1b, 0xf4, 0xdf, 0x02, 0x2e, 0xbc, 0x8e, 0xe3, 0x27, 0x29, 0x53, + 0x79, 0x15, 0x38, 0xf0, 0xdc, 0xa4, 0x3f, 0xb7, 0x38, 0xcf, 0x3c, 0xa8, + 0x96, 0x16, 0x8c, 0x34, 0x15, 0xe6, 0x92, 0x34, 0x3a, 0xa7, 0xd2, 0xd8, + 0x9c, 0x3e, 0xd1, 0x62, 0xfb, 0x01, 0xcd, 0x84, 0x1c, 0x41, 0x5c, 0x21, + 0x50, 0xac, 0xa7, 0x9e, 0xa6, 0xbe, 0xd4, 0x31, 0xfa, 0x6f, 0x0f, 0xb1, + 0x08, 0x71, 0xa8, 0x9b, 0x64, 0x7f, 0x9f, 0x54, 0xfb, 0x4c, 0x96, 0xd1, + 0x87, 0xce, 0x2d, 0xce, 0xdf, 0x6b, 0x5f, 0x28, 0xf1, 0x4a, 0xea, 0x23, + 0xfb, 0xbe, 0x1b, 0xee, 0xab, 0x62, 0xdf, 0x34, 0xf6, 0x64, 0x1a, 0xf5, + 0xf8, 0xc8, 0x79, 0xb2, 0x3a, 0x81, 0x5f, 0x31, 0x83, 0x98, 0x8f, 0x7d, + 0xce, 0xcc, 0xb1, 0xde, 0xd3, 0x4e, 0xfc, 0x06, 0x63, 0x94, 0xc9, 0x2e, + 0x23, 0x27, 0x18, 0xf1, 0xf7, 0x08, 0xf2, 0x05, 0x71, 0x65, 0x10, 0xf9, + 0xda, 0x3b, 0xc0, 0x87, 0xe3, 0x18, 0xd3, 0x2c, 0x83, 0xde, 0x41, 0xe4, + 0x09, 0x9c, 0xe3, 0x7b, 0xa7, 0xec, 0x1c, 0xda, 0xcb, 0x5a, 0xbc, 0x00, + 0xdb, 0x16, 0x4d, 0x7a, 0x50, 0xf2, 0x7d, 0x2c, 0xcb, 0x65, 0x10, 0x72, + 0x62, 0xbc, 0x73, 0x90, 0x13, 0xf3, 0x68, 0x38, 0x5e, 0x6c, 0x32, 0x8f, + 0x08, 0xf8, 0x68, 0xb0, 0x27, 0xd9, 0xcf, 0xf3, 0xc5, 0x15, 0x0b, 0xf3, + 0x7e, 0xac, 0x72, 0x2e, 0x66, 0x1b, 0xdc, 0x86, 0xed, 0xac, 0x8c, 0x63, + 0x2e, 0xb7, 0x1f, 0xc6, 0xbe, 0x7d, 0xb9, 0x1a, 0x75, 0xe4, 0x9e, 0x86, + 0xdd, 0x8a, 0xf9, 0x01, 0xc4, 0x68, 0x01, 0xb9, 0xa0, 0xe7, 0x75, 0xe4, + 0xbf, 0x00, 0x7a, 0x98, 0x0e, 0xe8, 0xf5, 0x2c, 0xf3, 0x95, 0xfe, 0x40, + 0xe4, 0x5c, 0x2d, 0xdf, 0xce, 0x6b, 0x38, 0x9e, 0xf3, 0xf9, 0x88, 0x23, + 0x8d, 0x3d, 0x88, 0xa5, 0xfe, 0xd9, 0xd0, 0xb1, 0x71, 0x2a, 0x34, 0x3e, + 0x8b, 0x9c, 0x93, 0x6d, 0x67, 0x9b, 0x60, 0x9f, 0x67, 0x1a, 0x09, 0xb1, + 0x66, 0x8d, 0x2a, 0x0d, 0x39, 0x6c, 0xbf, 0x8a, 0xb6, 0x12, 0xb6, 0xd7, + 0xd1, 0xee, 0x0e, 0xdb, 0xd7, 0xd0, 0x56, 0xc3, 0xf6, 0xcf, 0xd0, 0x4e, + 0x86, 0xed, 0x9f, 0xa3, 0x9d, 0x0a, 0xdb, 0x37, 0xd1, 0x4e, 0x87, 0xed, + 0x5b, 0x68, 0x6b, 0x61, 0xfb, 0x3d, 0xb4, 0x13, 0xb0, 0x73, 0x03, 0xef, + 0x37, 0x50, 0x2b, 0x66, 0xf1, 0xfc, 0x57, 0xe0, 0x36, 0x08, 0xde, 0x64, + 0xc1, 0x8f, 0x5e, 0x8c, 0xe5, 0xd0, 0x87, 0x1c, 0xb1, 0x91, 0xc7, 0xd3, + 0xc1, 0x18, 0x95, 0x61, 0x7b, 0x18, 0x1f, 0x2f, 0x16, 0x1a, 0x26, 0x9e, + 0x6c, 0x0f, 0xba, 0x4a, 0xc2, 0x65, 0xd8, 0xb9, 0xef, 0x63, 0x72, 0xb6, + 0x34, 0x09, 0xdb, 0x9e, 0xa0, 0x7f, 0x74, 0xf7, 0xd3, 0x6b, 0xee, 0x38, + 0xe2, 0x46, 0x11, 0x71, 0xc3, 0x42, 0xdc, 0x30, 0x11, 0x37, 0x86, 0x11, + 0x37, 0xf2, 0x88, 0x1b, 0x39, 0xc4, 0x0d, 0xa2, 0x33, 0x7e, 0x8c, 0x4a, + 0x2a, 0xa8, 0x51, 0x15, 0xcb, 0x2d, 0x82, 0xbf, 0x13, 0x90, 0xcd, 0x24, + 0x78, 0x7d, 0x38, 0x3e, 0xd2, 0xcc, 0xc3, 0x9f, 0x69, 0xf0, 0x11, 0x69, + 0xf8, 0xf2, 0x1c, 0x6a, 0x13, 0xa2, 0x2b, 0xb3, 0x1a, 0xfc, 0x8f, 0x47, + 0x45, 0xc4, 0xfe, 0x69, 0x15, 0xb8, 0x19, 0xbb, 0x7c, 0x9b, 0x91, 0xcc, + 0x2f, 0xf6, 0x50, 0xd7, 0x20, 0xe8, 0x39, 0x8b, 0xbe, 0x14, 0xf6, 0x63, + 0xbe, 0xde, 0x2a, 0xd9, 0x86, 0x46, 0x0b, 0x6e, 0x1c, 0xfe, 0x9f, 0xdf, + 0xe3, 0xcc, 0xe3, 0x43, 0x4f, 0x19, 0x4c, 0x03, 0xea, 0x3c, 0x23, 0xad, + 0x14, 0x1c, 0x81, 0x24, 0x93, 0x9f, 0xed, 0x1c, 0xe2, 0xcf, 0x90, 0x43, + 0x74, 0x41, 0x06, 0x55, 0xc4, 0x05, 0x9d, 0xf3, 0x0b, 0xe8, 0xf2, 0x27, + 0xcd, 0xff, 0x1e, 0xe6, 0xef, 0xc5, 0xd9, 0x3c, 0x8f, 0xcf, 0x39, 0x85, + 0xfa, 0xc1, 0xea, 0x91, 0x68, 0x3d, 0x25, 0xa1, 0x9e, 0x28, 0xd0, 0x59, + 0x2a, 0x00, 0x9f, 0x82, 0xdb, 0xbe, 0x07, 0xb0, 0x0e, 0x05, 0xfe, 0x6c, + 0xe2, 0xd0, 0xb7, 0x0d, 0x0b, 0xeb, 0x18, 0x3f, 0xd6, 0x5b, 0xe0, 0xbe, + 0xb1, 0xe7, 0x05, 0xec, 0xf9, 0x4f, 0x49, 0xea, 0x9a, 0x0c, 0xfc, 0x91, + 0x5f, 0xf3, 0xca, 0xc2, 0x48, 0xf3, 0x2c, 0xf8, 0xd3, 0x87, 0x1a, 0x05, + 0x7e, 0xa4, 0xd4, 0x02, 0x9f, 0xda, 0xf3, 0x5f, 0xc1, 0x7c, 0x7e, 0xf7, + 0xef, 0x0e, 0x4a, 0xd2, 0xea, 0x12, 0xe6, 0x69, 0xac, 0x3f, 0x25, 0xb9, + 0xff, 0x86, 0xf7, 0xa2, 0x91, 0xa7, 0x5d, 0xab, 0xbc, 0x2e, 0x4b, 0x7d, + 0xab, 0x37, 0xbc, 0x9a, 0xa3, 0xd1, 0x62, 0x93, 0xc0, 0xab, 0xf8, 0x6d, + 0x8b, 0xf4, 0x35, 0x12, 0xf5, 0x59, 0x0b, 0x7a, 0x5a, 0x1c, 0x12, 0xc9, + 0x1e, 0xea, 0x84, 0x8f, 0x32, 0x68, 0x09, 0x7c, 0xdf, 0x35, 0x63, 0xd1, + 0x13, 0x43, 0xed, 0x7c, 0x10, 0x51, 0x0f, 0xb8, 0xee, 0x5a, 0xd5, 0x30, + 0x87, 0x73, 0x71, 0xa6, 0x45, 0x03, 0x2f, 0x85, 0x60, 0x8d, 0x1f, 0xb3, + 0xb8, 0x8e, 0x05, 0xdf, 0xdc, 0xb5, 0xd2, 0xd5, 0x19, 0xd4, 0x1a, 0x90, + 0xf3, 0xae, 0x19, 0xae, 0x85, 0xb6, 0x81, 0x2f, 0x31, 0xd8, 0x06, 0xe7, + 0xf1, 0x08, 0xf4, 0xf0, 0x87, 0x27, 0xe0, 0xf1, 0x6b, 0xcd, 0x13, 0xd0, + 0xfb, 0x2e, 0x2a, 0xcb, 0x3e, 0x11, 0x9f, 0xc0, 0xe3, 0xff, 0xe4, 0xbc, + 0x0e, 0xf3, 0xbf, 0x4b, 0xc5, 0xd9, 0x2e, 0xec, 0xb5, 0x9b, 0xa6, 0x93, + 0x8c, 0x9b, 0x3e, 0x8c, 0x41, 0x2d, 0x06, 0x7e, 0xc6, 0xcd, 0x8f, 0xe6, + 0x7d, 0x6b, 0xa5, 0x2b, 0x33, 0x6b, 0xa5, 0x6b, 0xa0, 0xbf, 0x6e, 0x70, + 0x8d, 0x0c, 0x5d, 0x6a, 0x70, 0x6d, 0xcf, 0x79, 0xd1, 0x18, 0x74, 0x64, + 0xbf, 0x5f, 0x33, 0xdb, 0x8b, 0x39, 0xea, 0x3b, 0x47, 0xaa, 0x68, 0x96, + 0x84, 0x31, 0xe4, 0x45, 0x23, 0xee, 0x49, 0x7f, 0xee, 0x99, 0x06, 0xd7, + 0x2b, 0x18, 0x5b, 0x61, 0x5d, 0x18, 0x03, 0x3e, 0x49, 0xba, 0xe8, 0xb2, + 0x4f, 0x0a, 0xec, 0x78, 0x0c, 0xfc, 0x5a, 0xf0, 0xe9, 0x4a, 0x71, 0x1c, + 0x47, 0xbe, 0xc1, 0xf2, 0xf9, 0x21, 0xc7, 0x41, 0xa1, 0xd3, 0x6c, 0xfb, + 0xdb, 0x89, 0x5e, 0xe6, 0x59, 0xa1, 0x01, 0xdf, 0x3f, 0x34, 0x11, 0xe6, + 0x1c, 0x7f, 0x8f, 0x39, 0x8c, 0x3b, 0xcd, 0x4a, 0x26, 0xce, 0xc8, 0x33, + 0xcf, 0x38, 0xa7, 0xe4, 0x7d, 0xc1, 0x5b, 0xf0, 0x7d, 0x53, 0x6e, 0xe9, + 0xc3, 0x74, 0x33, 0x46, 0x95, 0x59, 0xf0, 0x2e, 0x8f, 0x27, 0x9c, 0x6b, + 0x1d, 0x7c, 0x03, 0x2d, 0xd5, 0x20, 0x9f, 0x3d, 0xc1, 0x31, 0x0d, 0xfe, + 0x06, 0x36, 0xcd, 0x31, 0x6b, 0xe3, 0xde, 0xc9, 0xf7, 0x25, 0x32, 0x19, + 0x41, 0xce, 0x2a, 0xe2, 0x2c, 0x3b, 0xcf, 0x7e, 0x10, 0xf8, 0xb8, 0xdf, + 0xa5, 0xfa, 0x2c, 0xd3, 0x05, 0x1b, 0x4f, 0xb2, 0x2e, 0xfe, 0x7f, 0xf9, + 0x38, 0xba, 0x45, 0x3e, 0x8e, 0x6e, 0x99, 0x8f, 0x12, 0xf8, 0x58, 0xd9, + 0xe0, 0xa3, 0x82, 0x3d, 0xf8, 0x3e, 0xe1, 0xab, 0x64, 0x4d, 0x3c, 0x02, + 0x3f, 0x0c, 0xff, 0xd1, 0x3c, 0x05, 0x9f, 0x70, 0x52, 0xb8, 0xda, 0xf0, + 0x68, 0x1c, 0xb5, 0xb2, 0x74, 0xff, 0x66, 0xfa, 0x33, 0xa0, 0xff, 0xcf, + 0x31, 0x5e, 0xa5, 0x6b, 0xb3, 0x94, 0x56, 0xa8, 0x7d, 0x2e, 0xed, 0x92, + 0xe9, 0x3b, 0x74, 0x75, 0xb6, 0x8b, 0xae, 0xcf, 0x66, 0xc0, 0xeb, 0x2c, + 0xc5, 0x7a, 0x32, 0xc3, 0x15, 0x18, 0xf1, 0xcf, 0x5a, 0xba, 0xc5, 0xba, + 0xf8, 0xfb, 0xf3, 0x82, 0xf9, 0x70, 0xd0, 0xe7, 0xc3, 0xd8, 0x47, 0xf8, + 0x30, 0x7e, 0x4f, 0x3e, 0x1c, 0xfc, 0x18, 0x1f, 0xc6, 0x3f, 0xc6, 0x07, + 0xe6, 0x01, 0xf3, 0xe2, 0xd1, 0xde, 0xf0, 0xff, 0x1f, 0x7d, 0x82, 0x7d, + 0x7c, 0x09, 0x74, 0x22, 0xa7, 0xd8, 0x19, 0xe4, 0x50, 0x9c, 0x63, 0xd5, + 0x0c, 0xe6, 0x57, 0x60, 0xbf, 0x32, 0x72, 0xea, 0x23, 0xa1, 0xfd, 0x16, + 0x1c, 0xe8, 0x65, 0x23, 0xe6, 0xdb, 0xaf, 0x64, 0xe6, 0xe1, 0x03, 0xaa, + 0xa5, 0x96, 0xc3, 0xfe, 0x07, 0x6d, 0x87, 0x79, 0xda, 0x0b, 0x5a, 0x12, + 0x54, 0x99, 0x54, 0x10, 0x5f, 0x87, 0xa1, 0xb7, 0x71, 0xdf, 0x07, 0x4a, + 0x26, 0xeb, 0xe1, 0x7e, 0xcc, 0x3f, 0x1c, 0xe6, 0x45, 0x88, 0x73, 0x38, + 0xa3, 0xd6, 0x38, 0x0d, 0xfc, 0xf8, 0x9c, 0x6a, 0xa9, 0xec, 0xf0, 0x9a, + 0x34, 0x62, 0x21, 0x3f, 0x37, 0xeb, 0xb7, 0xaf, 0xef, 0xf7, 0xd2, 0x71, + 0xe8, 0x26, 0xeb, 0xb4, 0x82, 0xdc, 0x78, 0x02, 0xf1, 0xc5, 0xd7, 0xd3, + 0xec, 0x02, 0xb1, 0xdf, 0x7f, 0x06, 0x75, 0xd1, 0x61, 0xfc, 0x34, 0x1a, + 0x71, 0x03, 0x9b, 0x5a, 0xf2, 0xcf, 0xfc, 0xb0, 0x4f, 0xaa, 0x39, 0xeb, + 0xc8, 0xdf, 0x0d, 0xec, 0xcb, 0xe7, 0x56, 0xc1, 0x1b, 0x09, 0xe7, 0x72, + 0x5f, 0x37, 0xe2, 0x00, 0xf8, 0xe4, 0xfe, 0x07, 0xfa, 0x97, 0xe0, 0x1f, + 0x39, 0x2f, 0x68, 0xe3, 0x8e, 0x1c, 0xc2, 0xe1, 0x78, 0x9d, 0x07, 0xcd, + 0x9c, 0x63, 0x73, 0x2e, 0x81, 0xfc, 0x63, 0xe9, 0x4d, 0xf4, 0x0d, 0xd3, + 0xe9, 0xa1, 0x2c, 0xe4, 0xc3, 0x7d, 0x0f, 0x84, 0x7d, 0x3c, 0x8f, 0x94, + 0x07, 0x4d, 0xfd, 0x07, 0x55, 0xdf, 0xaf, 0x43, 0x0f, 0x51, 0xf7, 0xd5, + 0x96, 0x90, 0x63, 0x00, 0xa7, 0xca, 0x6a, 0x16, 0xb9, 0x3c, 0xdf, 0xab, + 0xe9, 0x97, 0x91, 0x07, 0x83, 0x27, 0x0a, 0xf5, 0x1a, 0xa5, 0xd0, 0x0f, + 0xe7, 0x40, 0x1f, 0xdf, 0x3d, 0xf5, 0x21, 0xf7, 0x91, 0xc0, 0x08, 0xd8, + 0xe9, 0xaa, 0x44, 0x7b, 0xe5, 0x01, 0xb5, 0x46, 0xff, 0x80, 0xb9, 0x32, + 0x95, 0x57, 0x39, 0x87, 0x90, 0xe9, 0xc8, 0x2a, 0xd1, 0x5b, 0x33, 0xec, + 0x97, 0x19, 0xd8, 0x2f, 0xb3, 0x7f, 0x7d, 0xd0, 0x1f, 0x7b, 0x6b, 0x06, + 0x35, 0xf8, 0xcc, 0x00, 0xc7, 0xb0, 0x75, 0x11, 0xbc, 0x44, 0xee, 0xc3, + 0xf9, 0xf9, 0x5d, 0xee, 0x98, 0xda, 0xf7, 0x4b, 0x0a, 0x55, 0x66, 0xf8, + 0x6e, 0x49, 0xc6, 0xf9, 0x5c, 0x5b, 0x6c, 0x03, 0x7e, 0x02, 0xa1, 0xee, + 0x12, 0x38, 0xa6, 0x09, 0xd0, 0xa1, 0x5d, 0x90, 0x3d, 0xf8, 0x1f, 0xb6, + 0xdb, 0xfa, 0xf4, 0x2f, 0xd0, 0x27, 0x9e, 0x27, 0x6f, 0xc2, 0x25, 0x33, + 0x6b, 0x8b, 0x1c, 0x1f, 0x3e, 0x0d, 0xdb, 0xb3, 0xe2, 0x63, 0xcd, 0x0e, + 0x6a, 0xf5, 0xb2, 0x3d, 0xb0, 0x5e, 0x5c, 0x66, 0x9d, 0xc0, 0x19, 0xd0, + 0xa1, 0x19, 0xae, 0xe7, 0x65, 0xcc, 0xbb, 0x2f, 0x9c, 0xc7, 0xfc, 0xfe, + 0x1e, 0x4d, 0x0f, 0xa9, 0x42, 0x59, 0x0d, 0xe2, 0x45, 0x6d, 0xa8, 0x03, + 0x63, 0x22, 0x1d, 0x7c, 0x38, 0x8f, 0xb5, 0x9c, 0x53, 0xc5, 0x85, 0xc0, + 0x6f, 0x71, 0x1f, 0xdf, 0xd7, 0xa9, 0x54, 0xbe, 0xd4, 0x4b, 0x95, 0x4b, + 0x0a, 0xf8, 0x02, 0x44, 0x17, 0x82, 0x7d, 0xd8, 0x17, 0x1c, 0x87, 0xdc, + 0xc4, 0x73, 0x0a, 0xc5, 0xce, 0x21, 0x87, 0xbc, 0xd0, 0x45, 0x1d, 0x17, + 0xfa, 0x49, 0xba, 0xa0, 0x73, 0x7e, 0xa8, 0x9d, 0x81, 0x0c, 0x8f, 0x50, + 0x9e, 0x9e, 0x73, 0x07, 0x39, 0xc7, 0xc3, 0x39, 0x5c, 0xe7, 0x25, 0x49, + 0x42, 0xf2, 0x2f, 0xbe, 0x68, 0xd1, 0x8b, 0x43, 0xc0, 0x2b, 0x8f, 0xf6, + 0x8f, 0x91, 0xc7, 0xbb, 0x23, 0xf7, 0x71, 0xcc, 0x96, 0xcd, 0x3e, 0xc8, + 0x16, 0x74, 0xe5, 0x1e, 0xf2, 0xef, 0x44, 0x5f, 0x1c, 0x62, 0x7a, 0x34, + 0xd0, 0x52, 0x87, 0xae, 0xf3, 0x3d, 0x57, 0x17, 0xd9, 0x32, 0xeb, 0x32, + 0xf2, 0xaa, 0x0b, 0x75, 0x9a, 0x6a, 0xe8, 0x90, 0x59, 0x1f, 0xf4, 0x02, + 0x32, 0x4b, 0x73, 0x3f, 0xef, 0x2d, 0x84, 0xfb, 0xde, 0xd1, 0xf7, 0x17, + 0xef, 0xad, 0xef, 0x3e, 0xd4, 0x9b, 0x8f, 0xc0, 0x67, 0xa3, 0x2e, 0x32, + 0xe0, 0xd3, 0x55, 0xe4, 0x72, 0x06, 0xbf, 0x07, 0x77, 0x95, 0x15, 0xe4, + 0x85, 0xfc, 0x5e, 0x6b, 0xdd, 0xcd, 0x77, 0x07, 0xf6, 0x7d, 0x06, 0x3c, + 0xba, 0x32, 0xf7, 0x00, 0x5d, 0x9d, 0x53, 0xe8, 0x5a, 0x43, 0xcf, 0x16, + 0xa8, 0x83, 0xaa, 0xc9, 0x34, 0x5d, 0x5f, 0x6a, 0xe7, 0x93, 0x22, 0xf4, + 0xc4, 0x22, 0xce, 0xcd, 0xaf, 0x2c, 0x55, 0x4b, 0x37, 0x76, 0xa7, 0x49, + 0x7e, 0x09, 0xb6, 0xfd, 0x92, 0xae, 0xd5, 0xc0, 0xe7, 0xba, 0xe1, 0xa2, + 0x56, 0xe3, 0x3a, 0x32, 0x05, 0xbb, 0xd3, 0x53, 0x2d, 0xca, 0x90, 0xb4, + 0xa0, 0xd0, 0xaf, 0x66, 0x74, 0x8d, 0x75, 0xee, 0xa2, 0x81, 0x7e, 0x37, + 0x7e, 0x7b, 0x3d, 0xd0, 0x43, 0xf4, 0xf5, 0xa3, 0xbe, 0xd5, 0xb3, 0x9a, + 0xd8, 0x4d, 0x6f, 0x43, 0x27, 0xca, 0x7e, 0xdf, 0x47, 0xf7, 0xbc, 0x1e, + 0xee, 0x59, 0x2d, 0x5d, 0xe1, 0x3a, 0x68, 0x86, 0x75, 0xbe, 0x17, 0xfe, + 0x03, 0xef, 0x6e, 0x07, 0x95, 0x27, 0x11, 0xa3, 0x66, 0x1e, 0xa5, 0xc2, + 0x90, 0x18, 0xd0, 0xed, 0xf3, 0x82, 0xfb, 0xf8, 0x7e, 0xb2, 0x76, 0x1f, + 0xdb, 0xb2, 0xb8, 0x0a, 0xbd, 0x3a, 0xc8, 0x7a, 0x80, 0xdc, 0x0e, 0x39, + 0x04, 0xfb, 0x4e, 0x09, 0x39, 0x44, 0xc1, 0x0d, 0x74, 0xa3, 0x75, 0x30, + 0x49, 0xc7, 0x5e, 0x62, 0x19, 0x61, 0x6c, 0x43, 0xef, 0x36, 0xee, 0xc4, + 0x31, 0x66, 0xd0, 0xf1, 0xef, 0xb7, 0x73, 0x4a, 0xb6, 0xbd, 0x34, 0xe4, + 0xa1, 0xa3, 0xf6, 0xe8, 0x53, 0x2b, 0xbe, 0x4f, 0x81, 0x4e, 0xa4, 0x02, + 0x19, 0xd4, 0x30, 0x36, 0xed, 0x4e, 0xc2, 0x27, 0xc6, 0xe8, 0xe6, 0xa4, + 0x05, 0x9d, 0x68, 0x01, 0x87, 0xc3, 0x71, 0xbe, 0x4b, 0xb8, 0x39, 0x59, + 0xc4, 0xfb, 0x61, 0x3f, 0xf7, 0x97, 0xf6, 0x40, 0x97, 0xdc, 0x07, 0xc2, + 0xfc, 0x9c, 0xcf, 0xd3, 0x84, 0xda, 0xac, 0x2e, 0x4c, 0xcf, 0x7a, 0x34, + 0x9a, 0xeb, 0x4b, 0x5d, 0xa5, 0x4e, 0xff, 0xce, 0xd8, 0xf7, 0x9b, 0xfe, + 0x9c, 0x5d, 0x18, 0xff, 0x00, 0x3a, 0x85, 0x27, 0xe2, 0xf5, 0xe9, 0x66, + 0x35, 0xd5, 0x41, 0xac, 0x53, 0x24, 0x2c, 0x18, 0xec, 0x3b, 0x04, 0xba, + 0xea, 0xdf, 0x47, 0x13, 0x15, 0x9d, 0xd7, 0x99, 0x6e, 0x61, 0xb1, 0xc5, + 0x6b, 0x58, 0xce, 0xbc, 0x46, 0xa2, 0x9b, 0x49, 0xd8, 0xe5, 0x9e, 0x3d, + 0x7e, 0xbd, 0xf8, 0xf8, 0x10, 0xe3, 0xda, 0x0d, 0x99, 0x42, 0xbf, 0x50, + 0xdb, 0x94, 0x83, 0xbe, 0x59, 0xae, 0x4d, 0xa7, 0xf9, 0xde, 0x23, 0xef, + 0xeb, 0x5a, 0xa8, 0x1f, 0x1f, 0xd7, 0xb5, 0xe7, 0xb0, 0xf6, 0x2d, 0xf6, + 0xab, 0x90, 0x75, 0xe0, 0x23, 0xbe, 0x41, 0x6f, 0xcd, 0x55, 0xb3, 0xfc, + 0xcd, 0xa3, 0x35, 0x21, 0xa0, 0x16, 0x3f, 0x4e, 0x6f, 0xcf, 0x3d, 0x4b, + 0xbf, 0x9c, 0x65, 0xdd, 0x31, 0x68, 0x14, 0xfa, 0x74, 0x94, 0xe4, 0xec, + 0x69, 0x1a, 0x50, 0xaf, 0xfb, 0xb5, 0x8d, 0x9e, 0xf3, 0x6b, 0x3a, 0x33, + 0x4b, 0xc5, 0xc6, 0x40, 0xea, 0x1a, 0xfa, 0xca, 0x93, 0xba, 0xb6, 0x8e, + 0xdc, 0xa3, 0xd0, 0xfc, 0x80, 0xef, 0x6c, 0xb2, 0x35, 0xd8, 0xde, 0x22, + 0x6a, 0x9b, 0xb7, 0x9d, 0xbb, 0xe9, 0x2c, 0xd7, 0x56, 0x81, 0xff, 0x5e, + 0x33, 0x50, 0x63, 0xac, 0xaa, 0xa1, 0x0e, 0x31, 0x70, 0x9d, 0xc1, 0xf1, + 0x07, 0x4f, 0x37, 0x06, 0x9f, 0xb2, 0x1f, 0x7c, 0x67, 0xd9, 0x42, 0xfe, + 0xab, 0xfc, 0x8d, 0x0a, 0xf2, 0x5f, 0x5d, 0xfe, 0x40, 0xeb, 0x65, 0x3f, + 0x6b, 0x80, 0x96, 0x41, 0x3a, 0x33, 0xcf, 0xf2, 0x47, 0xec, 0xf5, 0xed, + 0x34, 0x0d, 0xfe, 0x72, 0x7c, 0x19, 0xa4, 0x5f, 0x2d, 0x15, 0xfd, 0xfb, + 0x6b, 0x1b, 0xb9, 0xd6, 0x11, 0x67, 0x12, 0xf5, 0xfa, 0x77, 0x40, 0x2f, + 0xce, 0x1e, 0xda, 0x8d, 0xa7, 0x0a, 0x9b, 0xdc, 0x72, 0x9e, 0x23, 0x07, + 0x79, 0xce, 0xde, 0x2d, 0xe6, 0x39, 0x7b, 0xb7, 0x92, 0xe7, 0xc8, 0x9d, + 0xe0, 0xab, 0xd6, 0xbb, 0x65, 0xdc, 0xa4, 0x00, 0xb7, 0x03, 0x5b, 0xc4, + 0xed, 0xc0, 0x56, 0x70, 0x93, 0x3a, 0xcd, 0xbf, 0x40, 0x8c, 0x35, 0x10, + 0xdb, 0xe0, 0xd7, 0x86, 0xfa, 0x59, 0x7f, 0x80, 0xa3, 0x8f, 0xeb, 0xef, + 0x8b, 0xa7, 0x18, 0xe0, 0xf9, 0xd8, 0x16, 0xf1, 0x7c, 0x6c, 0x2b, 0x78, + 0x8a, 0x9d, 0x26, 0xe3, 0x28, 0xc3, 0xd7, 0x70, 0x6d, 0x83, 0xd8, 0x3c, + 0x24, 0x87, 0xba, 0x2e, 0x87, 0x75, 0x0e, 0x03, 0x7c, 0x50, 0xaf, 0x46, + 0x4b, 0x4c, 0xcb, 0x46, 0xdf, 0x9d, 0x3a, 0x4b, 0x32, 0x5b, 0xa5, 0x4a, + 0x83, 0xef, 0x95, 0xfb, 0xb0, 0x0f, 0xf7, 0xf1, 0x37, 0x2a, 0x8b, 0x64, + 0xc4, 0xf7, 0xe7, 0x9a, 0x77, 0xa7, 0xf5, 0x2a, 0x68, 0x9d, 0x0a, 0x69, + 0xad, 0xf8, 0xb9, 0xe0, 0xbe, 0x4d, 0xb9, 0x60, 0x40, 0xe3, 0x08, 0x68, + 0x2c, 0x86, 0x34, 0x3e, 0xdd, 0x60, 0xda, 0xf6, 0xf9, 0xb4, 0x2d, 0x6d, + 0xa2, 0x6d, 0xe4, 0x9e, 0xf9, 0x1f, 0xe3, 0x81, 0x5a, 0x1a, 0xb9, 0xd7, + 0x6b, 0x4d, 0xd4, 0xd2, 0x4d, 0xd4, 0xd2, 0xd0, 0xf7, 0x57, 0x9b, 0xa8, + 0xa5, 0x9b, 0xa8, 0xa5, 0x61, 0x07, 0xaf, 0xc0, 0x56, 0x82, 0x3b, 0xdc, + 0x12, 0x71, 0x0d, 0xee, 0xd7, 0xe3, 0x14, 0xe4, 0x39, 0x05, 0xc4, 0xf0, + 0xa3, 0xc8, 0xf1, 0xd8, 0x6e, 0x4f, 0x13, 0xc7, 0x04, 0x3d, 0x87, 0x9a, + 0x2f, 0x5b, 0x25, 0x33, 0x5e, 0x9c, 0x1f, 0x50, 0x97, 0x02, 0xfb, 0xd6, + 0x5a, 0xc4, 0x71, 0x70, 0x20, 0x85, 0x08, 0xa9, 0xb2, 0x5f, 0xb0, 0x73, + 0x4c, 0xe7, 0x76, 0xf0, 0x10, 0xbe, 0xdb, 0x60, 0x1f, 0xc6, 0xbe, 0xb4, + 0x4e, 0x0b, 0x8d, 0xf0, 0x1b, 0x9a, 0xcc, 0xfd, 0xfc, 0xce, 0x31, 0xb7, + 0xcf, 0xf7, 0x69, 0x76, 0xb6, 0x0f, 0x71, 0x80, 0xfb, 0x15, 0xf8, 0x35, + 0xe8, 0xca, 0x52, 0x1b, 0x17, 0x19, 0xeb, 0x55, 0xaa, 0xcf, 0x07, 0x31, + 0x7c, 0xca, 0xe0, 0x38, 0x87, 0xf8, 0xbe, 0xc4, 0xdf, 0xb0, 0x10, 0xeb, + 0x97, 0xae, 0x68, 0x32, 0x6a, 0xc7, 0x3a, 0x7f, 0xa3, 0x1d, 0xec, 0xc3, + 0xf9, 0x1d, 0xfe, 0x1d, 0xed, 0x51, 0xff, 0xae, 0xcd, 0xa0, 0x23, 0xad, + 0x80, 0x16, 0xdb, 0xc8, 0xd0, 0xc8, 0x2c, 0xdf, 0x35, 0x51, 0x8f, 0x68, + 0xca, 0x54, 0x75, 0xf8, 0x7e, 0x68, 0xe3, 0xbb, 0x49, 0x76, 0x91, 0xeb, + 0x4f, 0x23, 0xb8, 0xff, 0x3c, 0xed, 0xbc, 0xc9, 0xf7, 0x9f, 0xe1, 0x3a, + 0x8d, 0xde, 0x70, 0x33, 0x34, 0x8e, 0xf8, 0x5a, 0x6c, 0x68, 0xf0, 0x6f, + 0xbe, 0x3c, 0x39, 0xa7, 0xad, 0xc6, 0x42, 0x99, 0x8e, 0x84, 0x32, 0xad, + 0x34, 0xd6, 0x80, 0xdf, 0x0d, 0xef, 0x8f, 0x43, 0x99, 0xee, 0x3a, 0x47, + 0xda, 0xd5, 0x1c, 0xcb, 0x95, 0x65, 0x19, 0xc8, 0x75, 0x7c, 0xb1, 0x24, + 0x14, 0x21, 0xd3, 0x51, 0x5f, 0xa6, 0x32, 0xc7, 0x05, 0xec, 0x95, 0x83, + 0xfc, 0xd9, 0x8f, 0xe1, 0xe9, 0xb0, 0x8c, 0xb9, 0xde, 0xe0, 0x58, 0x98, + 0xa4, 0x4b, 0x9b, 0xe4, 0x5c, 0xbc, 0xa7, 0x0e, 0xe7, 0xa9, 0xff, 0x9c, + 0x16, 0xde, 0x9b, 0x66, 0x21, 0xc7, 0x76, 0x2e, 0xf6, 0x23, 0x81, 0x8c, + 0xf6, 0x9d, 0x6e, 0xbb, 0xef, 0xe5, 0x4d, 0x7d, 0xed, 0x67, 0x9b, 0x56, + 0xc4, 0xb7, 0x0d, 0xde, 0xf3, 0x1d, 0xe4, 0x9d, 0x7e, 0xc9, 0x1f, 0x53, + 0x31, 0xd6, 0x4b, 0x85, 0x25, 0x83, 0xac, 0x16, 0xcf, 0x91, 0x49, 0x34, + 0xda, 0x72, 0xea, 0xa4, 0xf5, 0x30, 0xc6, 0x2d, 0x34, 0x3c, 0xef, 0xa7, + 0xd0, 0x9d, 0x8b, 0x5c, 0x77, 0x3b, 0xbf, 0xf1, 0xd6, 0x93, 0xc8, 0x21, + 0x37, 0xce, 0xfc, 0xe6, 0xfd, 0xd4, 0xa5, 0xab, 0x88, 0x09, 0x74, 0xc6, + 0x09, 0x51, 0x22, 0x1e, 0xe7, 0x3e, 0xfe, 0x06, 0xef, 0x79, 0x17, 0x8d, + 0x3b, 0x78, 0x75, 0x99, 0xc7, 0x69, 0xdf, 0x39, 0xf6, 0xff, 0x3f, 0xd0, + 0x2e, 0x1a, 0xd6, 0x9e, 0x38, 0xf2, 0xe7, 0xeb, 0xc4, 0xb1, 0x4f, 0x4e, + 0x14, 0x9b, 0xba, 0x7a, 0x09, 0x6b, 0x8b, 0x8e, 0xc2, 0xdf, 0xd6, 0xf9, + 0xfb, 0xa8, 0x76, 0x89, 0xda, 0xf7, 0x65, 0x90, 0xa7, 0xa3, 0xf2, 0x77, + 0x52, 0xb5, 0x8a, 0xd8, 0x52, 0x70, 0x92, 0x98, 0xaf, 0x62, 0x2e, 0xc7, + 0x05, 0x8f, 0x14, 0xd8, 0x50, 0xc1, 0x49, 0x27, 0xc6, 0x9a, 0x9e, 0xa7, + 0x7c, 0x5e, 0xa0, 0x87, 0x32, 0x29, 0x1a, 0x73, 0xf8, 0xfe, 0xf7, 0x9b, + 0xf4, 0x36, 0xec, 0xac, 0x78, 0x9e, 0x6b, 0x26, 0xf6, 0x29, 0x78, 0x77, + 0xf8, 0xbe, 0xea, 0x14, 0x3d, 0xb4, 0x47, 0xcf, 0x5e, 0x22, 0xe0, 0xb3, + 0x42, 0xfd, 0x48, 0x72, 0x53, 0xc7, 0xfd, 0xef, 0x6d, 0x8c, 0x6b, 0x9a, + 0x96, 0xc0, 0x1b, 0xa7, 0x99, 0xa4, 0x95, 0x66, 0x8a, 0x56, 0xa1, 0x1f, + 0xdb, 0xcc, 0x32, 0x7d, 0x03, 0x78, 0x2b, 0x66, 0x95, 0x94, 0x8c, 0xb5, + 0xaf, 0x0b, 0x78, 0x67, 0x05, 0x3d, 0x15, 0x17, 0x18, 0x77, 0x5d, 0x2d, + 0x03, 0x6f, 0xd6, 0xd1, 0x51, 0xa7, 0x9b, 0x8e, 0x61, 0xed, 0x7e, 0xe4, + 0x1f, 0xdf, 0x72, 0xa8, 0x2c, 0x99, 0x29, 0x3a, 0x80, 0xf3, 0x8e, 0x36, + 0x38, 0x57, 0x3b, 0x02, 0x5f, 0x23, 0xd0, 0xa3, 0x19, 0x8f, 0x1e, 0xdd, + 0xa3, 0x5b, 0x71, 0x01, 0x7b, 0xae, 0xb0, 0x9e, 0xa0, 0xdf, 0x09, 0xce, + 0x8d, 0xad, 0xf8, 0xba, 0x08, 0x7f, 0xfa, 0x0c, 0x65, 0xce, 0xad, 0xe5, + 0xa6, 0x90, 0x9f, 0x8f, 0x36, 0xe9, 0x8b, 0x31, 0x9c, 0xf7, 0x36, 0xf8, + 0x34, 0xea, 0xc8, 0x02, 0xf3, 0xe9, 0x58, 0xc0, 0x27, 0x8c, 0xf1, 0xb7, + 0x23, 0xce, 0xd1, 0xf8, 0xec, 0x13, 0x74, 0xb6, 0xc1, 0x77, 0xdd, 0x27, + 0xe8, 0x4a, 0xe3, 0x11, 0xba, 0x98, 0xe3, 0x5c, 0x07, 0xfb, 0xf8, 0x67, + 0xa0, 0xcf, 0x3f, 0xa3, 0x9b, 0x8e, 0xfb, 0x72, 0xfa, 0x3f, 0xc3, 0x06, + 0xd0, 0x70, 0x4c, 0x57, 0x00, 0x00, 0x00 }; static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 }; static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 }; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 55d236726d1..8171cae0668 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1199,8 +1199,7 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) } #define BOND_INTERSECT_FEATURES \ - (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\ - NETIF_F_TSO|NETIF_F_UFO) + (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO) /* * Compute the common dev->feature set available to all slaves. Some @@ -1218,9 +1217,7 @@ static int bond_compute_features(struct bonding *bond) features &= (slave->dev->features & BOND_INTERSECT_FEATURES); if ((features & NETIF_F_SG) && - !(features & (NETIF_F_IP_CSUM | - NETIF_F_NO_CSUM | - NETIF_F_HW_CSUM))) + !(features & NETIF_F_ALL_CSUM)) features &= ~NETIF_F_SG; /* @@ -4191,7 +4188,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) */ bond_dev->features |= NETIF_F_VLAN_CHALLENGED; - /* don't acquire bond device's xmit_lock when + /* don't acquire bond device's netif_tx_lock when * transmitting */ bond_dev->features |= NETIF_F_LLTX; diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 5669b95162b..04a53f1dfdb 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -108,6 +108,7 @@ * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup. * 0.55: 22 Mar 2006: Add flow control (pause frame). + * 0.56: 22 Mar 2006: Additional ethtool config and moduleparam support. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -119,7 +120,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.55" +#define FORCEDETH_VERSION "0.56" #define DRV_NAME "forcedeth" #include <linux/module.h> @@ -165,6 +166,8 @@ #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ #define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ #define DEV_HAS_PAUSEFRAME_TX 0x0200 /* device supports tx pause frames */ +#define DEV_HAS_STATISTICS 0x0400 /* device supports hw statistics */ +#define DEV_HAS_TEST_EXTENDED 0x0800 /* device supports extended diagnostic test */ enum { NvRegIrqStatus = 0x000, @@ -221,6 +224,7 @@ enum { #define NVREG_PFF_ALWAYS 0x7F0000 #define NVREG_PFF_PROMISC 0x80 #define NVREG_PFF_MYADDR 0x20 +#define NVREG_PFF_LOOPBACK 0x10 NvRegOffloadConfig = 0x90, #define NVREG_OFFLOAD_HOMEPHY 0x601 @@ -333,6 +337,33 @@ enum { #define NVREG_POWERSTATE_D1 0x0001 #define NVREG_POWERSTATE_D2 0x0002 #define NVREG_POWERSTATE_D3 0x0003 + NvRegTxCnt = 0x280, + NvRegTxZeroReXmt = 0x284, + NvRegTxOneReXmt = 0x288, + NvRegTxManyReXmt = 0x28c, + NvRegTxLateCol = 0x290, + NvRegTxUnderflow = 0x294, + NvRegTxLossCarrier = 0x298, + NvRegTxExcessDef = 0x29c, + NvRegTxRetryErr = 0x2a0, + NvRegRxFrameErr = 0x2a4, + NvRegRxExtraByte = 0x2a8, + NvRegRxLateCol = 0x2ac, + NvRegRxRunt = 0x2b0, + NvRegRxFrameTooLong = 0x2b4, + NvRegRxOverflow = 0x2b8, + NvRegRxFCSErr = 0x2bc, + NvRegRxFrameAlignErr = 0x2c0, + NvRegRxLenErr = 0x2c4, + NvRegRxUnicast = 0x2c8, + NvRegRxMulticast = 0x2cc, + NvRegRxBroadcast = 0x2d0, + NvRegTxDef = 0x2d4, + NvRegTxFrame = 0x2d8, + NvRegRxCnt = 0x2dc, + NvRegTxPause = 0x2e0, + NvRegRxPause = 0x2e4, + NvRegRxDropFrame = 0x2e8, NvRegVlanControl = 0x300, #define NVREG_VLANCONTROL_ENABLE 0x2000 NvRegMSIXMap0 = 0x3e0, @@ -456,16 +487,18 @@ typedef union _ring_type { /* General driver defaults */ #define NV_WATCHDOG_TIMEO (5*HZ) -#define RX_RING 128 -#define TX_RING 256 +#define RX_RING_DEFAULT 128 +#define TX_RING_DEFAULT 256 +#define RX_RING_MIN 128 +#define TX_RING_MIN 64 +#define RING_MAX_DESC_VER_1 1024 +#define RING_MAX_DESC_VER_2_3 16384 /* - * If your nic mysteriously hangs then try to reduce the limits - * to 1/0: It might be required to set NV_TX_LASTPACKET in the - * last valid ring entry. But this would be impossible to - * implement - probably a disassembly error. + * Difference between the get and put pointers for the tx ring. + * This is used to throttle the amount of data outstanding in the + * tx ring. */ -#define TX_LIMIT_STOP 255 -#define TX_LIMIT_START 254 +#define TX_LIMIT_DIFFERENCE 1 /* rx/tx mac addr + type + vlan + align + slack*/ #define NV_RX_HEADERS (64) @@ -479,6 +512,7 @@ typedef union _ring_type { #define OOM_REFILL (1+HZ/20) #define POLL_WAIT (1+HZ/100) #define LINK_TIMEOUT (3*HZ) +#define STATS_INTERVAL (10*HZ) /* * desc_ver values: @@ -517,6 +551,9 @@ typedef union _ring_type { #define NV_PAUSEFRAME_TX_CAPABLE 0x0002 #define NV_PAUSEFRAME_RX_ENABLE 0x0004 #define NV_PAUSEFRAME_TX_ENABLE 0x0008 +#define NV_PAUSEFRAME_RX_REQ 0x0010 +#define NV_PAUSEFRAME_TX_REQ 0x0020 +#define NV_PAUSEFRAME_AUTONEG 0x0040 /* MSI/MSI-X defines */ #define NV_MSI_X_MAX_VECTORS 8 @@ -531,15 +568,110 @@ typedef union _ring_type { #define NV_MSI_X_VECTOR_TX 0x1 #define NV_MSI_X_VECTOR_OTHER 0x2 +/* statistics */ +struct nv_ethtool_str { + char name[ETH_GSTRING_LEN]; +}; + +static const struct nv_ethtool_str nv_estats_str[] = { + { "tx_bytes" }, + { "tx_zero_rexmt" }, + { "tx_one_rexmt" }, + { "tx_many_rexmt" }, + { "tx_late_collision" }, + { "tx_fifo_errors" }, + { "tx_carrier_errors" }, + { "tx_excess_deferral" }, + { "tx_retry_error" }, + { "tx_deferral" }, + { "tx_packets" }, + { "tx_pause" }, + { "rx_frame_error" }, + { "rx_extra_byte" }, + { "rx_late_collision" }, + { "rx_runt" }, + { "rx_frame_too_long" }, + { "rx_over_errors" }, + { "rx_crc_errors" }, + { "rx_frame_align_error" }, + { "rx_length_error" }, + { "rx_unicast" }, + { "rx_multicast" }, + { "rx_broadcast" }, + { "rx_bytes" }, + { "rx_pause" }, + { "rx_drop_frame" }, + { "rx_packets" }, + { "rx_errors_total" } +}; + +struct nv_ethtool_stats { + u64 tx_bytes; + u64 tx_zero_rexmt; + u64 tx_one_rexmt; + u64 tx_many_rexmt; + u64 tx_late_collision; + u64 tx_fifo_errors; + u64 tx_carrier_errors; + u64 tx_excess_deferral; + u64 tx_retry_error; + u64 tx_deferral; + u64 tx_packets; + u64 tx_pause; + u64 rx_frame_error; + u64 rx_extra_byte; + u64 rx_late_collision; + u64 rx_runt; + u64 rx_frame_too_long; + u64 rx_over_errors; + u64 rx_crc_errors; + u64 rx_frame_align_error; + u64 rx_length_error; + u64 rx_unicast; + u64 rx_multicast; + u64 rx_broadcast; + u64 rx_bytes; + u64 rx_pause; + u64 rx_drop_frame; + u64 rx_packets; + u64 rx_errors_total; +}; + +/* diagnostics */ +#define NV_TEST_COUNT_BASE 3 +#define NV_TEST_COUNT_EXTENDED 4 + +static const struct nv_ethtool_str nv_etests_str[] = { + { "link (online/offline)" }, + { "register (offline) " }, + { "interrupt (offline) " }, + { "loopback (offline) " } +}; + +struct register_test { + u32 reg; + u32 mask; +}; + +static const struct register_test nv_registers_test[] = { + { NvRegUnknownSetupReg6, 0x01 }, + { NvRegMisc1, 0x03c }, + { NvRegOffloadConfig, 0x03ff }, + { NvRegMulticastAddrA, 0xffffffff }, + { NvRegUnknownSetupReg3, 0x0ff }, + { NvRegWakeUpFlags, 0x07777 }, + { 0,0 } +}; + /* * SMP locking: * All hardware access under dev->priv->lock, except the performance * critical parts: * - rx is (pseudo-) lockless: it relies on the single-threading provided * by the arch code for interrupts. - * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission + * - tx setup is lockless: it relies on netif_tx_lock. Actual submission * needs dev->priv->lock :-( - * - set_multicast_list: preparation lockless, relies on dev->xmit_lock. + * - set_multicast_list: preparation lockless, relies on netif_tx_lock. */ /* in dev: base, irq */ @@ -549,6 +681,7 @@ struct fe_priv { /* General data: * Locking: spin_lock(&np->lock); */ struct net_device_stats stats; + struct nv_ethtool_stats estats; int in_shutdown; u32 linkspeed; int duplex; @@ -558,6 +691,7 @@ struct fe_priv { int wolenabled; unsigned int phy_oui; u16 gigabit; + int intr_test; /* General data: RO fields */ dma_addr_t ring_addr; @@ -577,13 +711,15 @@ struct fe_priv { */ ring_type rx_ring; unsigned int cur_rx, refill_rx; - struct sk_buff *rx_skbuff[RX_RING]; - dma_addr_t rx_dma[RX_RING]; + struct sk_buff **rx_skbuff; + dma_addr_t *rx_dma; unsigned int rx_buf_sz; unsigned int pkt_limit; struct timer_list oom_kick; struct timer_list nic_poll; + struct timer_list stats_poll; u32 nic_poll_irq; + int rx_ring_size; /* media detection workaround. * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); @@ -595,10 +731,13 @@ struct fe_priv { */ ring_type tx_ring; unsigned int next_tx, nic_tx; - struct sk_buff *tx_skbuff[TX_RING]; - dma_addr_t tx_dma[TX_RING]; - unsigned int tx_dma_len[TX_RING]; + struct sk_buff **tx_skbuff; + dma_addr_t *tx_dma; + unsigned int *tx_dma_len; u32 tx_flags; + int tx_ring_size; + int tx_limit_start; + int tx_limit_stop; /* vlan fields */ struct vlan_group *vlangrp; @@ -623,8 +762,10 @@ static int max_interrupt_work = 5; * Throughput Mode: Every tx and rx packet will generate an interrupt. * CPU Mode: Interrupts are controlled by a timer. */ -#define NV_OPTIMIZATION_MODE_THROUGHPUT 0 -#define NV_OPTIMIZATION_MODE_CPU 1 +enum { + NV_OPTIMIZATION_MODE_THROUGHPUT, + NV_OPTIMIZATION_MODE_CPU +}; static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT; /* @@ -637,14 +778,31 @@ static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT; static int poll_interval = -1; /* - * Disable MSI interrupts + * MSI interrupts + */ +enum { + NV_MSI_INT_DISABLED, + NV_MSI_INT_ENABLED +}; +static int msi = NV_MSI_INT_ENABLED; + +/* + * MSIX interrupts */ -static int disable_msi = 0; +enum { + NV_MSIX_INT_DISABLED, + NV_MSIX_INT_ENABLED +}; +static int msix = NV_MSIX_INT_ENABLED; /* - * Disable MSIX interrupts + * DMA 64bit */ -static int disable_msix = 0; +enum { + NV_DMA_64BIT_DISABLED, + NV_DMA_64BIT_ENABLED +}; +static int dma_64bit = NV_DMA_64BIT_ENABLED; static inline struct fe_priv *get_nvpriv(struct net_device *dev) { @@ -704,7 +862,7 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags) writel((u32) cpu_to_le64(np->ring_addr), base + NvRegRxRingPhysAddr); } if (rxtx_flags & NV_SETUP_TX_RING) { - writel((u32) cpu_to_le64(np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); + writel((u32) cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); } } else { if (rxtx_flags & NV_SETUP_RX_RING) { @@ -712,12 +870,37 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags) writel((u32) (cpu_to_le64(np->ring_addr) >> 32), base + NvRegRxRingPhysAddrHigh); } if (rxtx_flags & NV_SETUP_TX_RING) { - writel((u32) cpu_to_le64(np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); - writel((u32) (cpu_to_le64(np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)) >> 32), base + NvRegTxRingPhysAddrHigh); + writel((u32) cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); + writel((u32) (cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)) >> 32), base + NvRegTxRingPhysAddrHigh); } } } +static void free_rings(struct net_device *dev) +{ + struct fe_priv *np = get_nvpriv(dev); + + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + if(np->rx_ring.orig) + pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (np->rx_ring_size + np->tx_ring_size), + np->rx_ring.orig, np->ring_addr); + } else { + if (np->rx_ring.ex) + pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (np->rx_ring_size + np->tx_ring_size), + np->rx_ring.ex, np->ring_addr); + } + if (np->rx_skbuff) + kfree(np->rx_skbuff); + if (np->rx_dma) + kfree(np->rx_dma); + if (np->tx_skbuff) + kfree(np->tx_skbuff); + if (np->tx_dma) + kfree(np->tx_dma); + if (np->tx_dma_len) + kfree(np->tx_dma_len); +} + static int using_multi_irqs(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -1056,7 +1239,7 @@ static int nv_alloc_rx(struct net_device *dev) while (np->cur_rx != refill_rx) { struct sk_buff *skb; - nr = refill_rx % RX_RING; + nr = refill_rx % np->rx_ring_size; if (np->rx_skbuff[nr] == NULL) { skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); @@ -1085,7 +1268,7 @@ static int nv_alloc_rx(struct net_device *dev) refill_rx++; } np->refill_rx = refill_rx; - if (np->cur_rx - refill_rx == RX_RING) + if (np->cur_rx - refill_rx == np->rx_ring_size) return 1; return 0; } @@ -1124,9 +1307,9 @@ static void nv_init_rx(struct net_device *dev) struct fe_priv *np = netdev_priv(dev); int i; - np->cur_rx = RX_RING; + np->cur_rx = np->rx_ring_size; np->refill_rx = 0; - for (i = 0; i < RX_RING; i++) + for (i = 0; i < np->rx_ring_size; i++) if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->rx_ring.orig[i].FlagLen = 0; else @@ -1139,7 +1322,7 @@ static void nv_init_tx(struct net_device *dev) int i; np->next_tx = np->nic_tx = 0; - for (i = 0; i < TX_RING; i++) { + for (i = 0; i < np->tx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->tx_ring.orig[i].FlagLen = 0; else @@ -1184,7 +1367,7 @@ static void nv_drain_tx(struct net_device *dev) struct fe_priv *np = netdev_priv(dev); unsigned int i; - for (i = 0; i < TX_RING; i++) { + for (i = 0; i < np->tx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->tx_ring.orig[i].FlagLen = 0; else @@ -1198,7 +1381,7 @@ static void nv_drain_rx(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); int i; - for (i = 0; i < RX_RING; i++) { + for (i = 0; i < np->rx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) np->rx_ring.orig[i].FlagLen = 0; else @@ -1222,7 +1405,7 @@ static void drain_ring(struct net_device *dev) /* * nv_start_xmit: dev->hard_start_xmit function - * Called with dev->xmit_lock held. + * Called with netif_tx_lock held. */ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -1230,8 +1413,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 tx_flags = 0; u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET); unsigned int fragments = skb_shinfo(skb)->nr_frags; - unsigned int nr = (np->next_tx - 1) % TX_RING; - unsigned int start_nr = np->next_tx % TX_RING; + unsigned int nr = (np->next_tx - 1) % np->tx_ring_size; + unsigned int start_nr = np->next_tx % np->tx_ring_size; unsigned int i; u32 offset = 0; u32 bcnt; @@ -1247,7 +1430,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&np->lock); - if ((np->next_tx - np->nic_tx + entries - 1) > TX_LIMIT_STOP) { + if ((np->next_tx - np->nic_tx + entries - 1) > np->tx_limit_stop) { spin_unlock_irq(&np->lock); netif_stop_queue(dev); return NETDEV_TX_BUSY; @@ -1256,7 +1439,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) /* setup the header buffer */ do { bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - nr = (nr + 1) % TX_RING; + nr = (nr + 1) % np->tx_ring_size; np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data + offset, bcnt, PCI_DMA_TODEVICE); @@ -1283,7 +1466,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) do { bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - nr = (nr + 1) % TX_RING; + nr = (nr + 1) % np->tx_ring_size; np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, PCI_DMA_TODEVICE); @@ -1365,7 +1548,7 @@ static void nv_tx_done(struct net_device *dev) struct sk_buff *skb; while (np->nic_tx != np->next_tx) { - i = np->nic_tx % TX_RING; + i = np->nic_tx % np->tx_ring_size; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) Flags = le32_to_cpu(np->tx_ring.orig[i].FlagLen); @@ -1410,13 +1593,13 @@ static void nv_tx_done(struct net_device *dev) nv_release_txskb(dev, i); np->nic_tx++; } - if (np->next_tx - np->nic_tx < TX_LIMIT_START) + if (np->next_tx - np->nic_tx < np->tx_limit_start) netif_wake_queue(dev); } /* * nv_tx_timeout: dev->tx_timeout function - * Called with dev->xmit_lock held. + * Called with netif_tx_lock held. */ static void nv_tx_timeout(struct net_device *dev) { @@ -1447,7 +1630,7 @@ static void nv_tx_timeout(struct net_device *dev) readl(base + i + 24), readl(base + i + 28)); } printk(KERN_INFO "%s: Dumping tx ring\n", dev->name); - for (i=0;i<TX_RING;i+= 4) { + for (i=0;i<np->tx_ring_size;i+= 4) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", i, @@ -1563,10 +1746,10 @@ static void nv_rx_process(struct net_device *dev) struct sk_buff *skb; int len; int i; - if (np->cur_rx - np->refill_rx >= RX_RING) + if (np->cur_rx - np->refill_rx >= np->rx_ring_size) break; /* we scanned the whole ring - do not continue */ - i = np->cur_rx % RX_RING; + i = np->cur_rx % np->rx_ring_size; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { Flags = le32_to_cpu(np->rx_ring.orig[i].FlagLen); len = nv_descr_getlength(&np->rx_ring.orig[i], np->desc_ver); @@ -1673,14 +1856,16 @@ static void nv_rx_process(struct net_device *dev) } } } - Flags &= NV_RX2_CHECKSUMMASK; - if (Flags == NV_RX2_CHECKSUMOK1 || - Flags == NV_RX2_CHECKSUMOK2 || - Flags == NV_RX2_CHECKSUMOK3) { - dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name); - np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY; - } else { - dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name); + if (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) { + Flags &= NV_RX2_CHECKSUMMASK; + if (Flags == NV_RX2_CHECKSUMOK1 || + Flags == NV_RX2_CHECKSUMOK2 || + Flags == NV_RX2_CHECKSUMOK3) { + dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name); + np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY; + } else { + dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name); + } } } /* got a valid packet - forward it to the network core */ @@ -1745,7 +1930,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) * Changing the MTU is a rare event, it shouldn't matter. */ nv_disable_irq(dev); - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock(&np->lock); /* stop engines */ nv_stop_rx(dev); @@ -1755,18 +1940,15 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) nv_drain_rx(dev); nv_drain_tx(dev); /* reinit driver view of the rx queue */ - nv_init_rx(dev); - nv_init_tx(dev); - /* alloc new rx buffers */ set_bufsize(dev); - if (nv_alloc_rx(dev)) { + if (nv_init_ring(dev)) { if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); } /* reinit nic view of the rx queue */ writel(np->rx_buf_sz, base + NvRegOffloadConfig); setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); @@ -1776,7 +1958,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) nv_start_rx(dev); nv_start_tx(dev); spin_unlock(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); nv_enable_irq(dev); } return 0; @@ -1811,7 +1993,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN); if (netif_running(dev)) { - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock_irq(&np->lock); /* stop rx engine */ @@ -1823,7 +2005,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) /* restart rx engine */ nv_start_rx(dev); spin_unlock_irq(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } else { nv_copy_mac_to_hw(dev); } @@ -1832,7 +2014,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) /* * nv_set_multicast: dev->set_multicast function - * Called with dev->xmit_lock held. + * Called with netif_tx_lock held. */ static void nv_set_multicast(struct net_device *dev) { @@ -1840,16 +2022,16 @@ static void nv_set_multicast(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 addr[2]; u32 mask[2]; - u32 pff; + u32 pff = readl(base + NvRegPacketFilterFlags) & NVREG_PFF_PAUSE_RX; memset(addr, 0, sizeof(addr)); memset(mask, 0, sizeof(mask)); if (dev->flags & IFF_PROMISC) { printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); - pff = NVREG_PFF_PROMISC; + pff |= NVREG_PFF_PROMISC; } else { - pff = NVREG_PFF_MYADDR; + pff |= NVREG_PFF_MYADDR; if (dev->flags & IFF_ALLMULTI || dev->mc_list) { u32 alwaysOff[2]; @@ -1894,6 +2076,35 @@ static void nv_set_multicast(struct net_device *dev) spin_unlock_irq(&np->lock); } +void nv_update_pause(struct net_device *dev, u32 pause_flags) +{ + struct fe_priv *np = netdev_priv(dev); + u8 __iomem *base = get_hwbase(dev); + + np->pause_flags &= ~(NV_PAUSEFRAME_TX_ENABLE | NV_PAUSEFRAME_RX_ENABLE); + + if (np->pause_flags & NV_PAUSEFRAME_RX_CAPABLE) { + u32 pff = readl(base + NvRegPacketFilterFlags) & ~NVREG_PFF_PAUSE_RX; + if (pause_flags & NV_PAUSEFRAME_RX_ENABLE) { + writel(pff|NVREG_PFF_PAUSE_RX, base + NvRegPacketFilterFlags); + np->pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + } else { + writel(pff, base + NvRegPacketFilterFlags); + } + } + if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) { + u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX; + if (pause_flags & NV_PAUSEFRAME_TX_ENABLE) { + writel(NVREG_TX_PAUSEFRAME_ENABLE, base + NvRegTxPauseFrame); + writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1); + np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE; + } else { + writel(NVREG_TX_PAUSEFRAME_DISABLE, base + NvRegTxPauseFrame); + writel(regmisc, base + NvRegMisc1); + } + } +} + /** * nv_update_linkspeed: Setup the MAC according to the link partner * @dev: Network device to be configured @@ -1916,7 +2127,7 @@ static int nv_update_linkspeed(struct net_device *dev) int newdup = np->duplex; int mii_status; int retval = 0; - u32 control_1000, status_1000, phyreg; + u32 control_1000, status_1000, phyreg, pause_flags; /* BMSR_LSTATUS is latched, read it twice: * we want the current value. @@ -1962,6 +2173,11 @@ static int nv_update_linkspeed(struct net_device *dev) goto set_speed; } + adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); + lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); + dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", + dev->name, adv, lpa); + retval = 1; if (np->gigabit == PHY_GIGABIT) { control_1000 = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); @@ -1977,11 +2193,6 @@ static int nv_update_linkspeed(struct net_device *dev) } } - adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); - lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); - dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", - dev->name, adv, lpa); - /* FIXME: handle parallel detection properly */ adv_lpa = lpa & adv; if (adv_lpa & LPA_100FULL) { @@ -2040,55 +2251,45 @@ set_speed: writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); - /* setup pause frame based on advertisement and link partner */ - np->pause_flags &= ~(NV_PAUSEFRAME_TX_ENABLE | NV_PAUSEFRAME_RX_ENABLE); - + pause_flags = 0; + /* setup pause frame */ if (np->duplex != 0) { - adv_pause = adv & (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM); - lpa_pause = lpa & (LPA_PAUSE_CAP| LPA_PAUSE_ASYM); - - switch (adv_pause) { - case (ADVERTISE_PAUSE_CAP): - if (lpa_pause & LPA_PAUSE_CAP) { - np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE | NV_PAUSEFRAME_RX_ENABLE; - } - break; - case (ADVERTISE_PAUSE_ASYM): - if (lpa_pause == (LPA_PAUSE_CAP| LPA_PAUSE_ASYM)) - { - np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE; - } - break; - case (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM): - if (lpa_pause & LPA_PAUSE_CAP) - { - np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE | NV_PAUSEFRAME_RX_ENABLE; - } - if (lpa_pause == LPA_PAUSE_ASYM) - { - np->pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + if (np->autoneg && np->pause_flags & NV_PAUSEFRAME_AUTONEG) { + adv_pause = adv & (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM); + lpa_pause = lpa & (LPA_PAUSE_CAP| LPA_PAUSE_ASYM); + + switch (adv_pause) { + case (ADVERTISE_PAUSE_CAP): + if (lpa_pause & LPA_PAUSE_CAP) { + pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) + pause_flags |= NV_PAUSEFRAME_TX_ENABLE; + } + break; + case (ADVERTISE_PAUSE_ASYM): + if (lpa_pause == (LPA_PAUSE_CAP| LPA_PAUSE_ASYM)) + { + pause_flags |= NV_PAUSEFRAME_TX_ENABLE; + } + break; + case (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM): + if (lpa_pause & LPA_PAUSE_CAP) + { + pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) + pause_flags |= NV_PAUSEFRAME_TX_ENABLE; + } + if (lpa_pause == LPA_PAUSE_ASYM) + { + pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + } + break; } - break; - } - } - - if (np->pause_flags & NV_PAUSEFRAME_RX_CAPABLE) { - u32 pff = readl(base + NvRegPacketFilterFlags) & ~NVREG_PFF_PAUSE_RX; - if (np->pause_flags & NV_PAUSEFRAME_RX_ENABLE) - writel(pff|NVREG_PFF_PAUSE_RX, base + NvRegPacketFilterFlags); - else - writel(pff, base + NvRegPacketFilterFlags); - } - if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) { - u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX; - if (np->pause_flags & NV_PAUSEFRAME_TX_ENABLE) { - writel(NVREG_TX_PAUSEFRAME_ENABLE, base + NvRegTxPauseFrame); - writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1); } else { - writel(NVREG_TX_PAUSEFRAME_DISABLE, base + NvRegTxPauseFrame); - writel(regmisc, base + NvRegMisc1); + pause_flags = np->pause_flags; } } + nv_update_pause(dev, pause_flags); return retval; } @@ -2350,6 +2551,175 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) return IRQ_RETVAL(i); } +static irqreturn_t nv_nic_irq_test(int foo, void *data, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) data; + struct fe_priv *np = netdev_priv(dev); + u8 __iomem *base = get_hwbase(dev); + u32 events; + + dprintk(KERN_DEBUG "%s: nv_nic_irq_test\n", dev->name); + + if (!(np->msi_flags & NV_MSI_X_ENABLED)) { + events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; + writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus); + } else { + events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; + writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus); + } + pci_push(base); + dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); + if (!(events & NVREG_IRQ_TIMER)) + return IRQ_RETVAL(0); + + spin_lock(&np->lock); + np->intr_test = 1; + spin_unlock(&np->lock); + + dprintk(KERN_DEBUG "%s: nv_nic_irq_test completed\n", dev->name); + + return IRQ_RETVAL(1); +} + +static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask) +{ + u8 __iomem *base = get_hwbase(dev); + int i; + u32 msixmap = 0; + + /* Each interrupt bit can be mapped to a MSIX vector (4 bits). + * MSIXMap0 represents the first 8 interrupts and MSIXMap1 represents + * the remaining 8 interrupts. + */ + for (i = 0; i < 8; i++) { + if ((irqmask >> i) & 0x1) { + msixmap |= vector << (i << 2); + } + } + writel(readl(base + NvRegMSIXMap0) | msixmap, base + NvRegMSIXMap0); + + msixmap = 0; + for (i = 0; i < 8; i++) { + if ((irqmask >> (i + 8)) & 0x1) { + msixmap |= vector << (i << 2); + } + } + writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); +} + +static int nv_request_irq(struct net_device *dev, int intr_test) +{ + struct fe_priv *np = get_nvpriv(dev); + u8 __iomem *base = get_hwbase(dev); + int ret = 1; + int i; + + if (np->msi_flags & NV_MSI_X_CAPABLE) { + for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { + np->msi_x_entry[i].entry = i; + } + if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) { + np->msi_flags |= NV_MSI_X_ENABLED; + if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) { + /* Request irq for rx handling */ + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) { + printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + goto out_err; + } + /* Request irq for tx handling */ + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) { + printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret); + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + goto out_free_rx; + } + /* Request irq for link and timer handling */ + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) { + printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret); + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + goto out_free_tx; + } + /* map interrupts to their respective vector */ + writel(0, base + NvRegMSIXMap0); + writel(0, base + NvRegMSIXMap1); + set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL); + set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL); + set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER); + } else { + /* Request irq for all interrupts */ + if ((!intr_test && + request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) || + (intr_test && + request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) { + printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + goto out_err; + } + + /* map interrupts to vector 0 */ + writel(0, base + NvRegMSIXMap0); + writel(0, base + NvRegMSIXMap1); + } + } + } + if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { + if ((ret = pci_enable_msi(np->pci_dev)) == 0) { + np->msi_flags |= NV_MSI_ENABLED; + if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) || + (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) { + printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); + pci_disable_msi(np->pci_dev); + np->msi_flags &= ~NV_MSI_ENABLED; + goto out_err; + } + + /* map interrupts to vector 0 */ + writel(0, base + NvRegMSIMap0); + writel(0, base + NvRegMSIMap1); + /* enable msi vector 0 */ + writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); + } + } + if (ret != 0) { + if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) || + (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) + goto out_err; + + } + + return 0; +out_free_tx: + free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, dev); +out_free_rx: + free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, dev); +out_err: + return 1; +} + +static void nv_free_irq(struct net_device *dev) +{ + struct fe_priv *np = get_nvpriv(dev); + int i; + + if (np->msi_flags & NV_MSI_X_ENABLED) { + for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { + free_irq(np->msi_x_entry[i].vector, dev); + } + pci_disable_msix(np->pci_dev); + np->msi_flags &= ~NV_MSI_X_ENABLED; + } else { + free_irq(np->pci_dev->irq, dev); + if (np->msi_flags & NV_MSI_ENABLED) { + pci_disable_msi(np->pci_dev); + np->msi_flags &= ~NV_MSI_ENABLED; + } + } +} + static void nv_do_nic_poll(unsigned long data) { struct net_device *dev = (struct net_device *) data; @@ -2419,6 +2789,56 @@ static void nv_poll_controller(struct net_device *dev) } #endif +static void nv_do_stats_poll(unsigned long data) +{ + struct net_device *dev = (struct net_device *) data; + struct fe_priv *np = netdev_priv(dev); + u8 __iomem *base = get_hwbase(dev); + + np->estats.tx_bytes += readl(base + NvRegTxCnt); + np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt); + np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt); + np->estats.tx_many_rexmt += readl(base + NvRegTxManyReXmt); + np->estats.tx_late_collision += readl(base + NvRegTxLateCol); + np->estats.tx_fifo_errors += readl(base + NvRegTxUnderflow); + np->estats.tx_carrier_errors += readl(base + NvRegTxLossCarrier); + np->estats.tx_excess_deferral += readl(base + NvRegTxExcessDef); + np->estats.tx_retry_error += readl(base + NvRegTxRetryErr); + np->estats.tx_deferral += readl(base + NvRegTxDef); + np->estats.tx_packets += readl(base + NvRegTxFrame); + np->estats.tx_pause += readl(base + NvRegTxPause); + np->estats.rx_frame_error += readl(base + NvRegRxFrameErr); + np->estats.rx_extra_byte += readl(base + NvRegRxExtraByte); + np->estats.rx_late_collision += readl(base + NvRegRxLateCol); + np->estats.rx_runt += readl(base + NvRegRxRunt); + np->estats.rx_frame_too_long += readl(base + NvRegRxFrameTooLong); + np->estats.rx_over_errors += readl(base + NvRegRxOverflow); + np->estats.rx_crc_errors += readl(base + NvRegRxFCSErr); + np->estats.rx_frame_align_error += readl(base + NvRegRxFrameAlignErr); + np->estats.rx_length_error += readl(base + NvRegRxLenErr); + np->estats.rx_unicast += readl(base + NvRegRxUnicast); + np->estats.rx_multicast += readl(base + NvRegRxMulticast); + np->estats.rx_broadcast += readl(base + NvRegRxBroadcast); + np->estats.rx_bytes += readl(base + NvRegRxCnt); + np->estats.rx_pause += readl(base + NvRegRxPause); + np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame); + np->estats.rx_packets = + np->estats.rx_unicast + + np->estats.rx_multicast + + np->estats.rx_broadcast; + np->estats.rx_errors_total = + np->estats.rx_crc_errors + + np->estats.rx_over_errors + + np->estats.rx_frame_error + + (np->estats.rx_frame_align_error - np->estats.rx_extra_byte) + + np->estats.rx_late_collision + + np->estats.rx_runt + + np->estats.rx_frame_too_long; + + if (!np->in_shutdown) + mod_timer(&np->stats_poll, jiffies + STATS_INTERVAL); +} + static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct fe_priv *np = netdev_priv(dev); @@ -2442,17 +2862,19 @@ static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); + u32 flags = 0; - spin_lock_irq(&np->lock); if (wolinfo->wolopts == 0) { - writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; - } - if (wolinfo->wolopts & WAKE_MAGIC) { - writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags); + } else if (wolinfo->wolopts & WAKE_MAGIC) { np->wolenabled = 1; + flags = NVREG_WAKEUPFLAGS_ENABLE; + } + if (netif_running(dev)) { + spin_lock_irq(&np->lock); + writel(flags, base + NvRegWakeUpFlags); + spin_unlock_irq(&np->lock); } - spin_unlock_irq(&np->lock); return 0; } @@ -2466,9 +2888,17 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (!netif_running(dev)) { /* We do not track link speed / duplex setting if the * interface is disabled. Force a link check */ - nv_update_linkspeed(dev); + if (nv_update_linkspeed(dev)) { + if (!netif_carrier_ok(dev)) + netif_carrier_on(dev); + } else { + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); + } } - switch(np->linkspeed & (NVREG_LINKSPEED_MASK)) { + + if (netif_carrier_ok(dev)) { + switch(np->linkspeed & (NVREG_LINKSPEED_MASK)) { case NVREG_LINKSPEED_10: ecmd->speed = SPEED_10; break; @@ -2478,10 +2908,14 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) case NVREG_LINKSPEED_1000: ecmd->speed = SPEED_1000; break; + } + ecmd->duplex = DUPLEX_HALF; + if (np->duplex) + ecmd->duplex = DUPLEX_FULL; + } else { + ecmd->speed = -1; + ecmd->duplex = -1; } - ecmd->duplex = DUPLEX_HALF; - if (np->duplex) - ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = np->autoneg; @@ -2489,23 +2923,20 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (np->autoneg) { ecmd->advertising |= ADVERTISED_Autoneg; adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); - } else { - adv = np->fixed_mode; - } - if (adv & ADVERTISE_10HALF) - ecmd->advertising |= ADVERTISED_10baseT_Half; - if (adv & ADVERTISE_10FULL) - ecmd->advertising |= ADVERTISED_10baseT_Full; - if (adv & ADVERTISE_100HALF) - ecmd->advertising |= ADVERTISED_100baseT_Half; - if (adv & ADVERTISE_100FULL) - ecmd->advertising |= ADVERTISED_100baseT_Full; - if (np->autoneg && np->gigabit == PHY_GIGABIT) { - adv = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); - if (adv & ADVERTISE_1000FULL) - ecmd->advertising |= ADVERTISED_1000baseT_Full; + if (adv & ADVERTISE_10HALF) + ecmd->advertising |= ADVERTISED_10baseT_Half; + if (adv & ADVERTISE_10FULL) + ecmd->advertising |= ADVERTISED_10baseT_Full; + if (adv & ADVERTISE_100HALF) + ecmd->advertising |= ADVERTISED_100baseT_Half; + if (adv & ADVERTISE_100FULL) + ecmd->advertising |= ADVERTISED_100baseT_Full; + if (np->gigabit == PHY_GIGABIT) { + adv = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); + if (adv & ADVERTISE_1000FULL) + ecmd->advertising |= ADVERTISED_1000baseT_Full; + } } - ecmd->supported = (SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | @@ -2557,7 +2988,18 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) return -EINVAL; } - spin_lock_irq(&np->lock); + netif_carrier_off(dev); + if (netif_running(dev)) { + nv_disable_irq(dev); + spin_lock_bh(&dev->xmit_lock); + spin_lock(&np->lock); + /* stop engines */ + nv_stop_rx(dev); + nv_stop_tx(dev); + spin_unlock(&np->lock); + spin_unlock_bh(&dev->xmit_lock); + } + if (ecmd->autoneg == AUTONEG_ENABLE) { int adv, bmcr; @@ -2569,11 +3011,15 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (ecmd->advertising & ADVERTISED_10baseT_Half) adv |= ADVERTISE_10HALF; if (ecmd->advertising & ADVERTISED_10baseT_Full) - adv |= ADVERTISE_10FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + adv |= ADVERTISE_10FULL; if (ecmd->advertising & ADVERTISED_100baseT_Half) adv |= ADVERTISE_100HALF; if (ecmd->advertising & ADVERTISED_100baseT_Full) - adv |= ADVERTISE_100FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + adv |= ADVERTISE_100FULL; + if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) /* for rx we set both advertisments but disable tx pause */ + adv |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) + adv |= ADVERTISE_PAUSE_ASYM; mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); if (np->gigabit == PHY_GIGABIT) { @@ -2584,6 +3030,8 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) mii_rw(dev, np->phyaddr, MII_CTRL1000, adv); } + if (netif_running(dev)) + printk(KERN_INFO "%s: link down.\n", dev->name); bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); @@ -2598,11 +3046,20 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF) adv |= ADVERTISE_10HALF; if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL) - adv |= ADVERTISE_10FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + adv |= ADVERTISE_10FULL; if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF) adv |= ADVERTISE_100HALF; if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL) - adv |= ADVERTISE_100FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + adv |= ADVERTISE_100FULL; + np->pause_flags &= ~(NV_PAUSEFRAME_AUTONEG|NV_PAUSEFRAME_RX_ENABLE|NV_PAUSEFRAME_TX_ENABLE); + if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) {/* for rx we set both advertisments but disable tx pause */ + adv |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + np->pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + } + if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) { + adv |= ADVERTISE_PAUSE_ASYM; + np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE; + } mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); np->fixed_mode = adv; @@ -2613,20 +3070,30 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); - bmcr |= ~(BMCR_ANENABLE|BMCR_SPEED100|BMCR_FULLDPLX); - if (adv & (ADVERTISE_10FULL|ADVERTISE_100FULL)) + bmcr &= ~(BMCR_ANENABLE|BMCR_SPEED100|BMCR_SPEED1000|BMCR_FULLDPLX); + if (np->fixed_mode & (ADVERTISE_10FULL|ADVERTISE_100FULL)) bmcr |= BMCR_FULLDPLX; - if (adv & (ADVERTISE_100HALF|ADVERTISE_100FULL)) + if (np->fixed_mode & (ADVERTISE_100HALF|ADVERTISE_100FULL)) bmcr |= BMCR_SPEED100; mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); - - if (netif_running(dev)) { + if (np->phy_oui == PHY_OUI_MARVELL) { + /* reset the phy */ + if (phy_reset(dev)) { + printk(KERN_INFO "%s: phy reset failed\n", dev->name); + return -EINVAL; + } + } else if (netif_running(dev)) { /* Wait a bit and then reconfigure the nic. */ udelay(10); nv_linkchange(dev); } } - spin_unlock_irq(&np->lock); + + if (netif_running(dev)) { + nv_start_rx(dev); + nv_start_tx(dev); + nv_enable_irq(dev); + } return 0; } @@ -2658,24 +3125,39 @@ static int nv_nway_reset(struct net_device *dev) struct fe_priv *np = netdev_priv(dev); int ret; - spin_lock_irq(&np->lock); if (np->autoneg) { int bmcr; + netif_carrier_off(dev); + if (netif_running(dev)) { + nv_disable_irq(dev); + spin_lock_bh(&dev->xmit_lock); + spin_lock(&np->lock); + /* stop engines */ + nv_stop_rx(dev); + nv_stop_tx(dev); + spin_unlock(&np->lock); + spin_unlock_bh(&dev->xmit_lock); + printk(KERN_INFO "%s: link down.\n", dev->name); + } + bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); + if (netif_running(dev)) { + nv_start_rx(dev); + nv_start_tx(dev); + nv_enable_irq(dev); + } ret = 0; } else { ret = -EINVAL; } - spin_unlock_irq(&np->lock); return ret; } -#ifdef NETIF_F_TSO static int nv_set_tso(struct net_device *dev, u32 value) { struct fe_priv *np = netdev_priv(dev); @@ -2683,187 +3165,702 @@ static int nv_set_tso(struct net_device *dev, u32 value) if ((np->driver_data & DEV_HAS_CHECKSUM)) return ethtool_op_set_tso(dev, value); else - return value ? -EOPNOTSUPP : 0; + return -EOPNOTSUPP; } -#endif -static struct ethtool_ops ops = { - .get_drvinfo = nv_get_drvinfo, - .get_link = ethtool_op_get_link, - .get_wol = nv_get_wol, - .set_wol = nv_set_wol, - .get_settings = nv_get_settings, - .set_settings = nv_set_settings, - .get_regs_len = nv_get_regs_len, - .get_regs = nv_get_regs, - .nway_reset = nv_nway_reset, - .get_perm_addr = ethtool_op_get_perm_addr, -#ifdef NETIF_F_TSO - .get_tso = ethtool_op_get_tso, - .set_tso = nv_set_tso -#endif -}; +static void nv_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) +{ + struct fe_priv *np = netdev_priv(dev); -static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) + ring->rx_max_pending = (np->desc_ver == DESC_VER_1) ? RING_MAX_DESC_VER_1 : RING_MAX_DESC_VER_2_3; + ring->rx_mini_max_pending = 0; + ring->rx_jumbo_max_pending = 0; + ring->tx_max_pending = (np->desc_ver == DESC_VER_1) ? RING_MAX_DESC_VER_1 : RING_MAX_DESC_VER_2_3; + + ring->rx_pending = np->rx_ring_size; + ring->rx_mini_pending = 0; + ring->rx_jumbo_pending = 0; + ring->tx_pending = np->tx_ring_size; +} + +static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) { - struct fe_priv *np = get_nvpriv(dev); + struct fe_priv *np = netdev_priv(dev); + u8 __iomem *base = get_hwbase(dev); + u8 *rxtx_ring, *rx_skbuff, *tx_skbuff, *rx_dma, *tx_dma, *tx_dma_len; + dma_addr_t ring_addr; - spin_lock_irq(&np->lock); + if (ring->rx_pending < RX_RING_MIN || + ring->tx_pending < TX_RING_MIN || + ring->rx_mini_pending != 0 || + ring->rx_jumbo_pending != 0 || + (np->desc_ver == DESC_VER_1 && + (ring->rx_pending > RING_MAX_DESC_VER_1 || + ring->tx_pending > RING_MAX_DESC_VER_1)) || + (np->desc_ver != DESC_VER_1 && + (ring->rx_pending > RING_MAX_DESC_VER_2_3 || + ring->tx_pending > RING_MAX_DESC_VER_2_3))) { + return -EINVAL; + } - /* save vlan group */ - np->vlangrp = grp; + /* allocate new rings */ + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + rxtx_ring = pci_alloc_consistent(np->pci_dev, + sizeof(struct ring_desc) * (ring->rx_pending + ring->tx_pending), + &ring_addr); + } else { + rxtx_ring = pci_alloc_consistent(np->pci_dev, + sizeof(struct ring_desc_ex) * (ring->rx_pending + ring->tx_pending), + &ring_addr); + } + rx_skbuff = kmalloc(sizeof(struct sk_buff*) * ring->rx_pending, GFP_KERNEL); + rx_dma = kmalloc(sizeof(dma_addr_t) * ring->rx_pending, GFP_KERNEL); + tx_skbuff = kmalloc(sizeof(struct sk_buff*) * ring->tx_pending, GFP_KERNEL); + tx_dma = kmalloc(sizeof(dma_addr_t) * ring->tx_pending, GFP_KERNEL); + tx_dma_len = kmalloc(sizeof(unsigned int) * ring->tx_pending, GFP_KERNEL); + if (!rxtx_ring || !rx_skbuff || !rx_dma || !tx_skbuff || !tx_dma || !tx_dma_len) { + /* fall back to old rings */ + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + if(rxtx_ring) + pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (ring->rx_pending + ring->tx_pending), + rxtx_ring, ring_addr); + } else { + if (rxtx_ring) + pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (ring->rx_pending + ring->tx_pending), + rxtx_ring, ring_addr); + } + if (rx_skbuff) + kfree(rx_skbuff); + if (rx_dma) + kfree(rx_dma); + if (tx_skbuff) + kfree(tx_skbuff); + if (tx_dma) + kfree(tx_dma); + if (tx_dma_len) + kfree(tx_dma_len); + goto exit; + } - if (grp) { - /* enable vlan on MAC */ - np->txrxctl_bits |= NVREG_TXRXCTL_VLANSTRIP | NVREG_TXRXCTL_VLANINS; + if (netif_running(dev)) { + nv_disable_irq(dev); + spin_lock_bh(&dev->xmit_lock); + spin_lock(&np->lock); + /* stop engines */ + nv_stop_rx(dev); + nv_stop_tx(dev); + nv_txrx_reset(dev); + /* drain queues */ + nv_drain_rx(dev); + nv_drain_tx(dev); + /* delete queues */ + free_rings(dev); + } + + /* set new values */ + np->rx_ring_size = ring->rx_pending; + np->tx_ring_size = ring->tx_pending; + np->tx_limit_stop = ring->tx_pending - TX_LIMIT_DIFFERENCE; + np->tx_limit_start = ring->tx_pending - TX_LIMIT_DIFFERENCE - 1; + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->rx_ring.orig = (struct ring_desc*)rxtx_ring; + np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size]; } else { - /* disable vlan on MAC */ - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANSTRIP; - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANINS; + np->rx_ring.ex = (struct ring_desc_ex*)rxtx_ring; + np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; } + np->rx_skbuff = (struct sk_buff**)rx_skbuff; + np->rx_dma = (dma_addr_t*)rx_dma; + np->tx_skbuff = (struct sk_buff**)tx_skbuff; + np->tx_dma = (dma_addr_t*)tx_dma; + np->tx_dma_len = (unsigned int*)tx_dma_len; + np->ring_addr = ring_addr; + + memset(np->rx_skbuff, 0, sizeof(struct sk_buff*) * np->rx_ring_size); + memset(np->rx_dma, 0, sizeof(dma_addr_t) * np->rx_ring_size); + memset(np->tx_skbuff, 0, sizeof(struct sk_buff*) * np->tx_ring_size); + memset(np->tx_dma, 0, sizeof(dma_addr_t) * np->tx_ring_size); + memset(np->tx_dma_len, 0, sizeof(unsigned int) * np->tx_ring_size); - writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + if (netif_running(dev)) { + /* reinit driver view of the queues */ + set_bufsize(dev); + if (nv_init_ring(dev)) { + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + } - spin_unlock_irq(&np->lock); -}; + /* reinit nic view of the queues */ + writel(np->rx_buf_sz, base + NvRegOffloadConfig); + setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + base + NvRegRingSizes); + pci_push(base); + writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + pci_push(base); -static void nv_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) + /* restart engines */ + nv_start_rx(dev); + nv_start_tx(dev); + spin_unlock(&np->lock); + spin_unlock_bh(&dev->xmit_lock); + nv_enable_irq(dev); + } + return 0; +exit: + return -ENOMEM; +} + +static void nv_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam* pause) { - /* nothing to do */ -}; + struct fe_priv *np = netdev_priv(dev); -static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask) + pause->autoneg = (np->pause_flags & NV_PAUSEFRAME_AUTONEG) != 0; + pause->rx_pause = (np->pause_flags & NV_PAUSEFRAME_RX_ENABLE) != 0; + pause->tx_pause = (np->pause_flags & NV_PAUSEFRAME_TX_ENABLE) != 0; +} + +static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* pause) +{ + struct fe_priv *np = netdev_priv(dev); + int adv, bmcr; + + if ((!np->autoneg && np->duplex == 0) || + (np->autoneg && !pause->autoneg && np->duplex == 0)) { + printk(KERN_INFO "%s: can not set pause settings when forced link is in half duplex.\n", + dev->name); + return -EINVAL; + } + if (pause->tx_pause && !(np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE)) { + printk(KERN_INFO "%s: hardware does not support tx pause frames.\n", dev->name); + return -EINVAL; + } + + netif_carrier_off(dev); + if (netif_running(dev)) { + nv_disable_irq(dev); + spin_lock_bh(&dev->xmit_lock); + spin_lock(&np->lock); + /* stop engines */ + nv_stop_rx(dev); + nv_stop_tx(dev); + spin_unlock(&np->lock); + spin_unlock_bh(&dev->xmit_lock); + } + + np->pause_flags &= ~(NV_PAUSEFRAME_RX_REQ|NV_PAUSEFRAME_TX_REQ); + if (pause->rx_pause) + np->pause_flags |= NV_PAUSEFRAME_RX_REQ; + if (pause->tx_pause) + np->pause_flags |= NV_PAUSEFRAME_TX_REQ; + + if (np->autoneg && pause->autoneg) { + np->pause_flags |= NV_PAUSEFRAME_AUTONEG; + + adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); + adv &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); + if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) /* for rx we set both advertisments but disable tx pause */ + adv |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) + adv |= ADVERTISE_PAUSE_ASYM; + mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); + + if (netif_running(dev)) + printk(KERN_INFO "%s: link down.\n", dev->name); + bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); + mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); + } else { + np->pause_flags &= ~(NV_PAUSEFRAME_AUTONEG|NV_PAUSEFRAME_RX_ENABLE|NV_PAUSEFRAME_TX_ENABLE); + if (pause->rx_pause) + np->pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + if (pause->tx_pause) + np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE; + + if (!netif_running(dev)) + nv_update_linkspeed(dev); + else + nv_update_pause(dev, np->pause_flags); + } + + if (netif_running(dev)) { + nv_start_rx(dev); + nv_start_tx(dev); + nv_enable_irq(dev); + } + return 0; +} + +static u32 nv_get_rx_csum(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + return (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) != 0; +} + +static int nv_set_rx_csum(struct net_device *dev, u32 data) { + struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - int i; - u32 msixmap = 0; + int retcode = 0; - /* Each interrupt bit can be mapped to a MSIX vector (4 bits). - * MSIXMap0 represents the first 8 interrupts and MSIXMap1 represents - * the remaining 8 interrupts. - */ - for (i = 0; i < 8; i++) { - if ((irqmask >> i) & 0x1) { - msixmap |= vector << (i << 2); + if (np->driver_data & DEV_HAS_CHECKSUM) { + + if (((np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && data) || + (!(np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && !data)) { + /* already set or unset */ + return 0; } - } - writel(readl(base + NvRegMSIXMap0) | msixmap, base + NvRegMSIXMap0); - msixmap = 0; - for (i = 0; i < 8; i++) { - if ((irqmask >> (i + 8)) & 0x1) { - msixmap |= vector << (i << 2); + if (data) { + np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; + } else if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) { + np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; + } else { + printk(KERN_INFO "Can not disable rx checksum if vlan is enabled\n"); + return -EINVAL; } + + if (netif_running(dev)) { + spin_lock_irq(&np->lock); + writel(np->txrxctl_bits, base + NvRegTxRxControl); + spin_unlock_irq(&np->lock); + } + } else { + return -EINVAL; } - writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); + + return retcode; } -static int nv_request_irq(struct net_device *dev) +static int nv_set_tx_csum(struct net_device *dev, u32 data) +{ + struct fe_priv *np = netdev_priv(dev); + + if (np->driver_data & DEV_HAS_CHECKSUM) + return ethtool_op_set_tx_hw_csum(dev, data); + else + return -EOPNOTSUPP; +} + +static int nv_set_sg(struct net_device *dev, u32 data) +{ + struct fe_priv *np = netdev_priv(dev); + + if (np->driver_data & DEV_HAS_CHECKSUM) + return ethtool_op_set_sg(dev, data); + else + return -EOPNOTSUPP; +} + +static int nv_get_stats_count(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + + if (np->driver_data & DEV_HAS_STATISTICS) + return (sizeof(struct nv_ethtool_stats)/sizeof(u64)); + else + return 0; +} + +static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *buffer) +{ + struct fe_priv *np = netdev_priv(dev); + + /* update stats */ + nv_do_stats_poll((unsigned long)dev); + + memcpy(buffer, &np->estats, nv_get_stats_count(dev)*sizeof(u64)); +} + +static int nv_self_test_count(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + + if (np->driver_data & DEV_HAS_TEST_EXTENDED) + return NV_TEST_COUNT_EXTENDED; + else + return NV_TEST_COUNT_BASE; +} + +static int nv_link_test(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + int mii_status; + + mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + + /* check phy link status */ + if (!(mii_status & BMSR_LSTATUS)) + return 0; + else + return 1; +} + +static int nv_register_test(struct net_device *dev) { - struct fe_priv *np = get_nvpriv(dev); + u8 __iomem *base = get_hwbase(dev); + int i = 0; + u32 orig_read, new_read; + + do { + orig_read = readl(base + nv_registers_test[i].reg); + + /* xor with mask to toggle bits */ + orig_read ^= nv_registers_test[i].mask; + + writel(orig_read, base + nv_registers_test[i].reg); + + new_read = readl(base + nv_registers_test[i].reg); + + if ((new_read & nv_registers_test[i].mask) != (orig_read & nv_registers_test[i].mask)) + return 0; + + /* restore original value */ + orig_read ^= nv_registers_test[i].mask; + writel(orig_read, base + nv_registers_test[i].reg); + + } while (nv_registers_test[++i].reg != 0); + + return 1; +} + +static int nv_interrupt_test(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); int ret = 1; - int i; + int testcnt; + u32 save_msi_flags, save_poll_interval = 0; - if (np->msi_flags & NV_MSI_X_CAPABLE) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { - np->msi_x_entry[i].entry = i; + if (netif_running(dev)) { + /* free current irq */ + nv_free_irq(dev); + save_poll_interval = readl(base+NvRegPollingInterval); + } + + /* flag to test interrupt handler */ + np->intr_test = 0; + + /* setup test irq */ + save_msi_flags = np->msi_flags; + np->msi_flags &= ~NV_MSI_X_VECTORS_MASK; + np->msi_flags |= 0x001; /* setup 1 vector */ + if (nv_request_irq(dev, 1)) + return 0; + + /* setup timer interrupt */ + writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval); + writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); + + nv_enable_hw_interrupts(dev, NVREG_IRQ_TIMER); + + /* wait for at least one interrupt */ + msleep(100); + + spin_lock_irq(&np->lock); + + /* flag should be set within ISR */ + testcnt = np->intr_test; + if (!testcnt) + ret = 2; + + nv_disable_hw_interrupts(dev, NVREG_IRQ_TIMER); + if (!(np->msi_flags & NV_MSI_X_ENABLED)) + writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); + else + writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); + + spin_unlock_irq(&np->lock); + + nv_free_irq(dev); + + np->msi_flags = save_msi_flags; + + if (netif_running(dev)) { + writel(save_poll_interval, base + NvRegPollingInterval); + writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); + /* restore original irq */ + if (nv_request_irq(dev, 0)) + return 0; + } + + return ret; +} + +static int nv_loopback_test(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + u8 __iomem *base = get_hwbase(dev); + struct sk_buff *tx_skb, *rx_skb; + dma_addr_t test_dma_addr; + u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET); + u32 Flags; + int len, i, pkt_len; + u8 *pkt_data; + u32 filter_flags = 0; + u32 misc1_flags = 0; + int ret = 1; + + if (netif_running(dev)) { + nv_disable_irq(dev); + filter_flags = readl(base + NvRegPacketFilterFlags); + misc1_flags = readl(base + NvRegMisc1); + } else { + nv_txrx_reset(dev); + } + + /* reinit driver view of the rx queue */ + set_bufsize(dev); + nv_init_ring(dev); + + /* setup hardware for loopback */ + writel(NVREG_MISC1_FORCE, base + NvRegMisc1); + writel(NVREG_PFF_ALWAYS | NVREG_PFF_LOOPBACK, base + NvRegPacketFilterFlags); + + /* reinit nic view of the rx queue */ + writel(np->rx_buf_sz, base + NvRegOffloadConfig); + setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + base + NvRegRingSizes); + pci_push(base); + + /* restart rx engine */ + nv_start_rx(dev); + nv_start_tx(dev); + + /* setup packet for tx */ + pkt_len = ETH_DATA_LEN; + tx_skb = dev_alloc_skb(pkt_len); + pkt_data = skb_put(tx_skb, pkt_len); + for (i = 0; i < pkt_len; i++) + pkt_data[i] = (u8)(i & 0xff); + test_dma_addr = pci_map_single(np->pci_dev, tx_skb->data, + tx_skb->end-tx_skb->data, PCI_DMA_FROMDEVICE); + + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + np->tx_ring.orig[0].PacketBuffer = cpu_to_le32(test_dma_addr); + np->tx_ring.orig[0].FlagLen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra); + } else { + np->tx_ring.ex[0].PacketBufferHigh = cpu_to_le64(test_dma_addr) >> 32; + np->tx_ring.ex[0].PacketBufferLow = cpu_to_le64(test_dma_addr) & 0x0FFFFFFFF; + np->tx_ring.ex[0].FlagLen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra); + } + writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + pci_push(get_hwbase(dev)); + + msleep(500); + + /* check for rx of the packet */ + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { + Flags = le32_to_cpu(np->rx_ring.orig[0].FlagLen); + len = nv_descr_getlength(&np->rx_ring.orig[0], np->desc_ver); + + } else { + Flags = le32_to_cpu(np->rx_ring.ex[0].FlagLen); + len = nv_descr_getlength_ex(&np->rx_ring.ex[0], np->desc_ver); + } + + if (Flags & NV_RX_AVAIL) { + ret = 0; + } else if (np->desc_ver == DESC_VER_1) { + if (Flags & NV_RX_ERROR) + ret = 0; + } else { + if (Flags & NV_RX2_ERROR) { + ret = 0; } - if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) { - np->msi_flags |= NV_MSI_X_ENABLED; - if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) { - /* Request irq for rx handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_err; - } - /* Request irq for tx handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_free_rx; - } - /* Request irq for link and timer handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_free_tx; - } - /* map interrupts to their respective vector */ - writel(0, base + NvRegMSIXMap0); - writel(0, base + NvRegMSIXMap1); - set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL); - set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL); - set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER); - } else { - /* Request irq for all interrupts */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_err; - } + } - /* map interrupts to vector 0 */ - writel(0, base + NvRegMSIXMap0); - writel(0, base + NvRegMSIXMap1); + if (ret) { + if (len != pkt_len) { + ret = 0; + dprintk(KERN_DEBUG "%s: loopback len mismatch %d vs %d\n", + dev->name, len, pkt_len); + } else { + rx_skb = np->rx_skbuff[0]; + for (i = 0; i < pkt_len; i++) { + if (rx_skb->data[i] != (u8)(i & 0xff)) { + ret = 0; + dprintk(KERN_DEBUG "%s: loopback pattern check failed on byte %d\n", + dev->name, i); + break; + } } } + } else { + dprintk(KERN_DEBUG "%s: loopback - did not receive test packet\n", dev->name); } - if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { - if ((ret = pci_enable_msi(np->pci_dev)) == 0) { - np->msi_flags |= NV_MSI_ENABLED; - if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); - pci_disable_msi(np->pci_dev); - np->msi_flags &= ~NV_MSI_ENABLED; - goto out_err; + + pci_unmap_page(np->pci_dev, test_dma_addr, + tx_skb->end-tx_skb->data, + PCI_DMA_TODEVICE); + dev_kfree_skb_any(tx_skb); + + /* stop engines */ + nv_stop_rx(dev); + nv_stop_tx(dev); + nv_txrx_reset(dev); + /* drain rx queue */ + nv_drain_rx(dev); + nv_drain_tx(dev); + + if (netif_running(dev)) { + writel(misc1_flags, base + NvRegMisc1); + writel(filter_flags, base + NvRegPacketFilterFlags); + nv_enable_irq(dev); + } + + return ret; +} + +static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 *buffer) +{ + struct fe_priv *np = netdev_priv(dev); + u8 __iomem *base = get_hwbase(dev); + int result; + memset(buffer, 0, nv_self_test_count(dev)*sizeof(u64)); + + if (!nv_link_test(dev)) { + test->flags |= ETH_TEST_FL_FAILED; + buffer[0] = 1; + } + + if (test->flags & ETH_TEST_FL_OFFLINE) { + if (netif_running(dev)) { + netif_stop_queue(dev); + spin_lock_bh(&dev->xmit_lock); + spin_lock_irq(&np->lock); + nv_disable_hw_interrupts(dev, np->irqmask); + if (!(np->msi_flags & NV_MSI_X_ENABLED)) { + writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); + } else { + writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); } + /* stop engines */ + nv_stop_rx(dev); + nv_stop_tx(dev); + nv_txrx_reset(dev); + /* drain rx queue */ + nv_drain_rx(dev); + nv_drain_tx(dev); + spin_unlock_irq(&np->lock); + spin_unlock_bh(&dev->xmit_lock); + } - /* map interrupts to vector 0 */ - writel(0, base + NvRegMSIMap0); - writel(0, base + NvRegMSIMap1); - /* enable msi vector 0 */ - writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); + if (!nv_register_test(dev)) { + test->flags |= ETH_TEST_FL_FAILED; + buffer[1] = 1; + } + + result = nv_interrupt_test(dev); + if (result != 1) { + test->flags |= ETH_TEST_FL_FAILED; + buffer[2] = 1; + } + if (result == 0) { + /* bail out */ + return; + } + + if (!nv_loopback_test(dev)) { + test->flags |= ETH_TEST_FL_FAILED; + buffer[3] = 1; + } + + if (netif_running(dev)) { + /* reinit driver view of the rx queue */ + set_bufsize(dev); + if (nv_init_ring(dev)) { + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + } + /* reinit nic view of the rx queue */ + writel(np->rx_buf_sz, base + NvRegOffloadConfig); + setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + base + NvRegRingSizes); + pci_push(base); + writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + pci_push(base); + /* restart rx engine */ + nv_start_rx(dev); + nv_start_tx(dev); + netif_start_queue(dev); + nv_enable_hw_interrupts(dev, np->irqmask); } } - if (ret != 0) { - if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) - goto out_err; - } +} - return 0; -out_free_tx: - free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, dev); -out_free_rx: - free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, dev); -out_err: - return 1; +static void nv_get_strings(struct net_device *dev, u32 stringset, u8 *buffer) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(buffer, &nv_estats_str, nv_get_stats_count(dev)*sizeof(struct nv_ethtool_str)); + break; + case ETH_SS_TEST: + memcpy(buffer, &nv_etests_str, nv_self_test_count(dev)*sizeof(struct nv_ethtool_str)); + break; + } } -static void nv_free_irq(struct net_device *dev) +static struct ethtool_ops ops = { + .get_drvinfo = nv_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_wol = nv_get_wol, + .set_wol = nv_set_wol, + .get_settings = nv_get_settings, + .set_settings = nv_set_settings, + .get_regs_len = nv_get_regs_len, + .get_regs = nv_get_regs, + .nway_reset = nv_nway_reset, + .get_perm_addr = ethtool_op_get_perm_addr, + .get_tso = ethtool_op_get_tso, + .set_tso = nv_set_tso, + .get_ringparam = nv_get_ringparam, + .set_ringparam = nv_set_ringparam, + .get_pauseparam = nv_get_pauseparam, + .set_pauseparam = nv_set_pauseparam, + .get_rx_csum = nv_get_rx_csum, + .set_rx_csum = nv_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = nv_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = nv_set_sg, + .get_strings = nv_get_strings, + .get_stats_count = nv_get_stats_count, + .get_ethtool_stats = nv_get_ethtool_stats, + .self_test_count = nv_self_test_count, + .self_test = nv_self_test, +}; + +static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) { struct fe_priv *np = get_nvpriv(dev); - int i; - if (np->msi_flags & NV_MSI_X_ENABLED) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { - free_irq(np->msi_x_entry[i].vector, dev); - } - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; + spin_lock_irq(&np->lock); + + /* save vlan group */ + np->vlangrp = grp; + + if (grp) { + /* enable vlan on MAC */ + np->txrxctl_bits |= NVREG_TXRXCTL_VLANSTRIP | NVREG_TXRXCTL_VLANINS; } else { - free_irq(np->pci_dev->irq, dev); - if (np->msi_flags & NV_MSI_ENABLED) { - pci_disable_msi(np->pci_dev); - np->msi_flags &= ~NV_MSI_ENABLED; - } + /* disable vlan on MAC */ + np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANSTRIP; + np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANINS; } -} + + writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + + spin_unlock_irq(&np->lock); +}; + +static void nv_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) +{ + /* nothing to do */ +}; static int nv_open(struct net_device *dev) { @@ -2908,7 +3905,7 @@ static int nv_open(struct net_device *dev) /* 4) give hw rings */ setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); /* 5) continue setup */ @@ -2950,7 +3947,8 @@ static int nv_open(struct net_device *dev) base + NvRegAdapterControl); writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed); writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4); - writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags); + if (np->wolenabled) + writel(NVREG_WAKEUPFLAGS_ENABLE , base + NvRegWakeUpFlags); i = readl(base + NvRegPowerState); if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) @@ -2966,7 +3964,7 @@ static int nv_open(struct net_device *dev) writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); - if (nv_request_irq(dev)) { + if (nv_request_irq(dev, 0)) { goto out_drain; } @@ -3003,6 +4001,11 @@ static int nv_open(struct net_device *dev) } if (oom) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + + /* start statistics timer */ + if (np->driver_data & DEV_HAS_STATISTICS) + mod_timer(&np->stats_poll, jiffies + STATS_INTERVAL); + spin_unlock_irq(&np->lock); return 0; @@ -3023,6 +4026,7 @@ static int nv_close(struct net_device *dev) del_timer_sync(&np->oom_kick); del_timer_sync(&np->nic_poll); + del_timer_sync(&np->stats_poll); netif_stop_queue(dev); spin_lock_irq(&np->lock); @@ -3082,6 +4086,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i init_timer(&np->nic_poll); np->nic_poll.data = (unsigned long) dev; np->nic_poll.function = &nv_do_nic_poll; /* timer handler */ + init_timer(&np->stats_poll); + np->stats_poll.data = (unsigned long) dev; + np->stats_poll.function = &nv_do_stats_poll; /* timer handler */ err = pci_enable_device(pci_dev); if (err) { @@ -3096,7 +4103,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (err < 0) goto out_disable; - if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL)) + if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS)) np->register_size = NV_PCI_REGSZ_VER2; else np->register_size = NV_PCI_REGSZ_VER1; @@ -3128,16 +4135,18 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* packet format 3: supports 40-bit addressing */ np->desc_ver = DESC_VER_3; np->txrxctl_bits = NVREG_TXRXCTL_DESC_3; - if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) { - printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n", - pci_name(pci_dev)); - } else { - dev->features |= NETIF_F_HIGHDMA; - printk(KERN_INFO "forcedeth: using HIGHDMA\n"); - } - if (pci_set_consistent_dma_mask(pci_dev, 0x0000007fffffffffULL)) { - printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed for device %s.\n", - pci_name(pci_dev)); + if (dma_64bit) { + if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) { + printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n", + pci_name(pci_dev)); + } else { + dev->features |= NETIF_F_HIGHDMA; + printk(KERN_INFO "forcedeth: using HIGHDMA\n"); + } + if (pci_set_consistent_dma_mask(pci_dev, DMA_39BIT_MASK)) { + printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed, using 32-bit ring buffers for device %s.\n", + pci_name(pci_dev)); + } } } else if (id->driver_data & DEV_HAS_LARGEDESC) { /* packet format 2: supports jumbo frames */ @@ -3170,16 +4179,16 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i } np->msi_flags = 0; - if ((id->driver_data & DEV_HAS_MSI) && !disable_msi) { + if ((id->driver_data & DEV_HAS_MSI) && msi) { np->msi_flags |= NV_MSI_CAPABLE; } - if ((id->driver_data & DEV_HAS_MSI_X) && !disable_msix) { + if ((id->driver_data & DEV_HAS_MSI_X) && msix) { np->msi_flags |= NV_MSI_X_CAPABLE; } - np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE; + np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG; if (id->driver_data & DEV_HAS_PAUSEFRAME_TX) { - np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE; + np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ; } @@ -3191,21 +4200,38 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->irq = pci_dev->irq; + np->rx_ring_size = RX_RING_DEFAULT; + np->tx_ring_size = TX_RING_DEFAULT; + np->tx_limit_stop = np->tx_ring_size - TX_LIMIT_DIFFERENCE; + np->tx_limit_start = np->tx_ring_size - TX_LIMIT_DIFFERENCE - 1; + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { np->rx_ring.orig = pci_alloc_consistent(pci_dev, - sizeof(struct ring_desc) * (RX_RING + TX_RING), + sizeof(struct ring_desc) * (np->rx_ring_size + np->tx_ring_size), &np->ring_addr); if (!np->rx_ring.orig) goto out_unmap; - np->tx_ring.orig = &np->rx_ring.orig[RX_RING]; + np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size]; } else { np->rx_ring.ex = pci_alloc_consistent(pci_dev, - sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), + sizeof(struct ring_desc_ex) * (np->rx_ring_size + np->tx_ring_size), &np->ring_addr); if (!np->rx_ring.ex) goto out_unmap; - np->tx_ring.ex = &np->rx_ring.ex[RX_RING]; + np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; } + np->rx_skbuff = kmalloc(sizeof(struct sk_buff*) * np->rx_ring_size, GFP_KERNEL); + np->rx_dma = kmalloc(sizeof(dma_addr_t) * np->rx_ring_size, GFP_KERNEL); + np->tx_skbuff = kmalloc(sizeof(struct sk_buff*) * np->tx_ring_size, GFP_KERNEL); + np->tx_dma = kmalloc(sizeof(dma_addr_t) * np->tx_ring_size, GFP_KERNEL); + np->tx_dma_len = kmalloc(sizeof(unsigned int) * np->tx_ring_size, GFP_KERNEL); + if (!np->rx_skbuff || !np->rx_dma || !np->tx_skbuff || !np->tx_dma || !np->tx_dma_len) + goto out_freering; + memset(np->rx_skbuff, 0, sizeof(struct sk_buff*) * np->rx_ring_size); + memset(np->rx_dma, 0, sizeof(dma_addr_t) * np->rx_ring_size); + memset(np->tx_skbuff, 0, sizeof(struct sk_buff*) * np->tx_ring_size); + memset(np->tx_dma, 0, sizeof(dma_addr_t) * np->tx_ring_size); + memset(np->tx_dma_len, 0, sizeof(unsigned int) * np->tx_ring_size); dev->open = nv_open; dev->stop = nv_close; @@ -3327,7 +4353,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (i == 33) { printk(KERN_INFO "%s: open: Could not find a valid PHY.\n", pci_name(pci_dev)); - goto out_freering; + goto out_error; } /* reset it */ @@ -3341,7 +4367,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i err = register_netdev(dev); if (err) { printk(KERN_INFO "forcedeth: unable to register netdev: %d\n", err); - goto out_freering; + goto out_error; } printk(KERN_INFO "%s: forcedeth.c: subsystem: %05x:%04x bound to %s\n", dev->name, pci_dev->subsystem_vendor, pci_dev->subsystem_device, @@ -3349,14 +4375,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i return 0; -out_freering: - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), - np->rx_ring.orig, np->ring_addr); - else - pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), - np->rx_ring.ex, np->ring_addr); +out_error: pci_set_drvdata(pci_dev, NULL); +out_freering: + free_rings(dev); out_unmap: iounmap(get_hwbase(dev)); out_relreg: @@ -3372,15 +4394,11 @@ out: static void __devexit nv_remove(struct pci_dev *pci_dev) { struct net_device *dev = pci_get_drvdata(pci_dev); - struct fe_priv *np = netdev_priv(dev); unregister_netdev(dev); /* free all structures */ - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), np->rx_ring.orig, np->ring_addr); - else - pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), np->rx_ring.ex, np->ring_addr); + free_rings(dev); iounmap(get_hwbase(dev)); pci_release_regions(pci_dev); pci_disable_device(pci_dev); @@ -3443,11 +4461,43 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP61 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP61 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP61 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP61 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP65 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP65 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP65 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, + }, + { /* MCP65 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED, }, {0,}, }; @@ -3477,10 +4527,12 @@ module_param(optimization_mode, int, 0); MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer."); module_param(poll_interval, int, 0); MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535."); -module_param(disable_msi, int, 0); -MODULE_PARM_DESC(disable_msi, "Disable MSI interrupts by setting to 1."); -module_param(disable_msix, int, 0); -MODULE_PARM_DESC(disable_msix, "Disable MSIX interrupts by setting to 1."); +module_param(msi, int, 0); +MODULE_PARM_DESC(msi, "MSI interrupts are enabled by setting to 1 and disabled by setting to 0."); +module_param(msix, int, 0); +MODULE_PARM_DESC(msix, "MSIX interrupts are enabled by setting to 1 and disabled by setting to 0."); +module_param(dma_64bit, int, 0); +MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0."); MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>"); MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 102c1f0b90d..d12605f0ac7 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr_ax25 *sa = addr; - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return 0; } @@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file, break; } - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); err = 0; break; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index d81a8e1eeb8..3ebbbe56b6e 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr_ax25 *sa = addr; - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return 0; } @@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file, break; } - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); err = 0; break; diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 0d7a6250e34..e26a3e407d7 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -446,7 +446,7 @@ MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ -int +int __init init_module(void) { struct net_device *dev; diff --git a/drivers/net/hp.c b/drivers/net/hp.c index cf9fb3698a6..551a71b3c5f 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -384,7 +384,7 @@ hp_block_output(struct net_device *dev, int count, } /* This function resets the ethercard if something screws up. */ -static void +static void __init hp_init_card(struct net_device *dev) { int irq = dev->irq; @@ -409,7 +409,7 @@ MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ -int +int __init init_module(void) { struct net_device *dev; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 31fb2d75dc4..2e222ef91e2 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev) dp->st_task_enter++; if ((skb = skb_peek(&dp->tq)) == NULL) { dp->st_txq_refl_try++; - if (spin_trylock(&_dev->xmit_lock)) { + if (netif_tx_trylock(_dev)) { dp->st_rxq_enter++; while ((skb = skb_dequeue(&dp->rq)) != NULL) { skb_queue_tail(&dp->tq, skb); dp->st_rx2tx_tran++; } - spin_unlock(&_dev->xmit_lock); + netif_tx_unlock(_dev); } else { /* reschedule */ dp->st_rxq_notenter++; @@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev) } } - if (spin_trylock(&_dev->xmit_lock)) { + if (netif_tx_trylock(_dev)) { dp->st_rxq_check++; if ((skb = skb_peek(&dp->rq)) == NULL) { dp->tasklet_pending = 0; @@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev) netif_wake_queue(_dev); } else { dp->st_rxq_rsch++; - spin_unlock(&_dev->xmit_lock); + netif_tx_unlock(_dev); goto resched; } - spin_unlock(&_dev->xmit_lock); + netif_tx_unlock(_dev); } else { resched: dp->tasklet_pending = 1; diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index cff8598aa80..d2ce4896abf 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -417,5 +417,20 @@ config PXA_FICP available capabilities may vary from one PXA2xx target to another. +config MCS_FIR + tristate "MosChip MCS7780 IrDA-USB dongle" + depends on IRDA && USB && EXPERIMENTAL + help + Say Y or M here if you want to build support for the MosChip + MCS7780 IrDA-USB bridge device driver. + + USB bridge based on the MosChip MCS7780 don't conform to the + IrDA-USB device class specification, and therefore need their + own specific driver. Those dongles support SIR and FIR (4Mbps) + speeds. + + To compile it as a module, choose M here: the module will be called + mcs7780. + endmenu diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index c1ce2398efe..5be09f1b9ee 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_ALI_FIR) += ali-ircc.o obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o obj-$(CONFIG_VIA_FIR) += via-ircc.o obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o +obj-$(CONFIG_MCS_FIR) += mcs7780.o # Old dongle drivers for old SIR drivers obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 2e7882eb7d6..bf1fca5a3fa 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -34,14 +34,12 @@ #include <linux/rtnetlink.h> #include <linux/serial_reg.h> #include <linux/dma-mapping.h> +#include <linux/platform_device.h> #include <asm/io.h> #include <asm/dma.h> #include <asm/byteorder.h> -#include <linux/pm.h> -#include <linux/pm_legacy.h> - #include <net/irda/wrapper.h> #include <net/irda/irda.h> #include <net/irda/irda_device.h> @@ -51,7 +49,19 @@ #define CHIP_IO_EXTENT 8 #define BROKEN_DONGLE_ID -static char *driver_name = "ali-ircc"; +#define ALI_IRCC_DRIVER_NAME "ali-ircc" + +/* Power Management */ +static int ali_ircc_suspend(struct platform_device *dev, pm_message_t state); +static int ali_ircc_resume(struct platform_device *dev); + +static struct platform_driver ali_ircc_driver = { + .suspend = ali_ircc_suspend, + .resume = ali_ircc_resume, + .driver = { + .name = ALI_IRCC_DRIVER_NAME, + }, +}; /* Module parameters */ static int qos_mtt_bits = 0x07; /* 1 ms or more */ @@ -97,10 +107,7 @@ static int ali_ircc_is_receiving(struct ali_ircc_cb *self); static int ali_ircc_net_open(struct net_device *dev); static int ali_ircc_net_close(struct net_device *dev); static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static int ali_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data); static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud); -static void ali_ircc_suspend(struct ali_ircc_cb *self); -static void ali_ircc_wakeup(struct ali_ircc_cb *self); static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev); /* SIR function */ @@ -145,6 +152,14 @@ static int __init ali_ircc_init(void) int i = 0; IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); + + ret = platform_driver_register(&ali_ircc_driver); + if (ret) { + IRDA_ERROR("%s, Can't register driver!\n", + ALI_IRCC_DRIVER_NAME); + return ret; + } + /* Probe for all the ALi chipsets we know about */ for (chip= chips; chip->name; chip++, i++) @@ -214,6 +229,10 @@ static int __init ali_ircc_init(void) } IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); + + if (ret) + platform_driver_unregister(&ali_ircc_driver); + return ret; } @@ -228,14 +247,14 @@ static void __exit ali_ircc_cleanup(void) int i; IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); - - pm_unregister_all(ali_ircc_pmproc); for (i=0; i < 4; i++) { if (dev_self[i]) ali_ircc_close(dev_self[i]); } + platform_driver_unregister(&ali_ircc_driver); + IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); } @@ -249,7 +268,6 @@ static int ali_ircc_open(int i, chipio_t *info) { struct net_device *dev; struct ali_ircc_cb *self; - struct pm_dev *pmdev; int dongle_id; int err; @@ -284,7 +302,8 @@ static int ali_ircc_open(int i, chipio_t *info) self->io.fifo_size = 16; /* SIR: 16, FIR: 32 Benjamin 2000/11/1 */ /* Reserve the ioports that we need */ - if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) { + if (!request_region(self->io.fir_base, self->io.fir_ext, + ALI_IRCC_DRIVER_NAME)) { IRDA_WARNING("%s(), can't get iobase of 0x%03x\n", __FUNCTION__, self->io.fir_base); err = -ENODEV; @@ -354,13 +373,10 @@ static int ali_ircc_open(int i, chipio_t *info) /* Check dongle id */ dongle_id = ali_ircc_read_dongle_id(i, info); - IRDA_MESSAGE("%s(), %s, Found dongle: %s\n", __FUNCTION__, driver_name, dongle_types[dongle_id]); + IRDA_MESSAGE("%s(), %s, Found dongle: %s\n", __FUNCTION__, + ALI_IRCC_DRIVER_NAME, dongle_types[dongle_id]); self->io.dongle_id = dongle_id; - - pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, ali_ircc_pmproc); - if (pmdev) - pmdev->data = self; IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); @@ -548,12 +564,11 @@ static int ali_ircc_setup(chipio_t *info) /* Should be 0x00 in the M1535/M1535D */ if(version != 0x00) { - IRDA_ERROR("%s, Wrong chip version %02x\n", driver_name, version); + IRDA_ERROR("%s, Wrong chip version %02x\n", + ALI_IRCC_DRIVER_NAME, version); return -1; } - // IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name, info->cfg_base); - /* Set FIR FIFO Threshold Register */ switch_bank(iobase, BANK1); outb(RX_FIFO_Threshold, iobase+FIR_FIFO_TR); @@ -583,7 +598,8 @@ static int ali_ircc_setup(chipio_t *info) /* Switch to SIR space */ FIR2SIR(iobase); - IRDA_MESSAGE("%s, driver loaded (Benjamin Kong)\n", driver_name); + IRDA_MESSAGE("%s, driver loaded (Benjamin Kong)\n", + ALI_IRCC_DRIVER_NAME); /* Enable receive interrupts */ // outb(UART_IER_RDI, iobase+UART_IER); //benjamin 2000/11/23 01:25PM @@ -647,7 +663,8 @@ static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id, IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); if (!dev) { - IRDA_WARNING("%s: irq %d for unknown device.\n", driver_name, irq); + IRDA_WARNING("%s: irq %d for unknown device.\n", + ALI_IRCC_DRIVER_NAME, irq); return IRQ_NONE; } @@ -1328,7 +1345,8 @@ static int ali_ircc_net_open(struct net_device *dev) /* Request IRQ and install Interrupt Handler */ if (request_irq(self->io.irq, ali_ircc_interrupt, 0, dev->name, dev)) { - IRDA_WARNING("%s, unable to allocate irq=%d\n", driver_name, + IRDA_WARNING("%s, unable to allocate irq=%d\n", + ALI_IRCC_DRIVER_NAME, self->io.irq); return -EAGAIN; } @@ -1338,7 +1356,8 @@ static int ali_ircc_net_open(struct net_device *dev) * failure. */ if (request_dma(self->io.dma, dev->name)) { - IRDA_WARNING("%s, unable to allocate dma=%d\n", driver_name, + IRDA_WARNING("%s, unable to allocate dma=%d\n", + ALI_IRCC_DRIVER_NAME, self->io.dma); free_irq(self->io.irq, self); return -EAGAIN; @@ -2108,61 +2127,38 @@ static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev) return &self->stats; } -static void ali_ircc_suspend(struct ali_ircc_cb *self) +static int ali_ircc_suspend(struct platform_device *dev, pm_message_t state) { - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + struct ali_ircc_cb *self = platform_get_drvdata(dev); - IRDA_MESSAGE("%s, Suspending\n", driver_name); + IRDA_MESSAGE("%s, Suspending\n", ALI_IRCC_DRIVER_NAME); if (self->io.suspended) - return; + return 0; ali_ircc_net_close(self->netdev); self->io.suspended = 1; - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); + return 0; } -static void ali_ircc_wakeup(struct ali_ircc_cb *self) +static int ali_ircc_resume(struct platform_device *dev) { - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); + struct ali_ircc_cb *self = platform_get_drvdata(dev); if (!self->io.suspended) - return; + return 0; ali_ircc_net_open(self->netdev); - IRDA_MESSAGE("%s, Waking up\n", driver_name); + IRDA_MESSAGE("%s, Waking up\n", ALI_IRCC_DRIVER_NAME); self->io.suspended = 0; - - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); -} -static int ali_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data) -{ - struct ali_ircc_cb *self = (struct ali_ircc_cb*) dev->data; - - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ ); - - if (self) { - switch (rqst) { - case PM_SUSPEND: - ali_ircc_suspend(self); - break; - case PM_RESUME: - ali_ircc_wakeup(self); - break; - } - } - - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ ); - return 0; } - /* ALi Chip Function */ static void SetCOMInterrupts(struct ali_ircc_cb *self , unsigned char enable) diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index cd87593e4e8..844fa74ac9e 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -83,9 +83,9 @@ static struct usb_device_id dongles[] = { /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, /* SigmaTel STIR4210/4220/4116 USB IrDA (VFIR) Bridge */ - { USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, - { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, - { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, + { USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR421X | IUC_SPEED_BUG }, + { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR421X | IUC_SPEED_BUG }, + { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR421X | IUC_SPEED_BUG }, { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS, .bInterfaceClass = USB_CLASS_APP_SPEC, @@ -154,7 +154,7 @@ static void irda_usb_build_header(struct irda_usb_cb *self, * and if either speed or xbofs (or both) needs * to be changed. */ - if (self->capability & IUC_STIR_4210 && + if (self->capability & IUC_STIR421X && ((self->new_speed != -1) || (self->new_xbofs != -1))) { /* With STIR421x, speed and xBOFs must be set at the same @@ -318,7 +318,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) /* Set the new speed and xbofs in this fake frame */ irda_usb_build_header(self, frame, 1); - if ( self->capability & IUC_STIR_4210 ) { + if (self->capability & IUC_STIR421X) { if (frame[0] == 0) return ; // do nothing if no change frame[1] = 0; // other parameters don't change here frame[2] = 0; @@ -455,7 +455,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) /* Change setting for next frame */ - if ( self->capability & IUC_STIR_4210 ) { + if (self->capability & IUC_STIR421X) { __u8 turnaround_time; __u8* frame; turnaround_time = get_turnaround_time( skb ); @@ -897,10 +897,13 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); /* Allocate a new skb */ - if ( self->capability & IUC_STIR_4210 ) - newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU + USB_IRDA_SIGMATEL_HEADER); + if (self->capability & IUC_STIR421X) + newskb = dev_alloc_skb(docopy ? urb->actual_length : + IRDA_SKB_MAX_MTU + + USB_IRDA_STIR421X_HEADER); else - newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); + newskb = dev_alloc_skb(docopy ? urb->actual_length : + IRDA_SKB_MAX_MTU); if (!newskb) { self->stats.rx_dropped++; @@ -1022,188 +1025,140 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) return 0; /* For now */ } - -#define STIR421X_PATCH_PRODUCT_VERSION_STR "Product Version: " -#define STIR421X_PATCH_COMPONENT_VERSION_STR "Component Version: " -#define STIR421X_PATCH_DATA_TAG_STR "STMP" -#define STIR421X_PATCH_FILE_VERSION_MAX_OFFSET 512 /* version info is before here */ -#define STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET 512 /* patch image starts before here */ -#define STIR421X_PATCH_FILE_END_OF_HEADER_TAG 0x1A /* marks end of patch file header (PC DOS text file EOF character) */ +#define STIR421X_PATCH_PRODUCT_VER "Product Version: " +#define STIR421X_PATCH_STMP_TAG "STMP" +#define STIR421X_PATCH_CODE_OFFSET 512 /* patch image starts before here */ +/* marks end of patch file header (PC DOS text file EOF character) */ +#define STIR421X_PATCH_END_OF_HDR_TAG 0x1A +#define STIR421X_PATCH_BLOCK_SIZE 1023 /* - * Known firmware patches for STIR421x dongles + * Function stir421x_fwupload (struct irda_usb_cb *self, + * unsigned char *patch, + * const unsigned int patch_len) + * + * Upload firmware code to SigmaTel 421X IRDA-USB dongle */ -static char * stir421x_patches[] = { - "42101001.sb", - "42101002.sb", -}; - -static int stir421x_get_patch_version(unsigned char * patch, const unsigned long patch_len) +static int stir421x_fw_upload(struct irda_usb_cb *self, + unsigned char *patch, + const unsigned int patch_len) { - unsigned int version_offset; - unsigned long version_major, version_minor, version_build; - unsigned char * version_start; - int version_found = 0; - - for (version_offset = 0; - version_offset < STIR421X_PATCH_FILE_END_OF_HEADER_TAG; - version_offset++) { - if (!memcmp(patch + version_offset, - STIR421X_PATCH_PRODUCT_VERSION_STR, - sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1)) { - version_found = 1; - version_start = patch + - version_offset + - sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1; - break; - } + int ret = -ENOMEM; + int actual_len = 0; + unsigned int i; + unsigned int block_size = 0; + unsigned char *patch_block; + + patch_block = kzalloc(STIR421X_PATCH_BLOCK_SIZE, GFP_KERNEL); + if (patch_block == NULL) + return -ENOMEM; + + /* break up patch into 1023-byte sections */ + for (i = 0; i < patch_len; i += block_size) { + block_size = patch_len - i; + + if (block_size > STIR421X_PATCH_BLOCK_SIZE) + block_size = STIR421X_PATCH_BLOCK_SIZE; + + /* upload the patch section */ + memcpy(patch_block, patch + i, block_size); + + ret = usb_bulk_msg(self->usbdev, + usb_sndbulkpipe(self->usbdev, + self->bulk_out_ep), + patch_block, block_size, + &actual_len, msecs_to_jiffies(500)); + IRDA_DEBUG(3,"%s(): Bulk send %u bytes, ret=%d\n", + __FUNCTION__, actual_len, ret); + + if (ret < 0) + break; } - /* We couldn't find a product version on this patch */ - if (!version_found) - return -EINVAL; - - /* Let's check if the product version is dotted */ - if (version_start[3] != '.' || - version_start[7] != '.') - return -EINVAL; - - version_major = simple_strtoul(version_start, NULL, 10); - version_minor = simple_strtoul(version_start + 4, NULL, 10); - version_build = simple_strtoul(version_start + 8, NULL, 10); - - IRDA_DEBUG(2, "%s(), Major: %ld Minor: %ld Build: %ld\n", - __FUNCTION__, - version_major, version_minor, version_build); - - return (((version_major) << 12) + - ((version_minor) << 8) + - ((version_build / 10) << 4) + - (version_build % 10)); - -} - - -static int stir421x_upload_patch (struct irda_usb_cb *self, - unsigned char * patch, - const unsigned int patch_len) -{ - int retval = 0; - int actual_len; - unsigned int i = 0, download_amount = 0; - unsigned char * patch_chunk; - - IRDA_DEBUG (2, "%s(), Uploading STIR421x Patch\n", __FUNCTION__); - - patch_chunk = kzalloc(STIR421X_MAX_PATCH_DOWNLOAD_SIZE, GFP_KERNEL); - if (patch_chunk == NULL) - return -ENOMEM; - - /* break up patch into 1023-byte sections */ - for (i = 0; retval >= 0 && i < patch_len; i += download_amount) { - download_amount = patch_len - i; - if (download_amount > STIR421X_MAX_PATCH_DOWNLOAD_SIZE) - download_amount = STIR421X_MAX_PATCH_DOWNLOAD_SIZE; - - /* download the patch section */ - memcpy(patch_chunk, patch + i, download_amount); - - retval = usb_bulk_msg (self->usbdev, - usb_sndbulkpipe (self->usbdev, - self->bulk_out_ep), - patch_chunk, download_amount, - &actual_len, msecs_to_jiffies (500)); - IRDA_DEBUG (2, "%s(), Sent %u bytes\n", __FUNCTION__, - actual_len); - if (retval == 0) - mdelay(10); - } - - kfree(patch_chunk); - - if (i != patch_len) { - IRDA_ERROR ("%s(), Pushed %d bytes (!= patch_len (%d))\n", - __FUNCTION__, i, patch_len); - retval = -EIO; - } - - if (retval < 0) - /* todo - mark device as not ready */ - IRDA_ERROR ("%s(), STIR421x patch upload failed (%d)\n", - __FUNCTION__, retval); - - return retval; -} + kfree(patch_block); + return ret; + } +/* + * Function stir421x_patch_device(struct irda_usb_cb *self) + * + * Get a firmware code from userspase using hotplug request_firmware() call + */ static int stir421x_patch_device(struct irda_usb_cb *self) { - unsigned int i, patch_found = 0, data_found = 0, data_offset; - int patch_version, ret = 0; - const struct firmware *fw_entry; - - for (i = 0; i < ARRAY_SIZE(stir421x_patches); i++) { - if(request_firmware(&fw_entry, stir421x_patches[i], &self->usbdev->dev) != 0) { - IRDA_ERROR( "%s(), Patch %s is not available\n", __FUNCTION__, stir421x_patches[i]); - continue; - } - - /* We found a patch from userspace */ - patch_version = stir421x_get_patch_version (fw_entry->data, fw_entry->size); - - if (patch_version < 0) { - /* Couldn't fetch a version, let's move on to the next file */ - IRDA_ERROR("%s(), version parsing failed\n", __FUNCTION__); - ret = patch_version; - release_firmware(fw_entry); - continue; - } - - if (patch_version != self->usbdev->descriptor.bcdDevice) { - /* Patch version and device don't match */ - IRDA_ERROR ("%s(), wrong patch version (%d <-> %d)\n", - __FUNCTION__, - patch_version, self->usbdev->descriptor.bcdDevice); - ret = -EINVAL; - release_firmware(fw_entry); - continue; - } - - /* If we're here, we've found a correct patch */ - patch_found = 1; - break; - - } - - /* We couldn't find a valid firmware, let's leave */ - if (!patch_found) - return ret; - - /* The actual image starts after the "STMP" keyword */ - for (data_offset = 0; data_offset < STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET; data_offset++) { - if (!memcmp(fw_entry->data + data_offset, - STIR421X_PATCH_DATA_TAG_STR, - sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))) { - IRDA_DEBUG(2, "%s(), found patch data for STIR421x at offset %d\n", - __FUNCTION__, data_offset); - data_found = 1; - break; - } - } - - /* We couldn't find "STMP" from the header */ - if (!data_found) - return -EINVAL; - - /* Let's upload the patch to the target */ - ret = stir421x_upload_patch(self, - &fw_entry->data[data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)], - fw_entry->size - (data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))); - - release_firmware(fw_entry); - - return ret; - + unsigned int i; + int ret; + char stir421x_fw_name[11]; + const struct firmware *fw; + unsigned char *fw_version_ptr; /* pointer to version string */ + unsigned long fw_version = 0; + + /* + * Known firmware patch file names for STIR421x dongles + * are "42101001.sb" or "42101002.sb" + */ + sprintf(stir421x_fw_name, "4210%4X.sb", + self->usbdev->descriptor.bcdDevice); + ret = request_firmware(&fw, stir421x_fw_name, &self->usbdev->dev); + if (ret < 0) + return ret; + + /* We get a patch from userspace */ + IRDA_MESSAGE("%s(): Received firmware %s (%u bytes)\n", + __FUNCTION__, stir421x_fw_name, fw->size); + + ret = -EINVAL; + + /* Get the bcd product version */ + if (!memcmp(fw->data, STIR421X_PATCH_PRODUCT_VER, + sizeof(STIR421X_PATCH_PRODUCT_VER) - 1)) { + fw_version_ptr = fw->data + + sizeof(STIR421X_PATCH_PRODUCT_VER) - 1; + + /* Let's check if the product version is dotted */ + if (fw_version_ptr[3] == '.' && + fw_version_ptr[7] == '.') { + unsigned long major, minor, build; + major = simple_strtoul(fw_version_ptr, NULL, 10); + minor = simple_strtoul(fw_version_ptr + 4, NULL, 10); + build = simple_strtoul(fw_version_ptr + 8, NULL, 10); + + fw_version = (major << 12) + + (minor << 8) + + ((build / 10) << 4) + + (build % 10); + + IRDA_DEBUG(3, "%s(): Firmware Product version %ld\n", + __FUNCTION__, fw_version); + } + } + + if (self->usbdev->descriptor.bcdDevice == fw_version) { + /* + * If we're here, we've found a correct patch + * The actual image starts after the "STMP" keyword + * so forward to the firmware header tag + */ + for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG) + && (i < fw->size); i++) ; + /* here we check for the out of buffer case */ + if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) + && (i < STIR421X_PATCH_CODE_OFFSET)) { + if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG, + sizeof(STIR421X_PATCH_STMP_TAG) - 1)) { + + /* We can upload the patch to the target */ + i += sizeof(STIR421X_PATCH_STMP_TAG); + ret = stir421x_fw_upload(self, &fw->data[i], + fw->size - i); + } + } + } + + release_firmware(fw); + + return ret; } @@ -1702,12 +1657,12 @@ static int irda_usb_probe(struct usb_interface *intf, init_timer(&self->rx_defer_timer); self->capability = id->driver_info; - self->needspatch = ((self->capability & IUC_STIR_4210) != 0) ; + self->needspatch = ((self->capability & IUC_STIR421X) != 0); /* Create all of the needed urbs */ - if (self->capability & IUC_STIR_4210) { + if (self->capability & IUC_STIR421X) { self->max_rx_urb = IU_SIGMATEL_MAX_RX_URBS; - self->header_length = USB_IRDA_SIGMATEL_HEADER; + self->header_length = USB_IRDA_STIR421X_HEADER; } else { self->max_rx_urb = IU_MAX_RX_URBS; self->header_length = USB_IRDA_HEADER; @@ -1813,8 +1768,8 @@ static int irda_usb_probe(struct usb_interface *intf, /* Now we fetch and upload the firmware patch */ ret = stir421x_patch_device(self); self->needspatch = (ret < 0); - if (ret < 0) { - printk("patch_device failed\n"); + if (self->needspatch) { + IRDA_ERROR("STIR421X: Couldn't upload patch\n"); goto err_out_5; } diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index d833db52ceb..6b2271f18e7 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h @@ -34,9 +34,6 @@ #include <net/irda/irda.h> #include <net/irda/irda_device.h> /* struct irlap_cb */ -#define PATCH_FILE_SIZE_MAX 65536 -#define PATCH_FILE_SIZE_MIN 80 - #define RX_COPY_THRESHOLD 200 #define IRDA_USB_MAX_MTU 2051 #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ @@ -107,14 +104,15 @@ #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ -#define IUC_STIR_4210 0x80 /* SigmaTel 4210/4220/4116 VFIR */ +#define IUC_STIR421X 0x80 /* SigmaTel 4210/4220/4116 VFIR */ /* USB class definitions */ #define USB_IRDA_HEADER 0x01 #define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ #define USB_DT_IRDA 0x21 -#define USB_IRDA_SIGMATEL_HEADER 0x03 -#define IU_SIGMATEL_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + USB_IRDA_SIGMATEL_HEADER) +#define USB_IRDA_STIR421X_HEADER 0x03 +#define IU_SIGMATEL_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + \ + USB_IRDA_STIR421X_HEADER) struct irda_class_desc { __u8 bLength; diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c new file mode 100644 index 00000000000..754297fc8f2 --- /dev/null +++ b/drivers/net/irda/mcs7780.c @@ -0,0 +1,1009 @@ +/***************************************************************************** +* +* Filename: mcs7780.c +* Version: 0.4-alpha +* Description: Irda MosChip USB Dongle Driver +* Authors: Lukasz Stelmach <stlman@poczta.fm> +* Brian Pugh <bpugh@cs.pdx.edu> +* Judy Fischbach <jfisch@cs.pdx.edu> +* +* Based on stir4200 driver, but some things done differently. +* Based on earlier driver by Paul Stewart <stewart@parc.com> +* +* Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at> +* Copyright (C) 2001, Dag Brattli <dag@brattli.net> +* Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> +* Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org> +* Copyright (C) 2005, Lukasz Stelmach <stlman@poczta.fm> +* Copyright (C) 2005, Brian Pugh <bpugh@cs.pdx.edu> +* Copyright (C) 2005, Judy Fischbach <jfisch@cs.pdx.edu> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +/* + * MCS7780 is a simple USB to IrDA bridge by MosChip. It is neither + * compatibile with irda-usb nor with stir4200. Although it is quite + * similar to the later as far as general idea of operation is concerned. + * That is it requires the software to do all the framing job at SIR speeds. + * The hardware does take care of the framing at MIR and FIR speeds. + * It supports all speeds from 2400 through 4Mbps + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/kref.h> +#include <linux/usb.h> +#include <linux/device.h> +#include <linux/crc32.h> + +#include <asm/unaligned.h> +#include <asm/byteorder.h> +#include <asm/uaccess.h> + +#include <net/irda/irda.h> +#include <net/irda/wrapper.h> +#include <net/irda/crc.h> + +#include "mcs7780.h" + +#define MCS_VENDOR_ID 0x9710 +#define MCS_PRODUCT_ID 0x7780 + +static struct usb_device_id mcs_table[] = { + /* MosChip Corp., MCS7780 FIR-USB Adapter */ + {USB_DEVICE(MCS_VENDOR_ID, MCS_PRODUCT_ID)}, + {}, +}; + +MODULE_AUTHOR("Brian Pugh <bpugh@cs.pdx.edu>"); +MODULE_DESCRIPTION("IrDA-USB Dongle Driver for MosChip MCS7780"); +MODULE_VERSION("0.3alpha"); +MODULE_LICENSE("GPL"); + +MODULE_DEVICE_TABLE(usb, mcs_table); + +static int qos_mtt_bits = 0x07 /* > 1ms */ ; +module_param(qos_mtt_bits, int, 0); +MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); + +static int receive_mode = 0x1; +module_param(receive_mode, int, 0); +MODULE_PARM_DESC(receive_mode, + "Receive mode of the device (1:fast, 0:slow, default:1)"); + +static int sir_tweak = 1; +module_param(sir_tweak, int, 0444); +MODULE_PARM_DESC(sir_tweak, + "Default pulse width (1:1.6us, 0:3/16 bit, default:1)."); + +static int transceiver_type = MCS_TSC_VISHAY; +module_param(transceiver_type, int, 0444); +MODULE_PARM_DESC(transceiver_type, "IR transceiver type, see mcs7780.h."); + +struct usb_driver mcs_driver = { + .name = "mcs7780", + .probe = mcs_probe, + .disconnect = mcs_disconnect, + .id_table = mcs_table, +}; + +/* speed flag selection by direct addressing. +addr = (speed >> 8) & 0x0f + +0x1 57600 0x2 115200 0x4 1152000 0x5 9600 +0x6 38400 0x9 2400 0xa 576000 0xb 19200 + +4Mbps (or 2400) must be checked separately. Since it also has +to be programmed in a different manner that is not a big problem. +*/ +static __u16 mcs_speed_set[16] = { 0, + MCS_SPEED_57600, + MCS_SPEED_115200, + 0, + MCS_SPEED_1152000, + MCS_SPEED_9600, + MCS_SPEED_38400, + 0, 0, + MCS_SPEED_2400, + MCS_SPEED_576000, + MCS_SPEED_19200, + 0, 0, 0, +}; + +/* Set given 16 bit register with a 16 bit value. Send control message + * to set dongle register. */ +static int mcs_set_reg(struct mcs_cb *mcs, __u16 reg, __u16 val) +{ + struct usb_device *dev = mcs->usbdev; + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, + MCS_WR_RTYPE, val, reg, NULL, 0, + msecs_to_jiffies(MCS_CTRL_TIMEOUT)); +} + +/* Get 16 bit register value. Send contol message to read dongle register. */ +static int mcs_get_reg(struct mcs_cb *mcs, __u16 reg, __u16 * val) +{ + struct usb_device *dev = mcs->usbdev; + int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, + MCS_RD_RTYPE, 0, reg, val, 2, + msecs_to_jiffies(MCS_CTRL_TIMEOUT)); + + return ret; +} + +/* Setup a communication between mcs7780 and TFDU chips. It is described + * in more detail in the data sheet. The setup sequence puts the the + * vishay tranceiver into high speed mode. It will also receive SIR speed + * packets but at reduced sensitivity. + */ + +/* 0: OK 1:ERROR */ +static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs) +{ + int ret = 0; + __u16 rval; + + /* mcs_get_reg should read exactly two bytes from the dongle */ + ret = mcs_get_reg(mcs, MCS_XCVR_REG, &rval); + if (unlikely(ret != 2)) { + ret = -EIO; + goto error; + } + + /* The MCS_XCVR_CONF bit puts the transceiver into configuration + * mode. The MCS_MODE0 bit must start out high (1) and then + * transition to low and the MCS_STFIR and MCS_MODE1 bits must + * be low. + */ + rval |= (MCS_MODE0 | MCS_XCVR_CONF); + rval &= ~MCS_STFIR; + rval &= ~MCS_MODE1; + ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval); + if (unlikely(ret)) + goto error; + + rval &= ~MCS_MODE0; + ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval); + if (unlikely(ret)) + goto error; + + rval &= ~MCS_XCVR_CONF; + ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval); + if (unlikely(ret)) + goto error; + + ret = 0; + error: + return ret; +} + +/* Setup a communication between mcs7780 and agilent chip. */ +static inline int mcs_setup_transceiver_agilent(struct mcs_cb *mcs) +{ + IRDA_WARNING("This transceiver type is not supported yet."); + return 1; +} + +/* Setup a communication between mcs7780 and sharp chip. */ +static inline int mcs_setup_transceiver_sharp(struct mcs_cb *mcs) +{ + IRDA_WARNING("This transceiver type is not supported yet."); + return 1; +} + +/* Common setup for all transceivers */ +static inline int mcs_setup_transceiver(struct mcs_cb *mcs) +{ + int ret = 0; + __u16 rval; + char *msg; + + msg = "Basic transceiver setup error."; + + /* read value of MODE Register, set the DRIVER and RESET bits + * and write value back out to MODE Register + */ + ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval); + if(unlikely(ret != 2)) + goto error; + rval |= MCS_DRIVER; /* put the mcs7780 into configuration mode. */ + ret = mcs_set_reg(mcs, MCS_MODE_REG, rval); + if(unlikely(ret)) + goto error; + + rval = 0; /* set min pulse width to 0 initially. */ + ret = mcs_set_reg(mcs, MCS_MINRXPW_REG, rval); + if(unlikely(ret)) + goto error; + + ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval); + if(unlikely(ret != 2)) + goto error; + + rval &= ~MCS_FIR; /* turn off fir mode. */ + if(mcs->sir_tweak) + rval |= MCS_SIR16US; /* 1.6us pulse width */ + else + rval &= ~MCS_SIR16US; /* 3/16 bit time pulse width */ + + /* make sure ask mode and back to back packets are off. */ + rval &= ~(MCS_BBTG | MCS_ASK); + + rval &= ~MCS_SPEED_MASK; + rval |= MCS_SPEED_9600; /* make sure initial speed is 9600. */ + mcs->speed = 9600; + mcs->new_speed = 0; /* new_speed is set to 0 */ + rval &= ~MCS_PLLPWDN; /* disable power down. */ + + /* make sure device determines direction and that the auto send sip + * pulse are on. + */ + rval |= MCS_DTD | MCS_SIPEN; + + ret = mcs_set_reg(mcs, MCS_MODE_REG, rval); + if(unlikely(ret)) + goto error; + + msg = "transceiver model specific setup error."; + switch (mcs->transceiver_type) { + case MCS_TSC_VISHAY: + ret = mcs_setup_transceiver_vishay(mcs); + break; + + case MCS_TSC_SHARP: + ret = mcs_setup_transceiver_sharp(mcs); + break; + + case MCS_TSC_AGILENT: + ret = mcs_setup_transceiver_agilent(mcs); + break; + + default: + IRDA_WARNING("Unknown transceiver type: %d", + mcs->transceiver_type); + ret = 1; + } + if (unlikely(ret)) + goto error; + + /* If transceiver is not SHARP, then if receive mode set + * on the RXFAST bit in the XCVR Register otherwise unset it + */ + if (mcs->transceiver_type != MCS_TSC_SHARP) { + + ret = mcs_get_reg(mcs, MCS_XCVR_REG, &rval); + if (unlikely(ret != 2)) + goto error; + if (mcs->receive_mode) + rval |= MCS_RXFAST; + else + rval &= ~MCS_RXFAST; + ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval); + if (unlikely(ret)) + goto error; + } + + msg = "transceiver reset."; + + ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval); + if (unlikely(ret != 2)) + goto error; + + /* reset the mcs7780 so all changes take effect. */ + rval &= ~MCS_RESET; + ret = mcs_set_reg(mcs, MCS_MODE_REG, rval); + if (unlikely(ret)) + goto error; + else + return ret; + +error: + IRDA_ERROR("%s", msg); + return ret; +} + +/* Wraps the data in format for SIR */ +static inline int mcs_wrap_sir_skb(struct sk_buff *skb, __u8 * buf) +{ + int wraplen; + + /* 2: full frame length, including "the length" */ + wraplen = async_wrap_skb(skb, buf + 2, 4094); + + wraplen += 2; + buf[0] = wraplen & 0xff; + buf[1] = (wraplen >> 8) & 0xff; + + return wraplen; +} + +/* Wraps the data in format for FIR */ +static unsigned mcs_wrap_fir_skb(const struct sk_buff *skb, __u8 *buf) +{ + unsigned int len = 0; + __u32 fcs = ~(crc32_le(~0, skb->data, skb->len)); + + /* add 2 bytes for length value and 4 bytes for fcs. */ + len = skb->len + 6; + + /* The mcs7780 requires that the first two bytes are the packet + * length in little endian order. Note: the length value includes + * the two bytes for the length value itself. + */ + buf[0] = len & 0xff; + buf[1] = (len >> 8) & 0xff; + /* copy the data into the tx buffer. */ + memcpy(buf+2, skb->data, skb->len); + /* put the fcs in the last four bytes in little endian order. */ + buf[len - 4] = fcs & 0xff; + buf[len - 3] = (fcs >> 8) & 0xff; + buf[len - 2] = (fcs >> 16) & 0xff; + buf[len - 1] = (fcs >> 24) & 0xff; + + return len; +} + +/* Wraps the data in format for MIR */ +static unsigned mcs_wrap_mir_skb(const struct sk_buff *skb, __u8 *buf) +{ + __u16 fcs = 0; + int len = skb->len + 4; + + fcs = ~(irda_calc_crc16(~fcs, skb->data, skb->len)); + /* put the total packet length in first. Note: packet length + * value includes the two bytes that hold the packet length + * itself. + */ + buf[0] = len & 0xff; + buf[1] = (len >> 8) & 0xff; + /* copy the data */ + memcpy(buf+2, skb->data, skb->len); + /* put the fcs in last two bytes in little endian order. */ + buf[len - 2] = fcs & 0xff; + buf[len - 1] = (fcs >> 8) & 0xff; + + return len; +} + +/* Unwrap received packets at MIR speed. A 16 bit crc_ccitt checksum is + * used for the fcs. When performed over the entire packet the result + * should be GOOD_FCS = 0xf0b8. Hands the unwrapped data off to the IrDA + * layer via a sk_buff. + */ +static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) +{ + __u16 fcs; + int new_len; + struct sk_buff *skb; + + /* Assume that the frames are going to fill a single packet + * rather than span multiple packets. + */ + + new_len = len - 2; + if(unlikely(new_len <= 0)) { + IRDA_ERROR("%s short frame length %d\n", + mcs->netdev->name, new_len); + ++mcs->stats.rx_errors; + ++mcs->stats.rx_length_errors; + return; + } + fcs = 0; + fcs = irda_calc_crc16(~fcs, buf, len); + + if(fcs != GOOD_FCS) { + IRDA_ERROR("crc error calc 0x%x len %d\n", + fcs, new_len); + mcs->stats.rx_errors++; + mcs->stats.rx_crc_errors++; + return; + } + + skb = dev_alloc_skb(new_len + 1); + if(unlikely(!skb)) { + ++mcs->stats.rx_dropped; + return; + } + + skb_reserve(skb, 1); + memcpy(skb->data, buf, new_len); + skb_put(skb, new_len); + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + skb->dev = mcs->netdev; + + netif_rx(skb); + + mcs->stats.rx_packets++; + mcs->stats.rx_bytes += new_len; + + return; +} + +/* Unwrap received packets at FIR speed. A 32 bit crc_ccitt checksum is + * used for the fcs. Hands the unwrapped data off to the IrDA + * layer via a sk_buff. + */ +static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len) +{ + __u32 fcs; + int new_len; + struct sk_buff *skb; + + /* Assume that the frames are going to fill a single packet + * rather than span multiple packets. This is most likely a false + * assumption. + */ + + new_len = len - 4; + if(unlikely(new_len <= 0)) { + IRDA_ERROR("%s short frame length %d\n", + mcs->netdev->name, new_len); + ++mcs->stats.rx_errors; + ++mcs->stats.rx_length_errors; + return; + } + + fcs = ~(crc32_le(~0, buf, new_len)); + if(fcs != le32_to_cpu(get_unaligned((u32 *)(buf+new_len)))) { + IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len); + mcs->stats.rx_errors++; + mcs->stats.rx_crc_errors++; + return; + } + + skb = dev_alloc_skb(new_len + 1); + if(unlikely(!skb)) { + ++mcs->stats.rx_dropped; + return; + } + + skb_reserve(skb, 1); + memcpy(skb->data, buf, new_len); + skb_put(skb, new_len); + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + skb->dev = mcs->netdev; + + netif_rx(skb); + + mcs->stats.rx_packets++; + mcs->stats.rx_bytes += new_len; + + return; +} + + +/* Allocates urbs for both receive and transmit. + * If alloc fails return error code 0 (fail) otherwise + * return error code 1 (success). + */ +static inline int mcs_setup_urbs(struct mcs_cb *mcs) +{ + mcs->rx_urb = NULL; + + mcs->tx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!mcs->tx_urb) + return 0; + + mcs->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!mcs->rx_urb) + return 0; + + return 1; +} + +/* Sets up state to be initially outside frame, gets receive urb, + * sets status to successful and then submits the urb to start + * receiving the data. + */ +static inline int mcs_receive_start(struct mcs_cb *mcs) +{ + mcs->rx_buff.in_frame = FALSE; + mcs->rx_buff.state = OUTSIDE_FRAME; + + usb_fill_bulk_urb(mcs->rx_urb, mcs->usbdev, + usb_rcvbulkpipe(mcs->usbdev, mcs->ep_in), + mcs->in_buf, 4096, mcs_receive_irq, mcs); + + mcs->rx_urb->status = 0; + return usb_submit_urb(mcs->rx_urb, GFP_KERNEL); +} + +/* Finds the in and out endpoints for the mcs control block */ +static inline int mcs_find_endpoints(struct mcs_cb *mcs, + struct usb_host_endpoint *ep, int epnum) +{ + int i; + int ret = 0; + + /* If no place to store the endpoints just return */ + if (!ep) + return ret; + + /* cycle through all endpoints, find the first two that are DIR_IN */ + for (i = 0; i < epnum; i++) { + if (ep[i].desc.bEndpointAddress & USB_DIR_IN) + mcs->ep_in = ep[i].desc.bEndpointAddress; + else + mcs->ep_out = ep[i].desc.bEndpointAddress; + + /* MosChip says that the chip has only two bulk + * endpoints. Find one for each direction and move on. + */ + if ((mcs->ep_in != 0) && (mcs->ep_out != 0)) { + ret = 1; + break; + } + } + + return ret; +} + +static void mcs_speed_work(void *arg) +{ + struct mcs_cb *mcs = arg; + struct net_device *netdev = mcs->netdev; + + mcs_speed_change(mcs); + netif_wake_queue(netdev); +} + +/* Function to change the speed of the mcs7780. Fully supports SIR, + * MIR, and FIR speeds. + */ +static int mcs_speed_change(struct mcs_cb *mcs) +{ + int ret = 0; + int rst = 0; + int cnt = 0; + __u16 nspeed; + __u16 rval; + + nspeed = mcs_speed_set[(mcs->new_speed >> 8) & 0x0f]; + + do { + mcs_get_reg(mcs, MCS_RESV_REG, &rval); + } while(cnt++ < 100 && (rval & MCS_IRINTX)); + + if(cnt >= 100) { + IRDA_ERROR("unable to change speed"); + ret = -EIO; + goto error; + } + + mcs_get_reg(mcs, MCS_MODE_REG, &rval); + + /* MINRXPW values recomended by MosChip */ + if (mcs->new_speed <= 115200) { + rval &= ~MCS_FIR; + + if ((rst = (mcs->speed > 115200))) + mcs_set_reg(mcs, MCS_MINRXPW_REG, 0); + + } else if (mcs->new_speed <= 1152000) { + rval &= ~MCS_FIR; + + if ((rst = !(mcs->speed == 576000 || mcs->speed == 1152000))) + mcs_set_reg(mcs, MCS_MINRXPW_REG, 5); + + } else { + rval |= MCS_FIR; + + if ((rst = (mcs->speed != 4000000))) + mcs_set_reg(mcs, MCS_MINRXPW_REG, 5); + + } + + rval &= ~MCS_SPEED_MASK; + rval |= nspeed; + + ret = mcs_set_reg(mcs, MCS_MODE_REG, rval); + if (unlikely(ret)) + goto error; + + if (rst) + switch (mcs->transceiver_type) { + case MCS_TSC_VISHAY: + ret = mcs_setup_transceiver_vishay(mcs); + break; + + case MCS_TSC_SHARP: + ret = mcs_setup_transceiver_sharp(mcs); + break; + + case MCS_TSC_AGILENT: + ret = mcs_setup_transceiver_agilent(mcs); + break; + + default: + ret = 1; + IRDA_WARNING("Unknown transceiver type: %d", + mcs->transceiver_type); + } + if (unlikely(ret)) + goto error; + + mcs_get_reg(mcs, MCS_MODE_REG, &rval); + rval &= ~MCS_RESET; + ret = mcs_set_reg(mcs, MCS_MODE_REG, rval); + + mcs->speed = mcs->new_speed; + error: + mcs->new_speed = 0; + return ret; +} + +/* Ioctl calls not supported at this time. Can be an area of future work. */ +static int mcs_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +{ + /* struct if_irda_req *irq = (struct if_irda_req *)rq; */ + /* struct mcs_cb *mcs = netdev_priv(netdev); */ + int ret = 0; + + switch (cmd) { + default: + ret = -EOPNOTSUPP; + } + + return ret; +} + +/* Network device is taken down, done by "ifconfig irda0 down" */ +static int mcs_net_close(struct net_device *netdev) +{ + int ret = 0; + struct mcs_cb *mcs = netdev_priv(netdev); + + /* Stop transmit processing */ + netif_stop_queue(netdev); + + /* kill and free the receive and transmit URBs */ + usb_kill_urb(mcs->rx_urb); + usb_free_urb(mcs->rx_urb); + usb_kill_urb(mcs->tx_urb); + usb_free_urb(mcs->tx_urb); + + /* Stop and remove instance of IrLAP */ + if (mcs->irlap) + irlap_close(mcs->irlap); + + mcs->irlap = NULL; + return ret; +} + +/* Network device is taken up, done by "ifconfig irda0 up" */ +static int mcs_net_open(struct net_device *netdev) +{ + struct mcs_cb *mcs = netdev_priv(netdev); + char hwname[16]; + int ret = 0; + + ret = usb_clear_halt(mcs->usbdev, + usb_sndbulkpipe(mcs->usbdev, mcs->ep_in)); + if (ret) + goto error1; + ret = usb_clear_halt(mcs->usbdev, + usb_rcvbulkpipe(mcs->usbdev, mcs->ep_out)); + if (ret) + goto error1; + + ret = mcs_setup_transceiver(mcs); + if (ret) + goto error1; + + ret = -ENOMEM; + + /* Initialize for SIR/FIR to copy data directly into skb. */ + mcs->receiving = 0; + mcs->rx_buff.truesize = IRDA_SKB_MAX_MTU; + mcs->rx_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); + if (!mcs->rx_buff.skb) + goto error1; + + skb_reserve(mcs->rx_buff.skb, 1); + mcs->rx_buff.head = mcs->rx_buff.skb->data; + do_gettimeofday(&mcs->rx_time); + + /* + * Now that everything should be initialized properly, + * Open new IrLAP layer instance to take care of us... + * Note : will send immediately a speed change... + */ + sprintf(hwname, "usb#%d", mcs->usbdev->devnum); + mcs->irlap = irlap_open(netdev, &mcs->qos, hwname); + if (!mcs->irlap) { + IRDA_ERROR("mcs7780: irlap_open failed"); + goto error2; + } + + if (!mcs_setup_urbs(mcs)) + goto error3; + + ret = mcs_receive_start(mcs); + if (ret) + goto error3; + + netif_start_queue(netdev); + return 0; + + error3: + irlap_close(mcs->irlap); + error2: + kfree_skb(mcs->rx_buff.skb); + error1: + return ret; +} + + +/* Get device stats for /proc/net/dev and ifconfig */ +static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev) +{ + struct mcs_cb *mcs = netdev_priv(netdev); + return &mcs->stats; +} + +/* Receive callback function. */ +static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs) +{ + __u8 *bytes; + struct mcs_cb *mcs = urb->context; + int i; + int ret; + + if (!netif_running(mcs->netdev)) + return; + + if (urb->status) + return; + + if (urb->actual_length > 0) { + bytes = urb->transfer_buffer; + + /* MCS returns frames without BOF and EOF + * I assume it returns whole frames. + */ + /* SIR speed */ + if(mcs->speed < 576000) { + async_unwrap_char(mcs->netdev, &mcs->stats, + &mcs->rx_buff, 0xc0); + + for (i = 0; i < urb->actual_length; i++) + async_unwrap_char(mcs->netdev, &mcs->stats, + &mcs->rx_buff, bytes[i]); + + async_unwrap_char(mcs->netdev, &mcs->stats, + &mcs->rx_buff, 0xc1); + } + /* MIR speed */ + else if(mcs->speed == 576000 || mcs->speed == 1152000) { + mcs_unwrap_mir(mcs, urb->transfer_buffer, + urb->actual_length); + } + /* FIR speed */ + else { + mcs_unwrap_fir(mcs, urb->transfer_buffer, + urb->actual_length); + } + mcs->netdev->last_rx = jiffies; + do_gettimeofday(&mcs->rx_time); + } + + ret = usb_submit_urb(urb, GFP_ATOMIC); +} + +/* Transmit callback funtion. */ +static void mcs_send_irq(struct urb *urb, struct pt_regs *regs) +{ + struct mcs_cb *mcs = urb->context; + struct net_device *ndev = mcs->netdev; + + if (unlikely(mcs->new_speed)) + schedule_work(&mcs->work); + else + netif_wake_queue(ndev); +} + +/* Transmit callback funtion. */ +static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + unsigned long flags; + struct mcs_cb *mcs; + int wraplen; + int ret = 0; + + + if (skb == NULL || ndev == NULL) + return -EINVAL; + + netif_stop_queue(ndev); + mcs = netdev_priv(ndev); + + spin_lock_irqsave(&mcs->lock, flags); + + mcs->new_speed = irda_get_next_speed(skb); + if (likely(mcs->new_speed == mcs->speed)) + mcs->new_speed = 0; + + /* SIR speed */ + if(mcs->speed < 576000) { + wraplen = mcs_wrap_sir_skb(skb, mcs->out_buf); + } + /* MIR speed */ + else if(mcs->speed == 576000 || mcs->speed == 1152000) { + wraplen = mcs_wrap_mir_skb(skb, mcs->out_buf); + } + /* FIR speed */ + else { + wraplen = mcs_wrap_fir_skb(skb, mcs->out_buf); + } + usb_fill_bulk_urb(mcs->tx_urb, mcs->usbdev, + usb_sndbulkpipe(mcs->usbdev, mcs->ep_out), + mcs->out_buf, wraplen, mcs_send_irq, mcs); + + if ((ret = usb_submit_urb(mcs->tx_urb, GFP_ATOMIC))) { + IRDA_ERROR("failed tx_urb: %d", ret); + switch (ret) { + case -ENODEV: + case -EPIPE: + break; + default: + mcs->stats.tx_errors++; + netif_start_queue(ndev); + } + } else { + mcs->stats.tx_packets++; + mcs->stats.tx_bytes += skb->len; + } + + dev_kfree_skb(skb); + spin_unlock_irqrestore(&mcs->lock, flags); + return ret; +} + +/* + * This function is called by the USB subsystem for each new device in the + * system. Need to verify the device and if it is, then start handling it. + */ +static int mcs_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct net_device *ndev = NULL; + struct mcs_cb *mcs; + int ret = -ENOMEM; + + ndev = alloc_irdadev(sizeof(*mcs)); + if (!ndev) + goto error1; + + IRDA_DEBUG(1, "MCS7780 USB-IrDA bridge found at %d.", udev->devnum); + + /* what is it realy for? */ + SET_MODULE_OWNER(ndev); + SET_NETDEV_DEV(ndev, &intf->dev); + + ret = usb_reset_configuration(udev); + if (ret != 0) { + IRDA_ERROR("mcs7780: usb reset configuration failed"); + goto error2; + } + + mcs = netdev_priv(ndev); + mcs->usbdev = udev; + mcs->netdev = ndev; + spin_lock_init(&mcs->lock); + + /* Initialize QoS for this device */ + irda_init_max_qos_capabilies(&mcs->qos); + + /* That's the Rx capability. */ + mcs->qos.baud_rate.bits &= + IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200 + | IR_576000 | IR_1152000 | (IR_4000000 << 8); + + + mcs->qos.min_turn_time.bits &= qos_mtt_bits; + irda_qos_bits_to_value(&mcs->qos); + + /* Speed change work initialisation*/ + INIT_WORK(&mcs->work, mcs_speed_work, mcs); + + /* Override the network functions we need to use */ + ndev->hard_start_xmit = mcs_hard_xmit; + ndev->open = mcs_net_open; + ndev->stop = mcs_net_close; + ndev->get_stats = mcs_net_get_stats; + ndev->do_ioctl = mcs_net_ioctl; + + if (!intf->cur_altsetting) + goto error2; + + ret = mcs_find_endpoints(mcs, intf->cur_altsetting->endpoint, + intf->cur_altsetting->desc.bNumEndpoints); + if (!ret) { + ret = -ENODEV; + goto error2; + } + + ret = register_netdev(ndev); + if (ret != 0) + goto error2; + + IRDA_DEBUG(1, "IrDA: Registered MosChip MCS7780 device as %s", + ndev->name); + + mcs->transceiver_type = transceiver_type; + mcs->sir_tweak = sir_tweak; + mcs->receive_mode = receive_mode; + + usb_set_intfdata(intf, mcs); + return 0; + + error2: + free_netdev(ndev); + + error1: + return ret; +} + +/* The current device is removed, the USB layer tells us to shut down. */ +static void mcs_disconnect(struct usb_interface *intf) +{ + struct mcs_cb *mcs = usb_get_intfdata(intf); + + if (!mcs) + return; + + flush_scheduled_work(); + + unregister_netdev(mcs->netdev); + free_netdev(mcs->netdev); + + usb_set_intfdata(intf, NULL); + IRDA_DEBUG(0, "MCS7780 now disconnected."); +} + +/* Module insertion */ +static int __init mcs_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + result = usb_register(&mcs_driver); + if (result) + IRDA_ERROR("usb_register failed. Error number %d", result); + + return result; +} +module_init(mcs_init); + +/* Module removal */ +static void __exit mcs_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&mcs_driver); +} +module_exit(mcs_exit); + diff --git a/drivers/net/irda/mcs7780.h b/drivers/net/irda/mcs7780.h new file mode 100644 index 00000000000..1a723d725c2 --- /dev/null +++ b/drivers/net/irda/mcs7780.h @@ -0,0 +1,167 @@ +/***************************************************************************** +* +* Filename: mcs7780.h +* Version: 0.2-alpha +* Description: Irda MosChip USB Dongle +* Status: Experimental +* Authors: Lukasz Stelmach <stlman@poczta.fm> +* Brian Pugh <bpugh@cs.pdx.edu> +* +* Copyright (C) 2005, Lukasz Stelmach <stlman@poczta.fm> +* Copyright (C) 2005, Brian Pugh <bpugh@cs.pdx.edu> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ +#ifndef _MCS7780_H +#define _MCS7780_H + +#define MCS_MODE_SIR 0 +#define MCS_MODE_MIR 1 +#define MCS_MODE_FIR 2 + +#define MCS_CTRL_TIMEOUT 500 +#define MCS_XMIT_TIMEOUT 500 +/* Possible transceiver types */ +#define MCS_TSC_VISHAY 0 /* Vishay TFD, default choice */ +#define MCS_TSC_AGILENT 1 /* Agilent 3602/3600 */ +#define MCS_TSC_SHARP 2 /* Sharp GP2W1000YP */ + +/* Requests */ +#define MCS_RD_RTYPE 0xC0 +#define MCS_WR_RTYPE 0x40 +#define MCS_RDREQ 0x0F +#define MCS_WRREQ 0x0E + +/* Register 0x00 */ +#define MCS_MODE_REG 0 +#define MCS_FIR ((__u16)0x0001) +#define MCS_SIR16US ((__u16)0x0002) +#define MCS_BBTG ((__u16)0x0004) +#define MCS_ASK ((__u16)0x0008) +#define MCS_PARITY ((__u16)0x0010) + +/* SIR/MIR speed constants */ +#define MCS_SPEED_SHIFT 5 +#define MCS_SPEED_MASK ((__u16)0x00E0) +#define MCS_SPEED(x) ((x & MCS_SPEED_MASK) >> MCS_SPEED_SHIFT) +#define MCS_SPEED_2400 ((0 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) +#define MCS_SPEED_9600 ((1 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) +#define MCS_SPEED_19200 ((2 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) +#define MCS_SPEED_38400 ((3 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) +#define MCS_SPEED_57600 ((4 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) +#define MCS_SPEED_115200 ((5 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) +#define MCS_SPEED_576000 ((6 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) +#define MCS_SPEED_1152000 ((7 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK) + +#define MCS_PLLPWDN ((__u16)0x0100) +#define MCS_DRIVER ((__u16)0x0200) +#define MCS_DTD ((__u16)0x0400) +#define MCS_DIR ((__u16)0x0800) +#define MCS_SIPEN ((__u16)0x1000) +#define MCS_SENDSIP ((__u16)0x2000) +#define MCS_CHGDIR ((__u16)0x4000) +#define MCS_RESET ((__u16)0x8000) + +/* Register 0x02 */ +#define MCS_XCVR_REG 2 +#define MCS_MODE0 ((__u16)0x0001) +#define MCS_STFIR ((__u16)0x0002) +#define MCS_XCVR_CONF ((__u16)0x0004) +#define MCS_RXFAST ((__u16)0x0008) +/* TXCUR [6:4] */ +#define MCS_TXCUR_SHIFT 4 +#define MCS_TXCUR_MASK ((__u16)0x0070) +#define MCS_TXCUR(x) ((x & MCS_TXCUR_MASK) >> MCS_TXCUR_SHIFT) +#define MCS_SETTXCUR(x,y) \ + ((x & ~MCS_TXCUR_MASK) | (y << MCS_TXCUR_SHIFT) & MCS_TXCUR_MASK) + +#define MCS_MODE1 ((__u16)0x0080) +#define MCS_SMODE0 ((__u16)0x0100) +#define MCS_SMODE1 ((__u16)0x0200) +#define MCS_INVTX ((__u16)0x0400) +#define MCS_INVRX ((__u16)0x0800) + +#define MCS_MINRXPW_REG 4 + +#define MCS_RESV_REG 7 +#define MCS_IRINTX ((__u16)0x0001) +#define MCS_IRINRX ((__u16)0x0002) + +struct mcs_cb { + struct usb_device *usbdev; /* init: probe_irda */ + struct net_device *netdev; /* network layer */ + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct net_device_stats stats; /* network statistics */ + struct qos_info qos; + unsigned int speed; /* Current speed */ + unsigned int new_speed; /* new speed */ + + struct work_struct work; /* Change speed work */ + + struct sk_buff *tx_pending; + char in_buf[4096]; /* transmit/receive buffer */ + char out_buf[4096]; /* transmit/receive buffer */ + __u8 *fifo_status; + + iobuff_t rx_buff; /* receive unwrap state machine */ + struct timeval rx_time; + spinlock_t lock; + int receiving; + + __u8 ep_in; + __u8 ep_out; + + struct urb *rx_urb; + struct urb *tx_urb; + + int transceiver_type; + int sir_tweak; + int receive_mode; +}; + +static int mcs_set_reg(struct mcs_cb *mcs, __u16 reg, __u16 val); +static int mcs_get_reg(struct mcs_cb *mcs, __u16 reg, __u16 * val); + +static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs); +static inline int mcs_setup_transceiver_agilent(struct mcs_cb *mcs); +static inline int mcs_setup_transceiver_sharp(struct mcs_cb *mcs); +static inline int mcs_setup_transceiver(struct mcs_cb *mcs); +static inline int mcs_wrap_sir_skb(struct sk_buff *skb, __u8 * buf); +static unsigned mcs_wrap_fir_skb(const struct sk_buff *skb, __u8 *buf); +static unsigned mcs_wrap_mir_skb(const struct sk_buff *skb, __u8 *buf); +static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len); +static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len); +static inline int mcs_setup_urbs(struct mcs_cb *mcs); +static inline int mcs_receive_start(struct mcs_cb *mcs); +static inline int mcs_find_endpoints(struct mcs_cb *mcs, + struct usb_host_endpoint *ep, int epnum); + +static int mcs_speed_change(struct mcs_cb *mcs); + +static int mcs_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd); +static int mcs_net_close(struct net_device *netdev); +static int mcs_net_open(struct net_device *netdev); +static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev); + +static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs); +static void mcs_send_irq(struct urb *urb, struct pt_regs *regs); +static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *netdev); + +static int mcs_probe(struct usb_interface *intf, + const struct usb_device_id *id); +static void mcs_disconnect(struct usb_interface *intf); + +#endif /* _MCS7780_H */ diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 31867e4b891..d61b208b52a 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -50,6 +50,7 @@ #include <linux/delay.h> #include <linux/usb.h> #include <linux/crc32.h> +#include <linux/kthread.h> #include <net/irda/irda.h> #include <net/irda/irlap.h> #include <net/irda/irda_device.h> @@ -173,9 +174,7 @@ struct stir_cb { struct qos_info qos; unsigned speed; /* Current speed */ - wait_queue_head_t thr_wait; /* transmit thread wakeup */ - struct completion thr_exited; - pid_t thr_pid; + struct task_struct *thread; /* transmit thread */ struct sk_buff *tx_pending; void *io_buf; /* transmit/receive buffer */ @@ -577,7 +576,7 @@ static int stir_hard_xmit(struct sk_buff *skb, struct net_device *netdev) SKB_LINEAR_ASSERT(skb); skb = xchg(&stir->tx_pending, skb); - wake_up(&stir->thr_wait); + wake_up_process(stir->thread); /* this should never happen unless stop/wakeup problem */ if (unlikely(skb)) { @@ -753,13 +752,7 @@ static int stir_transmit_thread(void *arg) struct net_device *dev = stir->netdev; struct sk_buff *skb; - daemonize("%s", dev->name); - allow_signal(SIGTERM); - - while (netif_running(dev) - && netif_device_present(dev) - && !signal_pending(current)) - { + while (!kthread_should_stop()) { #ifdef CONFIG_PM /* if suspending, then power off and wait */ if (unlikely(freezing(current))) { @@ -813,10 +806,11 @@ static int stir_transmit_thread(void *arg) } /* sleep if nothing to send */ - wait_event_interruptible(stir->thr_wait, stir->tx_pending); - } + set_current_state(TASK_INTERRUPTIBLE); + schedule(); - complete_and_exit (&stir->thr_exited, 0); + } + return 0; } @@ -859,7 +853,7 @@ static void stir_rcv_irq(struct urb *urb, struct pt_regs *regs) warn("%s: usb receive submit error: %d", stir->netdev->name, err); stir->receiving = 0; - wake_up(&stir->thr_wait); + wake_up_process(stir->thread); } } @@ -928,10 +922,10 @@ static int stir_net_open(struct net_device *netdev) } /** Start kernel thread for transmit. */ - stir->thr_pid = kernel_thread(stir_transmit_thread, stir, - CLONE_FS|CLONE_FILES); - if (stir->thr_pid < 0) { - err = stir->thr_pid; + stir->thread = kthread_run(stir_transmit_thread, stir, + "%s", stir->netdev->name); + if (IS_ERR(stir->thread)) { + err = PTR_ERR(stir->thread); err("stir4200: unable to start kernel thread"); goto err_out6; } @@ -968,8 +962,7 @@ static int stir_net_close(struct net_device *netdev) netif_stop_queue(netdev); /* Kill transmit thread */ - kill_proc(stir->thr_pid, SIGTERM, 1); - wait_for_completion(&stir->thr_exited); + kthread_stop(stir->thread); kfree(stir->fifo_status); /* Mop up receive urb's */ @@ -1084,9 +1077,6 @@ static int stir_probe(struct usb_interface *intf, stir->qos.min_turn_time.bits &= qos_mtt_bits; irda_qos_bits_to_value(&stir->qos); - init_completion (&stir->thr_exited); - init_waitqueue_head (&stir->thr_wait); - /* Override the network functions we need to use */ net->hard_start_xmit = stir_hard_xmit; net->open = stir_net_open; diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 97a49e0be76..d70b9e8d6e6 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) || (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) break; udelay(100); - /* must not sleep here - we are called under xmit_lock! */ + /* must not sleep here - called under netif_tx_lock! */ } } diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 411f4d809c4..625ff61c998 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1200,7 +1200,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) } if (has_tiny_unaligned_frags(skb)) { - if ((skb_linearize(skb, GFP_ATOMIC) != 0)) { + if (__skb_linearize(skb)) { stats->tx_dropped++; printk(KERN_DEBUG "%s: failed to linearize tiny " "unaligned fragment\n", dev->name); diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 90627756d6f..2e4ecedba05 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -318,12 +318,12 @@ performance critical codepaths: The rx process only runs in the interrupt handler. Access from outside the interrupt handler is only permitted after disable_irq(). -The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap +The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap is set, then access is permitted under spin_lock_irq(&np->lock). Thus configuration functions that want to access everything must call disable_irq(dev->irq); - spin_lock_bh(dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock_irq(&np->lock); IV. Notes diff --git a/drivers/net/ne.c b/drivers/net/ne.c index b32765215f7..963a11fa9fe 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -829,7 +829,7 @@ that the ne2k probe is the last 8390 based probe to take place (as it is at boot) and so the probe will get confused by any other 8390 cards. ISA device autoprobes on a running machine are not recommended anyway. */ -int init_module(void) +int __init init_module(void) { int this_dev, found = 0; diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index 2aa7b77f84f..eebf5f02b47 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -780,7 +780,7 @@ MODULE_PARM_DESC(bad, "(ignored)"); /* Module code fixed by David Weinehall */ -int init_module(void) +int __init init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index b2073fce821..01cd8ec751e 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1609,8 +1609,6 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) kfree_skb(skb); skb = ns; } - else if (!pskb_may_pull(skb, skb->len)) - goto err; else skb->ip_summed = CHECKSUM_NONE; diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index cac9fdd2e1d..11daed495b9 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2627,6 +2627,50 @@ no_rx: #endif /** + * s2io_netpoll - Rx interrupt service handler for netpoll support + * @dev : pointer to the device structure. + * Description: + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void s2io_netpoll(struct net_device *dev) +{ + nic_t *nic = dev->priv; + mac_info_t *mac_control; + struct config_param *config; + XENA_dev_config_t __iomem *bar0 = nic->bar0; + u64 val64; + int i; + + disable_irq(dev->irq); + + atomic_inc(&nic->isr_cnt); + mac_control = &nic->mac_control; + config = &nic->config; + + val64 = readq(&bar0->rx_traffic_int); + writeq(val64, &bar0->rx_traffic_int); + + for (i = 0; i < config->rx_ring_num; i++) + rx_intr_handler(&mac_control->rings[i]); + + for (i = 0; i < config->rx_ring_num; i++) { + if (fill_rx_buffers(nic, i) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(ERR_DBG, " in Rx Netpoll!!\n"); + break; + } + } + atomic_dec(&nic->isr_cnt); + enable_irq(dev->irq); + return; +} +#endif + +/** * rx_intr_handler - Rx interrupt handler * @nic: device private variable. * Description: @@ -6967,6 +7011,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->weight = 32; #endif +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = s2io_netpoll; +#endif + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 959109609d8..fba1e4d4d83 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -187,12 +187,11 @@ static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) return v; } -static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) +static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) { u16 power_control; u32 reg1; int vaux; - int ret = 0; pr_debug("sky2_set_power_state %d\n", state); sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); @@ -275,12 +274,10 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) break; default: printk(KERN_ERR PFX "Unknown power state %d\n", state); - ret = -1; } sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - return ret; } static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) @@ -2164,6 +2161,13 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, /* If idle then force a fake soft NAPI poll once a second * to work around cases where sharing an edge triggered interrupt. */ +static inline void sky2_idle_start(struct sky2_hw *hw) +{ + if (idle_timeout > 0) + mod_timer(&hw->idle_timer, + jiffies + msecs_to_jiffies(idle_timeout)); +} + static void sky2_idle(unsigned long arg) { struct sky2_hw *hw = (struct sky2_hw *) arg; @@ -2183,6 +2187,9 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); + if (!~status) + goto out; + if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); @@ -2219,7 +2226,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) if (sky2_more_work(hw)) return 1; - +out: netif_rx_complete(dev0); sky2_read32(hw, B0_Y2_SP_LISR); @@ -2248,8 +2255,10 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) static void sky2_netpoll(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); + struct net_device *dev0 = sky2->hw->dev[0]; - sky2_intr(sky2->hw->pdev->irq, sky2->hw, NULL); + if (netif_running(dev) && __netif_rx_schedule_prep(dev0)) + __netif_rx_schedule(dev0); } #endif @@ -3350,9 +3359,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_write32(hw, B0_IMSK, Y2_IS_BASE); setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); - if (idle_timeout > 0) - mod_timer(&hw->idle_timer, - jiffies + msecs_to_jiffies(idle_timeout)); + sky2_idle_start(hw); pci_set_drvdata(pdev, hw); @@ -3425,8 +3432,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) { struct sky2_hw *hw = pci_get_drvdata(pdev); int i; + pci_power_t pstate = pci_choose_state(pdev, state); + + if (!(pstate == PCI_D3hot || pstate == PCI_D3cold)) + return -EINVAL; + + del_timer_sync(&hw->idle_timer); - for (i = 0; i < 2; i++) { + for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; if (dev) { @@ -3435,10 +3448,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) sky2_down(dev); netif_device_detach(dev); + netif_poll_disable(dev); } } - return sky2_set_power_state(hw, pci_choose_state(pdev, state)); + sky2_write32(hw, B0_IMSK, 0); + pci_save_state(pdev); + sky2_set_power_state(hw, pstate); + return 0; } static int sky2_resume(struct pci_dev *pdev) @@ -3448,27 +3465,31 @@ static int sky2_resume(struct pci_dev *pdev) pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); - err = sky2_set_power_state(hw, PCI_D0); - if (err) - goto out; + sky2_set_power_state(hw, PCI_D0); err = sky2_reset(hw); if (err) goto out; - for (i = 0; i < 2; i++) { + sky2_write32(hw, B0_IMSK, Y2_IS_BASE); + + for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; if (dev && netif_running(dev)) { netif_device_attach(dev); + netif_poll_enable(dev); + err = sky2_up(dev); if (err) { printk(KERN_ERR PFX "%s: could not up: %d\n", dev->name, err); dev_close(dev); - break; + goto out; } } } + + sky2_idle_start(hw); out: return err; } diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index 3db30cd0625..5b4e8529d4a 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -553,7 +553,7 @@ MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ -int +int __init init_module(void) { struct net_device *dev; diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c index b3e397d7ca8..ff9bd97746d 100644 --- a/drivers/net/smc-ultra32.c +++ b/drivers/net/smc-ultra32.c @@ -421,7 +421,7 @@ static struct net_device *dev_ultra[MAX_ULTRA32_CARDS]; MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver"); MODULE_LICENSE("GPL"); -int init_module(void) +int __init init_module(void) { int this_dev, found = 0; diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index f86697da04d..6cf16f322ad 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -732,12 +732,9 @@ static int ifport; struct net_device * __init smc_init(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct smc_local)); - static struct devlist *smcdev = smc_devlist; + struct devlist *smcdev = smc_devlist; int err = 0; -#ifndef NO_AUTOPROBE - smcdev = smc_devlist; -#endif if (!dev) return ERR_PTR(-ENODEV); @@ -1607,7 +1604,7 @@ MODULE_PARM_DESC(io, "SMC 99194 I/O base address"); MODULE_PARM_DESC(irq, "SMC 99194 IRQ number"); MODULE_PARM_DESC(ifport, "SMC 99194 interface port (0-default, 1-TP, 2-AUI)"); -int init_module(void) +int __init init_module(void) { if (io == 0) printk(KERN_WARNING diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 61eec46cb11..f13b2a195c7 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -94,11 +94,13 @@ Version LK1.10 (Philippe De Muyter phdm@macqel.be): - Make 'unblock interface after Tx underrun' work + Version LK1.11 (Pedro Alejandro Lopez-Valencia palopezv at gmail.com): + - Add support for IC Plus Corporation IP100A chipset */ #define DRV_NAME "sundance" -#define DRV_VERSION "1.01+LK1.10" -#define DRV_RELDATE "28-Oct-2005" +#define DRV_VERSION "1.01+LK1.11" +#define DRV_RELDATE "14-Jun-2006" /* The user-configurable values. @@ -287,6 +289,7 @@ static struct pci_device_id sundance_pci_tbl[] = { {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3}, {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, + {0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, {0,} }; MODULE_DEVICE_TABLE(pci, sundance_pci_tbl); @@ -305,6 +308,7 @@ static const struct pci_id_info pci_id_tbl[] = { {"D-Link DFE-530TXS FAST Ethernet Adapter"}, {"D-Link DL10050-based FAST Ethernet Adapter"}, {"Sundance Technology Alta"}, + {"IC Plus Corporation IP100A FAST Ethernet Adapter"}, {NULL,}, /* 0 terminated list. */ }; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 49ad60b7265..b2ddd4522a8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.58" -#define DRV_MODULE_RELDATE "May 22, 2006" +#define DRV_MODULE_VERSION "3.60" +#define DRV_MODULE_RELDATE "June 17, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -229,6 +229,8 @@ static struct pci_device_id tg3_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M, @@ -2965,6 +2967,27 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) return err; } +/* This is called whenever we suspect that the system chipset is re- + * ordering the sequence of MMIO to the tx send mailbox. The symptom + * is bogus tx completions. We try to recover by setting the + * TG3_FLAG_MBOX_WRITE_REORDER flag and resetting the chip later + * in the workqueue. + */ +static void tg3_tx_recover(struct tg3 *tp) +{ + BUG_ON((tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) || + tp->write32_tx_mbox == tg3_write_indirect_mbox); + + printk(KERN_WARNING PFX "%s: The system may be re-ordering memory-" + "mapped I/O cycles to the network device, attempting to " + "recover. Please report the problem to the driver maintainer " + "and include system chipset information.\n", tp->dev->name); + + spin_lock(&tp->lock); + tp->tg3_flags |= TG3_FLAG_TX_RECOVERY_PENDING; + spin_unlock(&tp->lock); +} + /* Tigon3 never reports partial packet sends. So we do not * need special logic to handle SKBs that have not had all * of their frags sent yet, like SunGEM does. @@ -2977,9 +3000,13 @@ static void tg3_tx(struct tg3 *tp) while (sw_idx != hw_idx) { struct tx_ring_info *ri = &tp->tx_buffers[sw_idx]; struct sk_buff *skb = ri->skb; - int i; + int i, tx_bug = 0; + + if (unlikely(skb == NULL)) { + tg3_tx_recover(tp); + return; + } - BUG_ON(skb == NULL); pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping), skb_headlen(skb), @@ -2990,10 +3017,9 @@ static void tg3_tx(struct tg3 *tp) sw_idx = NEXT_TX(sw_idx); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - BUG_ON(sw_idx == hw_idx); - ri = &tp->tx_buffers[sw_idx]; - BUG_ON(ri->skb != NULL); + if (unlikely(ri->skb != NULL || sw_idx == hw_idx)) + tx_bug = 1; pci_unmap_page(tp->pdev, pci_unmap_addr(ri, mapping), @@ -3004,6 +3030,11 @@ static void tg3_tx(struct tg3 *tp) } dev_kfree_skb(skb); + + if (unlikely(tx_bug)) { + tg3_tx_recover(tp); + return; + } } tp->tx_cons = sw_idx; @@ -3331,6 +3362,11 @@ static int tg3_poll(struct net_device *netdev, int *budget) /* run TX completion thread */ if (sblk->idx[0].tx_consumer != tp->tx_cons) { tg3_tx(tp); + if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) { + netif_rx_complete(netdev); + schedule_work(&tp->reset_task); + return 0; + } } /* run RX thread, within the bounds set by NAPI. @@ -3391,12 +3427,10 @@ static inline void tg3_full_lock(struct tg3 *tp, int irq_sync) if (irq_sync) tg3_irq_quiesce(tp); spin_lock_bh(&tp->lock); - spin_lock(&tp->tx_lock); } static inline void tg3_full_unlock(struct tg3 *tp) { - spin_unlock(&tp->tx_lock); spin_unlock_bh(&tp->lock); } @@ -3579,6 +3613,13 @@ static void tg3_reset_task(void *_data) restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; + if (tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING) { + tp->write32_tx_mbox = tg3_write32_tx_mbox; + tp->write32_rx_mbox = tg3_write_flush_reg32; + tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER; + tp->tg3_flags &= ~TG3_FLAG_TX_RECOVERY_PENDING; + } + tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); tg3_init_hw(tp, 1); @@ -3718,14 +3759,11 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) len = skb_headlen(skb); - /* No BH disabling for tx_lock here. We are running in BH disabled - * context and TX reclaim runs via tp->poll inside of a software + /* We are running in BH disabled context with netif_tx_lock + * and TX reclaim runs via tp->poll inside of a software * interrupt. Furthermore, IRQ processing runs lockless so we have * no IRQ context deadlocks to worry about either. Rejoice! */ - if (!spin_trylock(&tp->tx_lock)) - return NETDEV_TX_LOCKED; - if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { if (!netif_queue_stopped(dev)) { netif_stop_queue(dev); @@ -3734,7 +3772,6 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " "queue awake!\n", dev->name); } - spin_unlock(&tp->tx_lock); return NETDEV_TX_BUSY; } @@ -3817,15 +3854,16 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); tp->tx_prod = entry; - if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) { + if (unlikely(TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))) { + spin_lock(&tp->tx_lock); netif_stop_queue(dev); if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH) netif_wake_queue(tp->dev); + spin_unlock(&tp->tx_lock); } out_unlock: mmiowb(); - spin_unlock(&tp->tx_lock); dev->trans_start = jiffies; @@ -3844,14 +3882,11 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) len = skb_headlen(skb); - /* No BH disabling for tx_lock here. We are running in BH disabled - * context and TX reclaim runs via tp->poll inside of a software + /* We are running in BH disabled context with netif_tx_lock + * and TX reclaim runs via tp->poll inside of a software * interrupt. Furthermore, IRQ processing runs lockless so we have * no IRQ context deadlocks to worry about either. Rejoice! */ - if (!spin_trylock(&tp->tx_lock)) - return NETDEV_TX_LOCKED; - if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { if (!netif_queue_stopped(dev)) { netif_stop_queue(dev); @@ -3860,7 +3895,6 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " "queue awake!\n", dev->name); } - spin_unlock(&tp->tx_lock); return NETDEV_TX_BUSY; } @@ -3998,15 +4032,16 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); tp->tx_prod = entry; - if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) { + if (unlikely(TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))) { + spin_lock(&tp->tx_lock); netif_stop_queue(dev); if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH) netif_wake_queue(tp->dev); + spin_unlock(&tp->tx_lock); } out_unlock: mmiowb(); - spin_unlock(&tp->tx_lock); dev->trans_start = jiffies; @@ -4485,9 +4520,8 @@ static void tg3_disable_nvram_access(struct tg3 *tp) /* tp->lock is held. */ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind) { - if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) - tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, - NIC_SRAM_FIRMWARE_MBOX_MAGIC1); + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, + NIC_SRAM_FIRMWARE_MBOX_MAGIC1); if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) { switch (kind) { @@ -4568,13 +4602,12 @@ static int tg3_chip_reset(struct tg3 *tp) void (*write_op)(struct tg3 *, u32, u32); int i; - if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { - tg3_nvram_lock(tp); - /* No matching tg3_nvram_unlock() after this because - * chip reset below will undo the nvram lock. - */ - tp->nvram_lock_cnt = 0; - } + tg3_nvram_lock(tp); + + /* No matching tg3_nvram_unlock() after this because + * chip reset below will undo the nvram lock. + */ + tp->nvram_lock_cnt = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || @@ -4727,20 +4760,25 @@ static int tg3_chip_reset(struct tg3 *tp) tw32_f(MAC_MODE, 0); udelay(40); - if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - if (i >= 100000) { - printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " - "firmware will not restart magic=%08x\n", - tp->dev->name, val); - return -ENODEV; - } + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + + /* Chip might not be fitted with firmare. Some Sun onboard + * parts are configured like that. So don't signal the timeout + * of the above loop as an error, but do report the lack of + * running firmware once. + */ + if (i >= 100000 && + !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { + tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; + + printk(KERN_INFO PFX "%s: No firmware running.\n", + tp->dev->name); } if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && @@ -9075,9 +9113,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) { int j; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) - return; - tw32_f(GRC_EEPROM_ADDR, (EEPROM_ADDR_FSM_RESET | (EEPROM_DEFAULT_CLOCK_PERIOD << @@ -9210,11 +9245,6 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) { int ret; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n"); - return -EINVAL; - } - if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) return tg3_nvram_read_using_eeprom(tp, offset, val); @@ -9447,11 +9477,6 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) { int ret; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n"); - return -EINVAL; - } - if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl & ~GRC_LCLCTRL_GPIO_OUTPUT1); @@ -9578,15 +9603,19 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); + /* The memory arbiter has to be enabled in order for SRAM accesses + * to succeed. Normally on powerup the tg3 chip firmware will make + * sure it is enabled, but other entities such as system netboot + * code might disable it. + */ + val = tr32(MEMARB_MODE); + tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); + tp->phy_id = PHY_ID_INVALID; tp->led_ctrl = LED_CTRL_MODE_PHY_1; - /* Do not even try poking around in here on Sun parts. */ - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - /* All SUN chips are built-in LOMs. */ - tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - return; - } + /* Assume an onboard device by default. */ + tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { @@ -9686,6 +9715,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; + else + tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; @@ -9834,16 +9865,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp) int i; u32 magic; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - /* Sun decided not to put the necessary bits in the - * NVRAM of their onboard tg3 parts :( - */ - strcpy(tp->board_part_number, "Sun 570X"); - return; - } - if (tg3_nvram_read_swab(tp, 0x0, &magic)) - return; + goto out_not_found; if (magic == TG3_EEPROM_MAGIC) { for (i = 0; i < 256; i += 4) { @@ -9874,6 +9897,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp) break; msleep(1); } + if (!(tmp16 & 0x8000)) + goto out_not_found; + pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA, &tmp); tmp = cpu_to_le32(tmp); @@ -9965,37 +9991,6 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) } } -#ifdef CONFIG_SPARC64 -static int __devinit tg3_is_sun_570X(struct tg3 *tp) -{ - struct pci_dev *pdev = tp->pdev; - struct pcidev_cookie *pcp = pdev->sysdata; - - if (pcp != NULL) { - int node = pcp->prom_node; - u32 venid; - int err; - - err = prom_getproperty(node, "subsystem-vendor-id", - (char *) &venid, sizeof(venid)); - if (err == 0 || err == -1) - return 0; - if (venid == PCI_VENDOR_ID_SUN) - return 1; - - /* TG3 chips onboard the SunBlade-2500 don't have the - * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they - * are distinguishable from non-Sun variants by being - * named "network" by the firmware. Non-Sun cards will - * show up as being named "ethernet". - */ - if (!strcmp(pcp->prom_name, "network")) - return 1; - } - return 0; -} -#endif - static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -10012,11 +10007,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) u16 pci_cmd; int err; -#ifdef CONFIG_SPARC64 - if (tg3_is_sun_570X(tp)) - tp->tg3_flags2 |= TG3_FLG2_SUN_570X; -#endif - /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary @@ -10312,8 +10302,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->write32 == tg3_write_indirect_reg32 || ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) || - (tp->tg3_flags2 & TG3_FLG2_SUN_570X)) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701))) tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; /* Get eeprom hw config before calling tg3_set_power_state(). @@ -10594,8 +10583,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) #endif mac_offset = 0x7c; - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - !(tp->tg3_flags & TG3_FLG2_SUN_570X)) || + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) mac_offset = 0xcc; @@ -10622,8 +10610,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) } if (!addr_ok) { /* Next, try NVRAM. */ - if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && - !tg3_nvram_read(tp, mac_offset + 0, &hi) && + if (!tg3_nvram_read(tp, mac_offset + 0, &hi) && !tg3_nvram_read(tp, mac_offset + 4, &lo)) { dev->dev_addr[0] = ((hi >> 16) & 0xff); dev->dev_addr[1] = ((hi >> 24) & 0xff); @@ -11291,7 +11278,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - dev->features |= NETIF_F_LLTX; #if TG3_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->vlan_rx_register = tg3_vlan_rx_register; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 0e29b885d44..8209da5dd15 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2074,12 +2074,22 @@ struct tg3 { /* SMP locking strategy: * - * lock: Held during all operations except TX packet - * processing. + * lock: Held during reset, PHY access, timer, and when + * updating tg3_flags and tg3_flags2. * - * tx_lock: Held during tg3_start_xmit and tg3_tx + * tx_lock: Held during tg3_start_xmit and tg3_tx only + * when calling netif_[start|stop]_queue. + * tg3_start_xmit is protected by netif_tx_lock. * * Both of these locks are to be held with BH safety. + * + * Because the IRQ handler, tg3_poll, and tg3_start_xmit + * are running lockless, it is necessary to completely + * quiesce the chip with tg3_netif_stop and tg3_full_lock + * before reconfiguring the device. + * + * indirect_lock: Held when accessing registers indirectly + * with IRQ disabling. */ spinlock_t lock; spinlock_t indirect_lock; @@ -2155,11 +2165,7 @@ struct tg3 { #define TG3_FLAG_ENABLE_ASF 0x00000020 #define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 -#if defined(CONFIG_X86) #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 -#else -#define TG3_FLAG_MBOX_WRITE_REORDER 0 /* disables code too */ -#endif #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 #define TG3_FLAG_WOL_SPEED_100MB 0x00000400 #define TG3_FLAG_WOL_ENABLE 0x00000800 @@ -2172,6 +2178,7 @@ struct tg3 { #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 #define TG3_FLAG_PCI_32BIT 0x00080000 #define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 +#define TG3_FLAG_TX_RECOVERY_PENDING 0x00200000 #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 #define TG3_FLAG_10_100_ONLY 0x01000000 @@ -2184,7 +2191,7 @@ struct tg3 { #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 -#define TG3_FLG2_SUN_570X 0x00000002 +/* 0x00000002 available */ #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 @@ -2216,6 +2223,7 @@ struct tg3 { #define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2) #define TG3_FLG2_1SHOT_MSI 0x10000000 #define TG3_FLG2_PHY_JITTER_BUG 0x20000000 +#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index b3cf11d32e2..cabdf894e21 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1483,14 +1483,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, sa_offset = 2; /* Grrr, damn Matrox boards. */ multiport_cnt = 4; } -#ifdef CONFIG_DDB5476 - if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 6)) { - /* DDB5476 MAC address in first EEPROM locations. */ - sa_offset = 0; - /* No media table either */ - tp->flags &= ~HAS_MEDIA_TABLE; - } -#endif #ifdef CONFIG_DDB5477 if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 4)) { /* DDB5477 MAC address in first EEPROM locations. */ diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 64ecf929d2a..8fea2aa455d 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -1605,11 +1605,11 @@ static void __devexit w840_remove1 (struct pci_dev *pdev) * - get_stats: * spin_lock_irq(np->lock), doesn't touch hw if not present * - hard_start_xmit: - * netif_stop_queue + spin_unlock_wait(&dev->xmit_lock); + * synchronize_irq + netif_tx_disable; * - tx_timeout: - * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); + * netif_device_detach + netif_tx_disable; * - set_multicast_list - * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); + * netif_device_detach + netif_tx_disable; * - interrupt handler * doesn't touch hw if not present, synchronize_irq waits for * running instances of the interrupt handler. @@ -1635,12 +1635,11 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); update_csr6(dev, 0); iowrite32(0, ioaddr + IntrEnable); - netif_stop_queue(dev); spin_unlock_irq(&np->lock); - spin_unlock_wait(&dev->xmit_lock); synchronize_irq(dev->irq); - + netif_tx_disable(dev); + np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff; /* no more hardware accesses behind this line. */ diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index ed1f837c8fd..2eb6b5f9ba0 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int pktlen = skb->len; +#ifdef VELOCITY_ZERO_COPY_SUPPORT + if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) { + kfree_skb(skb); + return 0; + } +#endif + spin_lock_irqsave(&vptr->lock, flags); index = vptr->td_curr[qnum]; @@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) */ if (pktlen < ETH_ZLEN) { /* Cannot occur until ZC support */ - if(skb_linearize(skb, GFP_ATOMIC)) - return 0; pktlen = ETH_ZLEN; memcpy(tdinfo->buf, skb->data, skb->len); memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); @@ -1933,7 +1938,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int nfrags = skb_shinfo(skb)->nr_frags; tdinfo->skb = skb; if (nfrags > 6) { - skb_linearize(skb, GFP_ATOMIC); memcpy(tdinfo->buf, skb->data, skb->len); tdinfo->skb_dma[0] = tdinfo->buf_dma; td_ptr->tdesc0.pktsize = diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index e66fdb1f3cf..d8f917c21ea 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -636,6 +636,17 @@ struct bcm43xx_key { u8 algorithm; }; +/* Driver initialization status. */ +enum { + BCM43xx_STAT_UNINIT, /* Uninitialized. */ + BCM43xx_STAT_INITIALIZING, /* init_board() in progress. */ + BCM43xx_STAT_INITIALIZED, /* Fully operational. */ + BCM43xx_STAT_SHUTTINGDOWN, /* free_board() in progress. */ + BCM43xx_STAT_RESTARTING, /* controller_restart() called. */ +}; +#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) +#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) + struct bcm43xx_private { struct ieee80211_device *ieee; struct ieee80211softmac_device *softmac; @@ -646,18 +657,17 @@ struct bcm43xx_private { void __iomem *mmio_addr; - /* Do not use the lock directly. Use the bcm43xx_lock* helper - * functions, to be MMIO-safe. */ - spinlock_t _lock; + /* Locking, see "theory of locking" text below. */ + spinlock_t irq_lock; + struct mutex mutex; - /* Driver status flags. */ - u32 initialized:1, /* init_board() succeed */ - was_initialized:1, /* for PCI suspend/resume. */ - shutting_down:1, /* free_board() in progress */ + /* Driver initialization status BCM43xx_STAT_*** */ + atomic_t init_status; + + u16 was_initialized:1, /* for PCI suspend/resume. */ __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ - powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */ short_preamble:1, /* TRUE, if short preamble is enabled. */ firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ @@ -721,7 +731,7 @@ struct bcm43xx_private { struct tasklet_struct isr_tasklet; /* Periodic tasks */ - struct timer_list periodic_tasks; + struct work_struct periodic_work; unsigned int periodic_state; struct work_struct restart_work; @@ -746,21 +756,55 @@ struct bcm43xx_private { #endif }; -/* bcm43xx_(un)lock() protect struct bcm43xx_private. - * Note that _NO_ MMIO writes are allowed. If you want to - * write to the device through MMIO in the critical section, use - * the *_mmio lock functions. - * MMIO read-access is allowed, though. - */ -#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags) -#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags) -/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO. - * MMIO write-access to the device is allowed. - * All MMIO writes are flushed on unlock, so it is guaranteed to not - * interfere with other threads writing MMIO registers. + +/* *** THEORY OF LOCKING *** + * + * We have two different locks in the bcm43xx driver. + * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private + * and the device registers. + * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency. + * + * We have three types of helper function pairs to utilize these locks. + * (Always use the helper functions.) + * 1) bcm43xx_{un}lock_noirq(): + * Takes bcm->mutex. Does _not_ protect against IRQ concurrency, + * so it is almost always unsafe, if device IRQs are enabled. + * So only use this, if device IRQs are masked. + * Locking may sleep. + * You can sleep within the critical section. + * 2) bcm43xx_{un}lock_irqonly(): + * Takes bcm->irq_lock. Does _not_ protect against + * bcm43xx_lock_noirq() critical sections. + * Does only protect against the IRQ handler path and other + * irqonly() critical sections. + * Locking does not sleep. + * You must not sleep within the critical section. + * 3) bcm43xx_{un}lock_irqsafe(): + * This is the cummulative lock and takes both, mutex and irq_lock. + * Protects against noirq() and irqonly() critical sections (and + * the IRQ handler path). + * Locking may sleep. + * You must not sleep within the critical section. */ -#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags) -#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0) + +/* Lock type 1 */ +#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex) +#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex) +/* Lock type 2 */ +#define bcm43xx_lock_irqonly(bcm, flags) \ + spin_lock_irqsave(&(bcm)->irq_lock, flags) +#define bcm43xx_unlock_irqonly(bcm, flags) \ + spin_unlock_irqrestore(&(bcm)->irq_lock, flags) +/* Lock type 3 */ +#define bcm43xx_lock_irqsafe(bcm, flags) do { \ + bcm43xx_lock_noirq(bcm); \ + bcm43xx_lock_irqonly(bcm, flags); \ + } while (0) +#define bcm43xx_unlock_irqsafe(bcm, flags) do { \ + bcm43xx_unlock_irqonly(bcm, flags); \ + bcm43xx_unlock_noirq(bcm); \ + } while (0) + static inline struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) @@ -843,16 +887,6 @@ struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); } -/* Are we running in init_board() context? */ -static inline -int bcm43xx_is_initializing(struct bcm43xx_private *bcm) -{ - if (bcm->initialized) - return 0; - if (bcm->shutting_down) - return 0; - return 1; -} static inline struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c index 7497fb16076..ce2e40b29b4 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c @@ -77,8 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { fappend("Board not initialized.\n"); goto out; } @@ -121,7 +121,7 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, fappend("\n"); out: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -159,8 +159,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, unsigned long flags; down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { fappend("Board not initialized.\n"); goto out; } @@ -169,7 +169,7 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); out: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -188,8 +188,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, u64 tsf; down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { fappend("Board not initialized.\n"); goto out; } @@ -199,7 +199,7 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, (unsigned int)(tsf & 0xFFFFFFFFULL)); out: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -221,8 +221,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, res = -EFAULT; goto out_up; } - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); res = -EFAULT; goto out_unlock; @@ -233,10 +233,11 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, goto out_unlock; } bcm43xx_tsf_write(bcm, tsf); + mmiowb(); res = buf_size; out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); out_up: up(&big_buffer_sem); return res; @@ -257,7 +258,7 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, int i, cnt, j = 0; down(&big_buffer_sem); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", BCM43xx_NR_LOGGED_XMITSTATUS); @@ -293,14 +294,14 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if (*ppos == pos) { /* Done. Drop the copied data. */ e->xmitstatus_printing = 0; } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); up(&big_buffer_sem); return res; } diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index 4b2c02c0b31..ec80692d638 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d) struct bcm43xx_private *bcm = led->bcm; unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); if (led->blink_interval) { bcm43xx_led_changestate(led); mod_timer(&led->blink_timer, jiffies + led->blink_interval); } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); } static void bcm43xx_led_blink_start(struct bcm43xx_led *led, diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 736dde96c4a..085d7857fe3 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -498,20 +498,31 @@ static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mas return old_mask; } +/* Synchronize IRQ top- and bottom-half. + * IRQs must be masked before calling this. + * This must not be called with the irq_lock held. + */ +static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm) +{ + synchronize_irq(bcm->irq); + tasklet_disable(&bcm->isr_tasklet); +} + /* Make sure we don't receive more data from the device. */ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate) { - u32 old; unsigned long flags; + u32 old; - bcm43xx_lock_mmio(bcm, flags); - if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); + if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { + bcm43xx_unlock_irqonly(bcm, flags); return -EBUSY; } old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - tasklet_disable(&bcm->isr_tasklet); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_synchronize_irq(bcm); + if (oldstate) *oldstate = old; @@ -1389,7 +1400,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy) bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); #endif } - if (bcm->shutting_down) { + if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) { bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); @@ -1709,7 +1720,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) # define bcmirq_handled(irq) do { /* nothing */ } while (0) #endif /* CONFIG_BCM43XX_DEBUG*/ - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); reason = bcm->irq_reason; dma_reason[0] = bcm->dma_reason[0]; dma_reason[1] = bcm->dma_reason[1]; @@ -1734,7 +1745,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) dma_reason[0], dma_reason[1], dma_reason[2], dma_reason[3]); bcm43xx_controller_restart(bcm, "DMA error"); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqonly(bcm, flags); return; } if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | @@ -1821,7 +1833,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) if (!modparam_noleds) bcm43xx_leds_update(bcm, activity); bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqonly(bcm, flags); } static void pio_irq_workaround(struct bcm43xx_private *bcm, @@ -1870,7 +1883,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re if (!bcm) return IRQ_NONE; - spin_lock(&bcm->_lock); + spin_lock(&bcm->irq_lock); reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); if (reason == 0xffffffff) { @@ -1899,7 +1912,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re * completely, but some careful work is needed to fix this. I think it * is best to stay with this cheap workaround for now... . */ - if (likely(bcm->initialized)) { + if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { /* disable all IRQs. They are enabled again in the bottom half. */ bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); /* save the reason code and call our bottom half. */ @@ -1909,7 +1922,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re out: mmiowb(); - spin_unlock(&bcm->_lock); + spin_unlock(&bcm->irq_lock); return ret; } @@ -2133,6 +2146,13 @@ out: return err; } +#ifdef CONFIG_BCM947XX +static struct pci_device_id bcm43xx_47xx_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, + { 0 } +}; +#endif + static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) { int res; @@ -2142,11 +2162,15 @@ static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) bcm->irq = bcm->pci_dev->irq; #ifdef CONFIG_BCM947XX if (bcm->pci_dev->bus->number == 0) { - struct pci_dev *d = NULL; - /* FIXME: we will probably need more device IDs here... */ - d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL); - if (d != NULL) { - bcm->irq = d->irq; + struct pci_dev *d; + struct pci_device_id *id; + for (id = bcm43xx_47xx_ids; id->vendor; id++) { + d = pci_get_device(id->vendor, id->device, NULL); + if (d != NULL) { + bcm->irq = d->irq; + pci_dev_put(d); + break; + } } } #endif @@ -3106,15 +3130,10 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) //TODO for APHY (temperature?) } -static void bcm43xx_periodic_task_handler(unsigned long d) +static void do_periodic_work(struct bcm43xx_private *bcm) { - struct bcm43xx_private *bcm = (struct bcm43xx_private *)d; - unsigned long flags; unsigned int state; - bcm43xx_lock_mmio(bcm, flags); - - assert(bcm->initialized); state = bcm->periodic_state; if (state % 8 == 0) bcm43xx_periodic_every120sec(bcm); @@ -3122,29 +3141,93 @@ static void bcm43xx_periodic_task_handler(unsigned long d) bcm43xx_periodic_every60sec(bcm); if (state % 2 == 0) bcm43xx_periodic_every30sec(bcm); - bcm43xx_periodic_every15sec(bcm); + if (state % 1 == 0) + bcm43xx_periodic_every15sec(bcm); bcm->periodic_state = state + 1; - mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); + schedule_delayed_work(&bcm->periodic_work, HZ * 15); +} + +/* Estimate a "Badness" value based on the periodic work + * state-machine state. "Badness" is worse (bigger), if the + * periodic work will take longer. + */ +static int estimate_periodic_work_badness(unsigned int state) +{ + int badness = 0; + + if (state % 8 == 0) /* every 120 sec */ + badness += 10; + if (state % 4 == 0) /* every 60 sec */ + badness += 5; + if (state % 2 == 0) /* every 30 sec */ + badness += 1; + if (state % 1 == 0) /* every 15 sec */ + badness += 1; - bcm43xx_unlock_mmio(bcm, flags); +#define BADNESS_LIMIT 4 + return badness; +} + +static void bcm43xx_periodic_work_handler(void *d) +{ + struct bcm43xx_private *bcm = d; + unsigned long flags; + u32 savedirqs = 0; + int badness; + + badness = estimate_periodic_work_badness(bcm->periodic_state); + if (badness > BADNESS_LIMIT) { + /* Periodic work will take a long time, so we want it to + * be preemtible. + */ + bcm43xx_lock_irqonly(bcm, flags); + netif_stop_queue(bcm->net_dev); + if (bcm43xx_using_pio(bcm)) + bcm43xx_pio_freeze_txqueues(bcm); + savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); + bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_lock_noirq(bcm); + bcm43xx_synchronize_irq(bcm); + } else { + /* Periodic work should take short time, so we want low + * locking overhead. + */ + bcm43xx_lock_irqsafe(bcm, flags); + } + + do_periodic_work(bcm); + + if (badness > BADNESS_LIMIT) { + bcm43xx_lock_irqonly(bcm, flags); + if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { + tasklet_enable(&bcm->isr_tasklet); + bcm43xx_interrupt_enable(bcm, savedirqs); + if (bcm43xx_using_pio(bcm)) + bcm43xx_pio_thaw_txqueues(bcm); + } + netif_wake_queue(bcm->net_dev); + mmiowb(); + bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_noirq(bcm); + } else { + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); + } } static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) { - del_timer_sync(&bcm->periodic_tasks); + cancel_rearming_delayed_work(&bcm->periodic_work); } static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) { - struct timer_list *timer = &(bcm->periodic_tasks); + struct work_struct *work = &(bcm->periodic_work); - assert(bcm->initialized); - setup_timer(timer, - bcm43xx_periodic_task_handler, - (unsigned long)bcm); - timer->expires = jiffies; - add_timer(timer); + assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); + INIT_WORK(work, bcm43xx_periodic_work_handler, bcm); + schedule_work(work); } static void bcm43xx_security_init(struct bcm43xx_private *bcm) @@ -3158,16 +3241,12 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm) static void bcm43xx_free_board(struct bcm43xx_private *bcm) { int i, err; - unsigned long flags; + bcm43xx_lock_noirq(bcm); bcm43xx_sysfs_unregister(bcm); - bcm43xx_periodic_tasks_delete(bcm); - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { if (!bcm->core_80211[i].available) @@ -3182,23 +3261,19 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) bcm43xx_pctl_set_crystal(bcm, 0); - bcm43xx_lock(bcm, flags); - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); + bcm43xx_unlock_noirq(bcm); } static int bcm43xx_init_board(struct bcm43xx_private *bcm) { int i, err; int connect_phy; - unsigned long flags; might_sleep(); - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_lock_noirq(bcm); + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); err = bcm43xx_pctl_set_crystal(bcm, 1); if (err) @@ -3265,9 +3340,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) } /* Initialization of the board is done. Flag it as such. */ - bcm43xx_lock(bcm, flags); - bcm->initialized = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED); bcm43xx_periodic_tasks_setup(bcm); bcm43xx_sysfs_register(bcm); @@ -3278,6 +3351,8 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) assert(err == 0); out: + bcm43xx_unlock_noirq(bcm); + return err; err_80211_unwind: @@ -3534,8 +3609,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, struct bcm43xx_radioinfo *radio; unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { bcm43xx_mac_suspend(bcm); bcm43xx_radio_selectchannel(bcm, channel, 0); bcm43xx_mac_enable(bcm); @@ -3543,7 +3618,7 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, radio = bcm43xx_current_radio(bcm); radio->initial_channel = channel; } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); } /* set_security() callback in struct ieee80211_device */ @@ -3557,7 +3632,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, dprintk(KERN_INFO PFX "set security called"); - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) if (sec->flags & (1<<keyidx)) { @@ -3587,7 +3662,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, dprintk(", .encrypt = %d", sec->encrypt); } dprintk("\n"); - if (bcm->initialized && !bcm->ieee->host_encrypt) { + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && + !bcm->ieee->host_encrypt) { if (secinfo->enabled) { /* upload WEP keys to hardware */ char null_address[6] = { 0 }; @@ -3621,7 +3697,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, } else bcm43xx_clear_keys(bcm); } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); } /* hard_start_xmit() callback in struct ieee80211_device */ @@ -3633,10 +3709,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, int err = -ENODEV; unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); - if (likely(bcm->initialized)) + bcm43xx_lock_irqonly(bcm, flags); + if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) err = bcm43xx_tx(bcm, txb); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); return err; } @@ -3651,9 +3727,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev) struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); bcm43xx_controller_restart(bcm, "TX timeout"); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -3678,9 +3754,11 @@ static int bcm43xx_net_open(struct net_device *net_dev) static int bcm43xx_net_stop(struct net_device *net_dev) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); + int err; ieee80211softmac_stop(net_dev); - bcm43xx_disable_interrupts_sync(bcm, NULL); + err = bcm43xx_disable_interrupts_sync(bcm, NULL); + assert(!err); bcm43xx_free_board(bcm); return 0; @@ -3692,6 +3770,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, { int err; + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); bcm->ieee = netdev_priv(net_dev); bcm->softmac = ieee80211_priv(net_dev); bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; @@ -3700,7 +3779,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, bcm->pci_dev = pci_dev; bcm->net_dev = net_dev; bcm->bad_frames_preempt = modparam_bad_frames_preempt; - spin_lock_init(&bcm->_lock); + spin_lock_init(&bcm->irq_lock); + mutex_init(&bcm->mutex); tasklet_init(&bcm->isr_tasklet, (void (*)(unsigned long))bcm43xx_interrupt_tasklet, (unsigned long)bcm); @@ -3831,7 +3911,7 @@ static void bcm43xx_chip_reset(void *_bcm) struct net_device *net_dev = bcm->net_dev; struct pci_dev *pci_dev = bcm->pci_dev; int err; - int was_initialized = bcm->initialized; + int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); netif_stop_queue(bcm->net_dev); tasklet_disable(&bcm->isr_tasklet); @@ -3866,6 +3946,7 @@ failure: */ void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) { + bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING); bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); @@ -3884,11 +3965,11 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) dprintk(KERN_INFO PFX "Suspending...\n"); - bcm43xx_lock(bcm, flags); - bcm->was_initialized = bcm->initialized; - if (bcm->initialized) + bcm43xx_lock_irqsafe(bcm, flags); + bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); + if (bcm->was_initialized) try_to_shutdown = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); netif_device_detach(net_dev); if (try_to_shutdown) { diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index b0abac51553..f8200deecc8 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c @@ -1410,7 +1410,10 @@ static inline u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) { struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); + u16 ret; + unsigned long flags; + local_irq_save(flags); if (phy->connected) { bcm43xx_phy_write(bcm, 0x15, 0xE300); control <<= 8; @@ -1430,8 +1433,10 @@ u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0); udelay(8); } + ret = bcm43xx_phy_read(bcm, 0x002D); + local_irq_restore(flags); - return bcm43xx_phy_read(bcm, 0x002D); + return ret; } static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control) @@ -1648,7 +1653,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) { static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 }; - const int is_initializing = bcm43xx_is_initializing(bcm); + const int is_initializing = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZING); struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); u16 h, i, oldi = 0, j; diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c index 0aa1bd269a2..574085c4615 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c @@ -262,8 +262,10 @@ static void tx_tasklet(unsigned long d) int err; u16 txctl; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); + if (queue->tx_frozen) + goto out_unlock; txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); if (txctl & BCM43xx_PIO_TXCTL_SUSPEND) goto out_unlock; @@ -298,7 +300,7 @@ static void tx_tasklet(unsigned long d) continue; } out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); } static void setup_txqueues(struct bcm43xx_pioqueue *queue) @@ -374,7 +376,6 @@ static void cancel_transfers(struct bcm43xx_pioqueue *queue) struct bcm43xx_pio_txpacket *packet, *tmp_packet; netif_tx_disable(queue->bcm->net_dev); - assert(queue->bcm->shutting_down); tasklet_disable(&queue->txtask); list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) @@ -634,5 +635,40 @@ void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) & ~BCM43xx_PIO_TXCTL_SUSPEND); bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1); - tasklet_schedule(&queue->txtask); + if (!list_empty(&queue->txqueue)) + tasklet_schedule(&queue->txtask); +} + +void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm) +{ + struct bcm43xx_pio *pio; + + assert(bcm43xx_using_pio(bcm)); + pio = bcm43xx_current_pio(bcm); + pio->queue0->tx_frozen = 1; + pio->queue1->tx_frozen = 1; + pio->queue2->tx_frozen = 1; + pio->queue3->tx_frozen = 1; } + +void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm) +{ + struct bcm43xx_pio *pio; + + assert(bcm43xx_using_pio(bcm)); + pio = bcm43xx_current_pio(bcm); + pio->queue0->tx_frozen = 0; + pio->queue1->tx_frozen = 0; + pio->queue2->tx_frozen = 0; + pio->queue3->tx_frozen = 0; + if (!list_empty(&pio->queue0->txqueue)) + tasklet_schedule(&pio->queue0->txtask); + if (!list_empty(&pio->queue1->txqueue)) + tasklet_schedule(&pio->queue1->txtask); + if (!list_empty(&pio->queue2->txqueue)) + tasklet_schedule(&pio->queue2->txtask); + if (!list_empty(&pio->queue3->txqueue)) + tasklet_schedule(&pio->queue3->txtask); +} + + diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h index dfc78209e3a..bc78a3c2caf 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h @@ -54,6 +54,7 @@ struct bcm43xx_pioqueue { u16 mmio_base; u8 tx_suspended:1, + tx_frozen:1, need_workarounds:1; /* Workarounds needed for core.rev < 3 */ /* Adjusted size of the device internal TX buffer. */ @@ -108,8 +109,12 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, struct bcm43xx_xmitstatus *status); void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); +/* Suspend a TX queue on hardware level. */ void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue); void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue); +/* Suspend (freeze) the TX tasklet (software level). */ +void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm); +void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm); #else /* CONFIG_BCM43XX_PIO */ @@ -145,6 +150,14 @@ static inline void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) { } +static inline +void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm) +{ +} +static inline +void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm) +{ +} #endif /* CONFIG_BCM43XX_PIO */ #endif /* BCM43xx_PIO_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index b438f48e891..6a23bdc7541 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -120,12 +120,12 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev, GFP_KERNEL); if (!sprom) return -ENOMEM; - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); err = bcm43xx_sprom_read(bcm, sprom); if (!err) err = sprom2hex(sprom, buf, PAGE_SIZE); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); kfree(sprom); return err; @@ -150,10 +150,10 @@ static ssize_t bcm43xx_attr_sprom_store(struct device *dev, err = hex2sprom(sprom, buf, count); if (err) goto out_kfree; - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); out_kfree: kfree(sprom); @@ -170,15 +170,13 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, char *buf) { struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; int err; ssize_t count = 0; if (!capable(CAP_NET_ADMIN)) return -EPERM; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_noirq(bcm); switch (bcm43xx_current_radio(bcm)->interfmode) { case BCM43xx_RADIO_INTERFMODE_NONE: @@ -195,7 +193,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, } err = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return err ? err : count; @@ -231,16 +229,15 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, return -EINVAL; } - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); err = bcm43xx_radio_set_interference_mitigation(bcm, mode); if (err) { printk(KERN_ERR PFX "Interference Mitigation not " "supported by device\n"); } - - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); return err ? err : count; } @@ -254,15 +251,13 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, char *buf) { struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; int err; ssize_t count; if (!capable(CAP_NET_ADMIN)) return -EPERM; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_noirq(bcm); if (bcm->short_preamble) count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); @@ -270,7 +265,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); err = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return err ? err : count; } @@ -290,13 +285,12 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, value = get_boolean(buf, count); if (value < 0) return value; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); bcm->short_preamble = !!value; err = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err ? err : count; } @@ -310,7 +304,7 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) struct device *dev = &bcm->pci_dev->dev; int err; - assert(bcm->initialized); + assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); err = device_create_file(dev, &dev_attr_sprom); if (err) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index b45063974ae..c35cb3a0777 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c @@ -55,13 +55,13 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; int i; + unsigned long flags; struct bcm43xx_phyinfo *phy; char suffix[7] = { 0 }; int have_a = 0, have_b = 0, have_g = 0; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); for (i = 0; i < bcm->nr_80211_available; i++) { phy = &(bcm->core_80211_ext[i].phy); switch (phy->type) { @@ -77,7 +77,7 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, assert(0); } } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); i = 0; if (have_a) { @@ -111,7 +111,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, int freq; int err = -EINVAL; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { channel = data->freq.m; freq = bcm43xx_channel_to_freq(bcm, channel); @@ -121,7 +121,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, } if (!bcm43xx_is_valid_channel(bcm, channel)) goto out_unlock; - if (bcm->initialized) { + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { //ieee80211softmac_disassoc(softmac, $REASON); bcm43xx_mac_suspend(bcm); err = bcm43xx_radio_selectchannel(bcm, channel, 0); @@ -131,7 +131,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, err = 0; } out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -147,11 +147,10 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, int err = -ENODEV; u16 channel; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); radio = bcm43xx_current_radio(bcm); channel = radio->channel; if (channel == 0xFF) { - assert(!bcm->initialized); channel = radio->initial_channel; if (channel == 0xFF) goto out_unlock; @@ -163,7 +162,7 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -181,13 +180,13 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev, if (mode == IW_MODE_AUTO) mode = BCM43xx_INITIAL_IWMODE; - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { if (bcm->ieee->iw_mode != mode) bcm43xx_set_iwmode(bcm, mode); } else bcm->ieee->iw_mode = mode; - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -200,9 +199,9 @@ static int bcm43xx_wx_get_mode(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); data->mode = bcm->ieee->iw_mode; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -255,7 +254,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); phy = bcm43xx_current_phy(bcm); range->num_bitrates = 0; @@ -302,7 +301,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, } range->num_frequency = j; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -313,14 +312,13 @@ static int bcm43xx_wx_set_nick(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; size_t len; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_noirq(bcm); len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); memcpy(bcm->nick, extra, len); bcm->nick[len] = '\0'; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return 0; } @@ -331,15 +329,14 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; size_t len; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_noirq(bcm); len = strlen(bcm->nick) + 1; memcpy(extra, bcm->nick, len); data->data.length = (__u16)len; data->data.flags = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return 0; } @@ -353,7 +350,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, unsigned long flags; int err = -EINVAL; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if (data->rts.disabled) { bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; err = 0; @@ -364,7 +361,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, err = 0; } } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -377,11 +374,11 @@ static int bcm43xx_wx_get_rts(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); data->rts.value = bcm->rts_threshold; data->rts.fixed = 0; data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -395,7 +392,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, unsigned long flags; int err = -EINVAL; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if (data->frag.disabled) { bcm->ieee->fts = MAX_FRAG_THRESHOLD; err = 0; @@ -406,7 +403,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, err = 0; } } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -419,11 +416,11 @@ static int bcm43xx_wx_get_frag(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); data->frag.value = bcm->ieee->fts; data->frag.fixed = 0; data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -445,8 +442,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, return -EOPNOTSUPP; } - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) goto out_unlock; radio = bcm43xx_current_radio(bcm); phy = bcm43xx_current_phy(bcm); @@ -469,7 +466,7 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -484,8 +481,8 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, unsigned long flags; int err = -ENODEV; - bcm43xx_lock(bcm, flags); - if (!bcm->initialized) + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) goto out_unlock; radio = bcm43xx_current_radio(bcm); /* desired dBm value is in Q5.2 */ @@ -496,7 +493,7 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -583,8 +580,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, return -EINVAL; } - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { err = bcm43xx_radio_set_interference_mitigation(bcm, mode); if (err) { printk(KERN_ERR PFX "Interference Mitigation not " @@ -598,7 +595,7 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, } else bcm43xx_current_radio(bcm)->interfmode = mode; } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -612,9 +609,9 @@ static int bcm43xx_wx_get_interfmode(struct net_device *net_dev, unsigned long flags; int mode; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); mode = bcm43xx_current_radio(bcm)->interfmode; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); switch (mode) { case BCM43xx_RADIO_INTERFMODE_NONE: @@ -644,9 +641,9 @@ static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev, int on; on = *((int *)extra); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); bcm->short_preamble = !!on; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -660,9 +657,9 @@ static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev, unsigned long flags; int on; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); on = bcm->short_preamble; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); if (on) strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); @@ -684,11 +681,11 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev, on = *((int *)extra); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); bcm->ieee->host_encrypt = !!on; bcm->ieee->host_decrypt = !!on; bcm->ieee->host_build_iv = !on; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -702,9 +699,9 @@ static int bcm43xx_wx_get_swencryption(struct net_device *net_dev, unsigned long flags; int on; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); on = bcm->ieee->host_encrypt; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); if (on) strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); @@ -767,11 +764,11 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, if (!sprom) goto out; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); err = -ENODEV; - if (bcm->initialized) + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) err = bcm43xx_sprom_read(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); if (!err) data->data.length = sprom2hex(sprom, extra); kfree(sprom); @@ -812,11 +809,11 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, if (err) goto out_kfree; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); err = -ENODEV; - if (bcm->initialized) + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); out_kfree: kfree(sprom); out: diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 39f82f21974..081a8999666 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -533,7 +533,7 @@ static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask) ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); } -static inline void ipw_enable_interrupts(struct ipw_priv *priv) +static inline void __ipw_enable_interrupts(struct ipw_priv *priv) { if (priv->status & STATUS_INT_ENABLED) return; @@ -541,7 +541,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL); } -static inline void ipw_disable_interrupts(struct ipw_priv *priv) +static inline void __ipw_disable_interrupts(struct ipw_priv *priv) { if (!(priv->status & STATUS_INT_ENABLED)) return; @@ -549,6 +549,24 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL); } +static inline void ipw_enable_interrupts(struct ipw_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->irq_lock, flags); + __ipw_enable_interrupts(priv); + spin_unlock_irqrestore(&priv->irq_lock, flags); +} + +static inline void ipw_disable_interrupts(struct ipw_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->irq_lock, flags); + __ipw_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->irq_lock, flags); +} + #ifdef CONFIG_IPW2200_DEBUG static char *ipw_error_desc(u32 val) { @@ -1856,7 +1874,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) unsigned long flags; int rc = 0; - spin_lock_irqsave(&priv->lock, flags); + spin_lock_irqsave(&priv->irq_lock, flags); inta = ipw_read32(priv, IPW_INTA_RW); inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); @@ -1865,6 +1883,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) /* Add any cached INTA values that need to be handled */ inta |= priv->isr_inta; + spin_unlock_irqrestore(&priv->irq_lock, flags); + + spin_lock_irqsave(&priv->lock, flags); + /* handle all the justifications for the interrupt */ if (inta & IPW_INTA_BIT_RX_TRANSFER) { ipw_rx(priv); @@ -1993,10 +2015,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); } + spin_unlock_irqrestore(&priv->lock, flags); + /* enable all interrupts */ ipw_enable_interrupts(priv); - - spin_unlock_irqrestore(&priv->lock, flags); } #define IPW_CMD(x) case IPW_CMD_ ## x : return #x @@ -10460,7 +10482,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) if (!priv) return IRQ_NONE; - spin_lock(&priv->lock); + spin_lock(&priv->irq_lock); if (!(priv->status & STATUS_INT_ENABLED)) { /* Shared IRQ */ @@ -10482,7 +10504,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) } /* tell the device to stop sending interrupts */ - ipw_disable_interrupts(priv); + __ipw_disable_interrupts(priv); /* ack current interrupts */ inta &= (IPW_INTA_MASK_ALL & inta_mask); @@ -10493,11 +10515,11 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) tasklet_schedule(&priv->irq_tasklet); - spin_unlock(&priv->lock); + spin_unlock(&priv->irq_lock); return IRQ_HANDLED; none: - spin_unlock(&priv->lock); + spin_unlock(&priv->irq_lock); return IRQ_NONE; } @@ -11477,6 +11499,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_IPW2200_DEBUG ipw_debug_level = debug; #endif + spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->lock); for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index 6044c0be2c8..ea12ad66b8e 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h @@ -1173,6 +1173,7 @@ struct ipw_priv { struct ieee80211_device *ieee; spinlock_t lock; + spinlock_t irq_lock; struct mutex mutex; /* basic pci-network driver stuff */ diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index b563decf599..8a31b591a90 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -1787,7 +1787,9 @@ static int __orinoco_program_rids(struct net_device *dev) /* Set promiscuity / multicast*/ priv->promiscuous = 0; priv->mc_count = 0; - __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */ + + /* FIXME: what about netif_tx_lock */ + __orinoco_set_multicast_list(dev); return 0; } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 1456759936c..10e1a905c14 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -285,9 +285,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) * Default resume method for devices that have no driver provided resume, * or not even a driver at all. */ -static void pci_default_resume(struct pci_dev *pci_dev) +static int pci_default_resume(struct pci_dev *pci_dev) { - int retval; + int retval = 0; /* restore the PCI config space */ pci_restore_state(pci_dev); @@ -297,18 +297,21 @@ static void pci_default_resume(struct pci_dev *pci_dev) /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); + + return retval; } static int pci_device_resume(struct device * dev) { + int error; struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; if (drv && drv->resume) - drv->resume(pci_dev); + error = drv->resume(pci_dev); else - pci_default_resume(pci_dev); - return 0; + error = pci_default_resume(pci_dev); + return error; } static void pci_device_shutdown(struct device *dev) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8d107c6c2c7..fde41cc1473 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -460,9 +460,23 @@ int pci_restore_state(struct pci_dev *dev) { int i; + int val; - for (i = 0; i < 16; i++) - pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); + /* + * The Base Address register should be programmed before the command + * register(s) + */ + for (i = 15; i >= 0; i--) { + pci_read_config_dword(dev, i * 4, &val); + if (val != dev->saved_config_space[i]) { + printk(KERN_DEBUG "PM: Writing back config space on " + "device %s at offset %x (was %x, writing %x)\n", + pci_name(dev), i, + val, (int)dev->saved_config_space[i]); + pci_write_config_dword(dev,i * 4, + dev->saved_config_space[i]); + } + } pci_restore_msi_state(dev); pci_restore_msix_state(dev); return 0; diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index b046ffa2210..de9ba7890b5 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -4297,6 +4297,7 @@ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev) int ata_device_resume(struct ata_port *ap, struct ata_device *dev) { if (ap->flags & ATA_FLAG_SUSPENDED) { + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 200000); ap->flags &= ~ATA_FLAG_SUSPENDED; ata_set_mode(ap); diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 9b8bca1ac1f..f16f92a6ec0 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -2035,6 +2035,7 @@ static void mv_phy_reset(struct ata_port *ap) static void mv_eng_timeout(struct ata_port *ap) { struct ata_queued_cmd *qc; + unsigned long flags; printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); DPRINTK("All regs @ start of eng_timeout\n"); @@ -2046,8 +2047,10 @@ static void mv_eng_timeout(struct ata_port *ap) ap->host_set->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd); + spin_lock_irqsave(&ap->host_set->lock, flags); mv_err_intr(ap, 0); mv_stop_and_reset(ap); + spin_unlock_irqrestore(&ap->host_set->lock, flags); WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); if (qc->flags & ATA_QCFLAG_ACTIVE) { diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index acde8868da2..fafe7c1265b 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -185,6 +185,9 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device /* Select Power Management Mode */ pxa27x_ohci_select_pmm(inf->port_mode); + if (inf->power_budget) + hcd->power_budget = inf->power_budget; + ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4587087d777..5641498725d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -743,7 +743,7 @@ config FB_I810_I2C config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)" - depends on FB && EXPERIMENTAL && PCI && X86_32 + depends on FB && EXPERIMENTAL && PCI && X86 select AGP select AGP_INTEL select FB_MODE_HELPERS diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 953eb8c171d..47ba1a79adc 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -1745,7 +1745,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, fbcon_redraw_move(vc, p, 0, t, count); ypan_up_redraw(vc, t, count); if (vc->vc_rows - b > 0) - fbcon_redraw_move(vc, p, b - count, + fbcon_redraw_move(vc, p, b, vc->vc_rows - b, b); } else fbcon_redraw_move(vc, p, t + count, b - t - count, t); diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index da29d007f21..469b06c2918 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h @@ -8,9 +8,9 @@ /*** Version/name ***/ -#define INTELFB_VERSION "0.9.2" +#define INTELFB_VERSION "0.9.4" #define INTELFB_MODULE_NAME "intelfb" -#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM" +#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM" /*** Debug/feature defines ***/ @@ -52,11 +52,14 @@ #define PCI_DEVICE_ID_INTEL_865G 0x2572 #define PCI_DEVICE_ID_INTEL_915G 0x2582 #define PCI_DEVICE_ID_INTEL_915GM 0x2592 +#define PCI_DEVICE_ID_INTEL_945G 0x2772 +#define PCI_DEVICE_ID_INTEL_945GM 0x27A2 /* Size of MMIO region */ #define INTEL_REG_SIZE 0x80000 #define STRIDE_ALIGNMENT 16 +#define STRIDE_ALIGNMENT_I9XX 64 #define PALETTE_8_ENTRIES 256 @@ -125,7 +128,9 @@ enum intel_chips { INTEL_855GME, INTEL_865G, INTEL_915G, - INTEL_915GM + INTEL_915GM, + INTEL_945G, + INTEL_945GM, }; struct intelfb_hwstate { @@ -277,8 +282,13 @@ struct intelfb_info { /* driver registered */ int registered; + + /* index into plls */ + int pll_index; }; +#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) + /*** function prototypes ***/ extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 995b47c165a..076fa56be19 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -1,11 +1,12 @@ /* * intelfb * - * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM - * integrated graphics chips. + * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/ + * 945G/945GM integrated graphics chips. * * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> * 2004 Sylvain Meyer + * 2006 David Airlie * * This driver consists of two parts. The first part (intelfbdrv.c) provides * the basic fbdev interfaces, is derived in part from the radeonfb and @@ -131,6 +132,7 @@ #include "intelfb.h" #include "intelfbhw.h" +#include "../edid.h" static void __devinit get_initial_mode(struct intelfb_info *dinfo); static void update_dinfo(struct intelfb_info *dinfo, @@ -182,6 +184,8 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM }, { 0, } }; @@ -261,7 +265,7 @@ MODULE_PARM_DESC(mode, #ifndef MODULE #define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name))) -#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name), NULL, 0) +#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0) #define OPT_STRVAL(opt, name) (opt + strlen(name)) static __inline__ char * @@ -546,11 +550,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) /* Set base addresses. */ if ((ent->device == PCI_DEVICE_ID_INTEL_915G) || - (ent->device == PCI_DEVICE_ID_INTEL_915GM)) { + (ent->device == PCI_DEVICE_ID_INTEL_915GM) || + (ent->device == PCI_DEVICE_ID_INTEL_945G) || + (ent->device == PCI_DEVICE_ID_INTEL_945GM)) { aperture_bar = 2; mmio_bar = 0; - /* Disable HW cursor on 915G/M (not implemented yet) */ - hwcursor = 0; } dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); dinfo->aperture.size = pci_resource_len(pdev, aperture_bar); @@ -584,8 +588,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) /* Get the chipset info. */ dinfo->pci_chipset = pdev->device; - if (intelfbhw_get_chipset(pdev, &dinfo->name, &dinfo->chipset, - &dinfo->mobile)) { + if (intelfbhw_get_chipset(pdev, dinfo)) { cleanup(dinfo); return -ENODEV; } @@ -1029,17 +1032,44 @@ intelfb_init_var(struct intelfb_info *dinfo) sizeof(struct fb_var_screeninfo)); msrc = 5; } else { + const u8 *edid_s = fb_firmware_edid(&dinfo->pdev->dev); + u8 *edid_d = NULL; + + if (edid_s) { + edid_d = kmalloc(EDID_LENGTH, GFP_KERNEL); + + if (edid_d) { + memcpy(edid_d, edid_s, EDID_LENGTH); + fb_edid_to_monspecs(edid_d, + &dinfo->info->monspecs); + kfree(edid_d); + } + } + if (mode) { + printk("intelfb: Looking for mode in private " + "database\n"); msrc = fb_find_mode(var, dinfo->info, mode, - vesa_modes, VESA_MODEDB_SIZE, + dinfo->info->monspecs.modedb, + dinfo->info->monspecs.modedb_len, NULL, 0); - if (msrc) - msrc |= 8; + + if (msrc && msrc > 1) { + printk("intelfb: No mode in private database, " + "intelfb: looking for mode in global " + "database "); + msrc = fb_find_mode(var, dinfo->info, mode, + NULL, 0, NULL, 0); + + if (msrc) + msrc |= 8; + } + } + if (!msrc) { msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, - vesa_modes, VESA_MODEDB_SIZE, - NULL, 0); + NULL, 0, NULL, 0); } } @@ -1139,7 +1169,10 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) } /* Make sure the line length is a aligned correctly. */ - dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); + if (IS_I9XX(dinfo)) + dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT_I9XX); + else + dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); if (FIXED_MODE(dinfo)) dinfo->pitch = dinfo->initial_pitch; @@ -1162,16 +1195,33 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) struct fb_var_screeninfo v; struct intelfb_info *dinfo; static int first = 1; + int i; + /* Good pitches to allow tiling. Don't care about pitches < 1024. */ + static const int pitches[] = { + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 + }; DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags); dinfo = GET_DINFO(info); + /* update the pitch */ if (intelfbhw_validate_mode(dinfo, var) != 0) return -EINVAL; v = *var; + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= v.xres_virtual) { + v.xres_virtual = pitches[i]; + break; + } + } + /* Check for a supported bpp. */ if (v.bits_per_pixel <= 8) { v.bits_per_pixel = 8; @@ -1467,7 +1517,7 @@ static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct intelfb_info *dinfo = GET_DINFO(info); - + u32 physical; #if VERBOSE > 0 DBG_MSG("intelfb_cursor\n"); #endif @@ -1478,7 +1528,10 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) intelfbhw_cursor_hide(dinfo); /* If XFree killed the cursor - restore it */ - if (INREG(CURSOR_A_BASEADDR) != dinfo->cursor.offset << 12) { + physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical : + (dinfo->cursor.offset << 12); + + if (INREG(CURSOR_A_BASEADDR) != physical) { u32 fg, bg; DBG_MSG("the cursor was killed - restore it !!\n"); diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 624c4bc96f0..426b7430b12 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -40,68 +40,110 @@ #include "intelfb.h" #include "intelfbhw.h" +struct pll_min_max { + int min_m, max_m, min_m1, max_m1; + int min_m2, max_m2, min_n, max_n; + int min_p, max_p, min_p1, max_p1; + int min_vco, max_vco, p_transition_clk, ref_clk; + int p_inc_lo, p_inc_hi; +}; + +#define PLLS_I8xx 0 +#define PLLS_I9xx 1 +#define PLLS_MAX 2 + +static struct pll_min_max plls[PLLS_MAX] = { + { 108, 140, 18, 26, + 6, 16, 3, 16, + 4, 128, 0, 31, + 930000, 1400000, 165000, 48000, + 4, 2 }, //I8xx + + { 75, 120, 10, 20, + 5, 9, 4, 7, + 5, 80, 1, 8, + 1400000, 2800000, 200000, 96000, + 10, 5 } //I9xx +}; + int -intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset, - int *mobile) +intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo) { u32 tmp; - - if (!pdev || !name || !chipset || !mobile) + if (!pdev || !dinfo) return 1; switch (pdev->device) { case PCI_DEVICE_ID_INTEL_830M: - *name = "Intel(R) 830M"; - *chipset = INTEL_830M; - *mobile = 1; + dinfo->name = "Intel(R) 830M"; + dinfo->chipset = INTEL_830M; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I8xx; return 0; case PCI_DEVICE_ID_INTEL_845G: - *name = "Intel(R) 845G"; - *chipset = INTEL_845G; - *mobile = 0; + dinfo->name = "Intel(R) 845G"; + dinfo->chipset = INTEL_845G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I8xx; return 0; case PCI_DEVICE_ID_INTEL_85XGM: tmp = 0; - *mobile = 1; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I8xx; pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp); switch ((tmp >> INTEL_85X_VARIANT_SHIFT) & INTEL_85X_VARIANT_MASK) { case INTEL_VAR_855GME: - *name = "Intel(R) 855GME"; - *chipset = INTEL_855GME; + dinfo->name = "Intel(R) 855GME"; + dinfo->chipset = INTEL_855GME; return 0; case INTEL_VAR_855GM: - *name = "Intel(R) 855GM"; - *chipset = INTEL_855GM; + dinfo->name = "Intel(R) 855GM"; + dinfo->chipset = INTEL_855GM; return 0; case INTEL_VAR_852GME: - *name = "Intel(R) 852GME"; - *chipset = INTEL_852GME; + dinfo->name = "Intel(R) 852GME"; + dinfo->chipset = INTEL_852GME; return 0; case INTEL_VAR_852GM: - *name = "Intel(R) 852GM"; - *chipset = INTEL_852GM; + dinfo->name = "Intel(R) 852GM"; + dinfo->chipset = INTEL_852GM; return 0; default: - *name = "Intel(R) 852GM/855GM"; - *chipset = INTEL_85XGM; + dinfo->name = "Intel(R) 852GM/855GM"; + dinfo->chipset = INTEL_85XGM; return 0; } break; case PCI_DEVICE_ID_INTEL_865G: - *name = "Intel(R) 865G"; - *chipset = INTEL_865G; - *mobile = 0; + dinfo->name = "Intel(R) 865G"; + dinfo->chipset = INTEL_865G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I8xx; return 0; case PCI_DEVICE_ID_INTEL_915G: - *name = "Intel(R) 915G"; - *chipset = INTEL_915G; - *mobile = 0; + dinfo->name = "Intel(R) 915G"; + dinfo->chipset = INTEL_915G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I9xx; return 0; case PCI_DEVICE_ID_INTEL_915GM: - *name = "Intel(R) 915GM"; - *chipset = INTEL_915GM; - *mobile = 1; + dinfo->name = "Intel(R) 915GM"; + dinfo->chipset = INTEL_915GM; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I9xx; + return 0; + case PCI_DEVICE_ID_INTEL_945G: + dinfo->name = "Intel(R) 945G"; + dinfo->chipset = INTEL_945G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I9xx; + return 0; + case PCI_DEVICE_ID_INTEL_945GM: + dinfo->name = "Intel(R) 945GM"; + dinfo->chipset = INTEL_945GM; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I9xx; return 0; default: return 1; @@ -114,6 +156,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, { struct pci_dev *bridge_dev; u16 tmp; + int stolen_overhead; if (!pdev || !aperture_size || !stolen_size) return 1; @@ -128,21 +171,41 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, tmp = 0; pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); switch (pdev->device) { - case PCI_DEVICE_ID_INTEL_830M: - case PCI_DEVICE_ID_INTEL_845G: + case PCI_DEVICE_ID_INTEL_915G: + case PCI_DEVICE_ID_INTEL_915GM: + case PCI_DEVICE_ID_INTEL_945G: + case PCI_DEVICE_ID_INTEL_945GM: + /* 915 and 945 chipsets support a 256MB aperture. + Aperture size is determined by inspected the + base address of the aperture. */ + if (pci_resource_start(pdev, 2) & 0x08000000) + *aperture_size = MB(128); + else + *aperture_size = MB(256); + break; + default: if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) *aperture_size = MB(64); else *aperture_size = MB(128); + break; + } + + /* Stolen memory size is reduced by the GTT and the popup. + GTT is 1K per MB of aperture size, and popup is 4K. */ + stolen_overhead = (*aperture_size / MB(1)) + 4; + switch(pdev->device) { + case PCI_DEVICE_ID_INTEL_830M: + case PCI_DEVICE_ID_INTEL_845G: switch (tmp & INTEL_830_GMCH_GMS_MASK) { case INTEL_830_GMCH_GMS_STOLEN_512: - *stolen_size = KB(512) - KB(132); + *stolen_size = KB(512) - KB(stolen_overhead); return 0; case INTEL_830_GMCH_GMS_STOLEN_1024: - *stolen_size = MB(1) - KB(132); + *stolen_size = MB(1) - KB(stolen_overhead); return 0; case INTEL_830_GMCH_GMS_STOLEN_8192: - *stolen_size = MB(8) - KB(132); + *stolen_size = MB(8) - KB(stolen_overhead); return 0; case INTEL_830_GMCH_GMS_LOCAL: ERR_MSG("only local memory found\n"); @@ -157,28 +220,27 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, } break; default: - *aperture_size = MB(128); switch (tmp & INTEL_855_GMCH_GMS_MASK) { case INTEL_855_GMCH_GMS_STOLEN_1M: - *stolen_size = MB(1) - KB(132); + *stolen_size = MB(1) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_4M: - *stolen_size = MB(4) - KB(132); + *stolen_size = MB(4) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_8M: - *stolen_size = MB(8) - KB(132); + *stolen_size = MB(8) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_16M: - *stolen_size = MB(16) - KB(132); + *stolen_size = MB(16) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_32M: - *stolen_size = MB(32) - KB(132); + *stolen_size = MB(32) - KB(stolen_overhead); return 0; case INTEL_915G_GMCH_GMS_STOLEN_48M: - *stolen_size = MB(48) - KB(132); + *stolen_size = MB(48) - KB(stolen_overhead); return 0; case INTEL_915G_GMCH_GMS_STOLEN_64M: - *stolen_size = MB(64) - KB(132); + *stolen_size = MB(64) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_DISABLED: ERR_MSG("video memory is disabled\n"); @@ -529,12 +591,63 @@ intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, } +static int calc_vclock3(int index, int m, int n, int p) +{ + if (p == 0 || n == 0) + return 0; + return plls[index].ref_clk * m / n / p; +} + +static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvds) +{ + struct pll_min_max *pll = &plls[index]; + u32 m, vco, p; + + m = (5 * (m1 + 2)) + (m2 + 2); + n += 2; + vco = pll->ref_clk * m / n; + + if (index == PLLS_I8xx) { + p = ((p1 + 2) * (1 << (p2 + 1))); + } else { + p = ((p1) * (p2 ? 5 : 10)); + } + return vco / p; +} + +static void +intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) +{ + int p1, p2; + + if (IS_I9XX(dinfo)) { + if (dpll & DPLL_P1_FORCE_DIV2) + p1 = 1; + else + p1 = (dpll >> DPLL_P1_SHIFT) & 0xff; + + p1 = ffs(p1); + + p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; + } else { + if (dpll & DPLL_P1_FORCE_DIV2) + p1 = 0; + else + p1 = (dpll >> DPLL_P1_SHIFT) & DPLL_P1_MASK; + p2 = (dpll >> DPLL_P2_SHIFT) & DPLL_P2_MASK; + } + + *o_p1 = p1; + *o_p2 = p2; +} + + void intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) { #if REGDUMP int i, m1, m2, n, p1, p2; - + int index = dinfo->pll_index; DBG_MSG("intelfbhw_print_hw_state\n"); if (!hw || !dinfo) @@ -547,26 +660,22 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; - if (hw->vga_pd & VGAPD_0_P1_FORCE_DIV2) - p1 = 0; - else - p1 = (hw->vga_pd >> VGAPD_0_P1_SHIFT) & DPLL_P1_MASK; - p2 = (hw->vga_pd >> VGAPD_0_P2_SHIFT) & DPLL_P2_MASK; + + intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); + printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" VGA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" VGA0: clock is %d\n", + calc_vclock(index, m1, m2, n, p1, p2, 0)); n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; - if (hw->vga_pd & VGAPD_1_P1_FORCE_DIV2) - p1 = 0; - else - p1 = (hw->vga_pd >> VGAPD_1_P1_SHIFT) & DPLL_P1_MASK; - p2 = (hw->vga_pd >> VGAPD_1_P2_SHIFT) & DPLL_P2_MASK; + + intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" VGA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); printk(" DPLL_A: 0x%08x\n", hw->dpll_a); printk(" DPLL_B: 0x%08x\n", hw->dpll_b); @@ -578,34 +687,30 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; - if (hw->dpll_a & DPLL_P1_FORCE_DIV2) - p1 = 0; - else - p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; - p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; + + intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2); + printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" PLLA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; - if (hw->dpll_a & DPLL_P1_FORCE_DIV2) - p1 = 0; - else - p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; - p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; + + intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2); + printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" PLLA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); #if 0 printk(" PALETTE_A:\n"); for (i = 0; i < PALETTE_8_ENTRIES) - printk(" %3d: 0x%08x\n", i, hw->palette_a[i]; + printk(" %3d: 0x%08x\n", i, hw->palette_a[i]); printk(" PALETTE_B:\n"); for (i = 0; i < PALETTE_8_ENTRIES) - printk(" %3d: 0x%08x\n", i, hw->palette_b[i]; + printk(" %3d: 0x%08x\n", i, hw->palette_b[i]); #endif printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a); @@ -680,11 +785,11 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) } for (i = 0; i < 3; i++) { printk(" SWF3%d 0x%08x\n", i, - hw->swf3x[i]); + hw->swf3x[i]); } for (i = 0; i < 8; i++) printk(" FENCE%d 0x%08x\n", i, - hw->fence[i]); + hw->fence[i]); printk(" INSTPM 0x%08x\n", hw->instpm); printk(" MEM_MODE 0x%08x\n", hw->mem_mode); @@ -695,43 +800,58 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) #endif } + + /* Split the M parameter into M1 and M2. */ static int -splitm(unsigned int m, unsigned int *retm1, unsigned int *retm2) +splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2) { int m1, m2; - - m1 = (m - 2 - (MIN_M2 + MAX_M2) / 2) / 5 - 2; - if (m1 < MIN_M1) - m1 = MIN_M1; - if (m1 > MAX_M1) - m1 = MAX_M1; - m2 = m - 5 * (m1 + 2) - 2; - if (m2 < MIN_M2 || m2 > MAX_M2 || m2 >= m1) { - return 1; - } else { - *retm1 = (unsigned int)m1; - *retm2 = (unsigned int)m2; - return 0; + int testm; + struct pll_min_max *pll = &plls[index]; + + /* no point optimising too much - brute force m */ + for (m1 = pll->min_m1; m1 < pll->max_m1 + 1; m1++) { + for (m2 = pll->min_m2; m2 < pll->max_m2 + 1; m2++) { + testm = (5 * (m1 + 2)) + (m2 + 2); + if (testm == m) { + *retm1 = (unsigned int)m1; + *retm2 = (unsigned int)m2; + return 0; + } + } } + return 1; } /* Split the P parameter into P1 and P2. */ static int -splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2) +splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2) { int p1, p2; + struct pll_min_max *pll = &plls[index]; + + if (index == PLLS_I9xx) { + p2 = (p % 10) ? 1 : 0; + + p1 = p / (p2 ? 5 : 10); + + *retp1 = (unsigned int)p1; + *retp2 = (unsigned int)p2; + return 0; + } if (p % 4 == 0) p2 = 1; else p2 = 0; p1 = (p / (1 << (p2 + 1))) - 2; - if (p % 4 == 0 && p1 < MIN_P1) { + if (p % 4 == 0 && p1 < pll->min_p1) { p2 = 0; p1 = (p / (1 << (p2 + 1))) - 2; } - if (p1 < MIN_P1 || p1 > MAX_P1 || (p1 + 2) * (1 << (p2 + 1)) != p) { + if (p1 < pll->min_p1 || p1 > pll->max_p1 || + (p1 + 2) * (1 << (p2 + 1)) != p) { return 1; } else { *retp1 = (unsigned int)p1; @@ -741,14 +861,15 @@ splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2) } static int -calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, +calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock) { - u32 m1, m2, n, p1, p2, n1; - u32 f_vco, p, p_best = 0, m, f_out; + u32 m1, m2, n, p1, p2, n1, testm; + u32 f_vco, p, p_best = 0, m, f_out = 0; u32 err_max, err_target, err_best = 10000000; u32 n_best = 0, m_best = 0, f_best, f_err; - u32 p_min, p_max, p_inc, div_min, div_max; + u32 p_min, p_max, p_inc, div_max; + struct pll_min_max *pll = &plls[index]; /* Accept 0.5% difference, but aim for 0.1% */ err_max = 5 * clock / 1000; @@ -756,58 +877,56 @@ calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, DBG_MSG("Clock is %d\n", clock); - div_max = MAX_VCO_FREQ / clock; - div_min = ROUND_UP_TO(MIN_VCO_FREQ, clock) / clock; + div_max = pll->max_vco / clock; - if (clock <= P_TRANSITION_CLOCK) - p_inc = 4; - else - p_inc = 2; - p_min = ROUND_UP_TO(div_min, p_inc); + p_inc = (clock <= pll->p_transition_clk) ? pll->p_inc_lo : pll->p_inc_hi; + p_min = p_inc; p_max = ROUND_DOWN_TO(div_max, p_inc); - if (p_min < MIN_P) - p_min = 4; - if (p_max > MAX_P) - p_max = 128; + if (p_min < pll->min_p) + p_min = pll->min_p; + if (p_max > pll->max_p) + p_max = pll->max_p; DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); p = p_min; do { - if (splitp(p, &p1, &p2)) { + if (splitp(index, p, &p1, &p2)) { WRN_MSG("cannot split p = %d\n", p); p += p_inc; continue; } - n = MIN_N; + n = pll->min_n; f_vco = clock * p; do { - m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK; - if (m < MIN_M) - m = MIN_M; - if (m > MAX_M) - m = MAX_M; - f_out = CALC_VCLOCK3(m, n, p); - if (splitm(m, &m1, &m2)) { - WRN_MSG("cannot split m = %d\n", m); - n++; - continue; - } - if (clock > f_out) - f_err = clock - f_out; - else - f_err = f_out - clock; - - if (f_err < err_best) { - m_best = m; - n_best = n; - p_best = p; - f_best = f_out; - err_best = f_err; + m = ROUND_UP_TO(f_vco * n, pll->ref_clk) / pll->ref_clk; + if (m < pll->min_m) + m = pll->min_m + 1; + if (m > pll->max_m) + m = pll->max_m - 1; + for (testm = m - 1; testm <= m; testm++) { + f_out = calc_vclock3(index, m, n, p); + if (splitm(index, testm, &m1, &m2)) { + WRN_MSG("cannot split m = %d\n", m); + n++; + continue; + } + if (clock > f_out) + f_err = clock - f_out; + else/* slightly bias the error for bigger clocks */ + f_err = f_out - clock + 1; + + if (f_err < err_best) { + m_best = testm; + n_best = n; + p_best = p; + f_best = f_out; + err_best = f_err; + } } n++; - } while ((n <= MAX_N) && (f_out >= clock)); + } while ((n <= pll->max_n) && (f_out >= clock)); p += p_inc; } while ((p <= p_max)); @@ -818,21 +937,22 @@ calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, m = m_best; n = n_best; p = p_best; - splitm(m, &m1, &m2); - splitp(p, &p1, &p2); + splitm(index, m, &m1, &m2); + splitp(index, p, &p1, &p2); n1 = n - 2; DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), " "f: %d (%d), VCO: %d\n", m, m1, m2, n, n1, p, p1, p2, - CALC_VCLOCK3(m, n, p), CALC_VCLOCK(m1, m2, n1, p1, p2), - CALC_VCLOCK3(m, n, p) * p); + calc_vclock3(index, m, n, p), + calc_vclock(index, m1, m2, n1, p1, p2, 0), + calc_vclock3(index, m, n, p) * p); *retm1 = m1; *retm2 = m2; *retn = n1; *retp1 = p1; *retp2 = p2; - *retclock = CALC_VCLOCK(m1, m2, n1, p1, p2); + *retclock = calc_vclock(index, m1, m2, n1, p1, p2, 0); return 0; } @@ -860,6 +980,7 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive; u32 vsync_pol, hsync_pol; u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf; + u32 stride_alignment; DBG_MSG("intelfbhw_mode_to_hw\n"); @@ -929,7 +1050,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, /* Desired clock in kHz */ clock_target = 1000000000 / var->pixclock; - if (calc_pll_params(clock_target, &m1, &m2, &n, &p1, &p2, &clock)) { + if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2, + &n, &p1, &p2, &clock)) { WRN_MSG("calc_pll_params failed\n"); return 1; } @@ -949,7 +1071,14 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, *dpll &= ~DPLL_P1_FORCE_DIV2; *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | (DPLL_P1_MASK << DPLL_P1_SHIFT)); - *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); + + if (IS_I9XX(dinfo)) { + *dpll |= (p2 << DPLL_I9XX_P2_SHIFT); + *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT; + } else { + *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); + } + *fp0 = (n << FP_N_DIVISOR_SHIFT) | (m1 << FP_M1_DIVISOR_SHIFT) | (m2 << FP_M2_DIVISOR_SHIFT); @@ -1054,7 +1183,7 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) | (vactive << SRC_SIZE_VERT_SHIFT); - hw->disp_a_stride = var->xres_virtual * var->bits_per_pixel / 8; + hw->disp_a_stride = dinfo->pitch; DBG_MSG("pitch is %d\n", hw->disp_a_stride); hw->disp_a_base = hw->disp_a_stride * var->yoffset + @@ -1063,9 +1192,11 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, hw->disp_a_base += dinfo->fb.offset << 12; /* Check stride alignment. */ - if (hw->disp_a_stride % STRIDE_ALIGNMENT != 0) { + stride_alignment = IS_I9XX(dinfo) ? STRIDE_ALIGNMENT_I9XX : + STRIDE_ALIGNMENT; + if (hw->disp_a_stride % stride_alignment != 0) { WRN_MSG("display stride %d has bad alignment %d\n", - hw->disp_a_stride, STRIDE_ALIGNMENT); + hw->disp_a_stride, stride_alignment); return 1; } @@ -1087,6 +1218,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, u32 hsync_reg, htotal_reg, hblank_reg; u32 vsync_reg, vtotal_reg, vblank_reg; u32 src_size_reg; + u32 count, tmp_val[3]; /* Assume single pipe, display plane A, analog CRT. */ @@ -1155,6 +1287,27 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, src_size_reg = SRC_SIZE_A; } + /* turn off pipe */ + tmp = INREG(pipe_conf_reg); + tmp &= ~PIPECONF_ENABLE; + OUTREG(pipe_conf_reg, tmp); + + count = 0; + do { + tmp_val[count%3] = INREG(0x70000); + if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2])) + break; + count++; + udelay(1); + if (count % 200 == 0) { + tmp = INREG(pipe_conf_reg); + tmp &= ~PIPECONF_ENABLE; + OUTREG(pipe_conf_reg, tmp); + } + } while(count < 2000); + + OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); + /* Disable planes A and B. */ tmp = INREG(DSPACNTR); tmp &= ~DISPPLANE_PLANE_ENABLE; @@ -1163,19 +1316,21 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, tmp &= ~DISPPLANE_PLANE_ENABLE; OUTREG(DSPBCNTR, tmp); - /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ + /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ mdelay(20); + OUTREG(DVOB, INREG(DVOB) & ~PORT_ENABLE); + OUTREG(DVOC, INREG(DVOC) & ~PORT_ENABLE); + OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); + /* Disable Sync */ tmp = INREG(ADPA); tmp &= ~ADPA_DPMS_CONTROL_MASK; tmp |= ADPA_DPMS_D3; OUTREG(ADPA, tmp); - /* turn off pipe */ - tmp = INREG(pipe_conf_reg); - tmp &= ~PIPECONF_ENABLE; - OUTREG(pipe_conf_reg, tmp); + /* do some funky magic - xyzzy */ + OUTREG(0x61204, 0xabcd0000); /* turn off PLL */ tmp = INREG(dpll_reg); @@ -1183,30 +1338,31 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, OUTREG(dpll_reg, tmp); /* Set PLL parameters */ - OUTREG(dpll_reg, *dpll & ~DPLL_VCO_ENABLE); OUTREG(fp0_reg, *fp0); OUTREG(fp1_reg, *fp1); - /* Set pipe parameters */ - OUTREG(hsync_reg, *hs); - OUTREG(hblank_reg, *hb); - OUTREG(htotal_reg, *ht); - OUTREG(vsync_reg, *vs); - OUTREG(vblank_reg, *vb); - OUTREG(vtotal_reg, *vt); - OUTREG(src_size_reg, *ss); + /* Enable PLL */ + OUTREG(dpll_reg, *dpll); /* Set DVOs B/C */ OUTREG(DVOB, hw->dvob); OUTREG(DVOC, hw->dvoc); + /* undo funky magic */ + OUTREG(0x61204, 0x00000000); + /* Set ADPA */ + OUTREG(ADPA, INREG(ADPA) | ADPA_DAC_ENABLE); OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3); - /* Enable PLL */ - tmp = INREG(dpll_reg); - tmp |= DPLL_VCO_ENABLE; - OUTREG(dpll_reg, tmp); + /* Set pipe parameters */ + OUTREG(hsync_reg, *hs); + OUTREG(hblank_reg, *hb); + OUTREG(htotal_reg, *ht); + OUTREG(vsync_reg, *vs); + OUTREG(vblank_reg, *vb); + OUTREG(vtotal_reg, *vt); + OUTREG(src_size_reg, *ss); /* Enable pipe */ OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); @@ -1231,7 +1387,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, OUTREG(DSPACNTR, hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); mdelay(1); - } + } } OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); @@ -1616,7 +1772,7 @@ intelfbhw_cursor_init(struct intelfb_info *dinfo) DBG_MSG("intelfbhw_cursor_init\n"); #endif - if (dinfo->mobile) { + if (dinfo->mobile || IS_I9XX(dinfo)) { if (!dinfo->cursor.physical) return; tmp = INREG(CURSOR_A_CONTROL); @@ -1649,7 +1805,7 @@ intelfbhw_cursor_hide(struct intelfb_info *dinfo) #endif dinfo->cursor_on = 0; - if (dinfo->mobile) { + if (dinfo->mobile || IS_I9XX(dinfo)) { if (!dinfo->cursor.physical) return; tmp = INREG(CURSOR_A_CONTROL); @@ -1679,7 +1835,7 @@ intelfbhw_cursor_show(struct intelfb_info *dinfo) if (dinfo->cursor_blanked) return; - if (dinfo->mobile) { + if (dinfo->mobile || IS_I9XX(dinfo)) { if (!dinfo->cursor.physical) return; tmp = INREG(CURSOR_A_CONTROL); @@ -1705,14 +1861,18 @@ intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y) #endif /* - * Sets the position. The coordinates are assumed to already - * have any offset adjusted. Assume that the cursor is never + * Sets the position. The coordinates are assumed to already + * have any offset adjusted. Assume that the cursor is never * completely off-screen, and that x, y are always >= 0. */ tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); OUTREG(CURSOR_A_POSITION, tmp); + + if (IS_I9XX(dinfo)) { + OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); + } } void diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h index ba1920159f5..10acda098b7 100644 --- a/drivers/video/intelfb/intelfbhw.h +++ b/drivers/video/intelfb/intelfbhw.h @@ -133,6 +133,7 @@ #define DPLL_VGA_MODE_DISABLE (1 << 28) #define DPLL_P2_MASK 1 #define DPLL_P2_SHIFT 23 +#define DPLL_I9XX_P2_SHIFT 24 #define DPLL_P1_FORCE_DIV2 (1 << 21) #define DPLL_P1_MASK 0x1f #define DPLL_P1_SHIFT 16 @@ -155,29 +156,8 @@ /* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */ /* Clock values are in units of kHz */ #define PLL_REFCLK 48000 -#define MIN_VCO_FREQ 930000 -#define MAX_VCO_FREQ 1400000 #define MIN_CLOCK 25000 #define MAX_CLOCK 350000 -#define P_TRANSITION_CLOCK 165000 -#define MIN_M 108 -#define MAX_M 140 -#define MIN_M1 18 -#define MAX_M1 26 -#define MIN_M2 6 -#define MAX_M2 16 -#define MIN_P 4 -#define MAX_P 128 -#define MIN_P1 0 -#define MAX_P1 31 -#define MIN_N 3 -#define MAX_N 16 - -#define CALC_VCLOCK(m1, m2, n, p1, p2) \ - ((PLL_REFCLK * (5 * ((m1) + 2) + ((m2) + 2)) / ((n) + 2)) / \ - (((p1) + 2) * (1 << (p2 + 1)))) - -#define CALC_VCLOCK3(m, n, p) ((PLL_REFCLK * (m) / (n)) / (p)) /* Two pipes */ #define PIPE_A 0 @@ -522,8 +502,7 @@ /* function protoypes */ -extern int intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, - int *chipset, int *mobile); +extern int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo); extern int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, int *stolen_size); extern int intelfbhw_check_non_crt(struct intelfb_info *dinfo); |